import { NextRequest, NextResponse } from "next/server";
import crypto from "crypto";
import { prisma } from "@/lib/prisma";

const COOKIE_NAME = "rkda_vid";
const BOT_REGEX = /bot|crawl|spider|slurp|bingpreview|facebookexternalhit|headless|lighthouse/i;

function getClientIp(req: NextRequest): string {
  const xff = req.headers.get("x-forwarded-for");
  if (xff) return xff.split(",")[0].trim();
  return req.headers.get("x-real-ip") || "unknown";
}

function hashIp(ip: string): string {
  return crypto
    .createHash("sha256")
    .update(ip + (process.env.VISITOR_HASH_SALT || ""))
    .digest("hex");
}

async function getTotal() {
  return prisma.site_visitors.count();
}

// GET -> just return total
export async function GET() {
  try {
    const total = await getTotal();
    return NextResponse.json({ success: true, data: { total } });
  } catch (err) {
    console.error(err);
    return NextResponse.json({ success: false, data: { total: 0 } }, { status: 500 });
  }
}

// POST -> track visit (once per unique visitor) and return total
export async function POST(req: NextRequest) {
  try {
    const userAgent = req.headers.get("user-agent") || "";

    // Ignore bots, just return the count
    if (BOT_REGEX.test(userAgent)) {
      return NextResponse.json({ success: true, data: { total: await getTotal() } });
    }

    // Returning visitor with cookie -> skip DB write
    const hasCookie = req.cookies.get(COOKIE_NAME)?.value;
    if (hasCookie) {
      return NextResponse.json({ success: true, data: { total: await getTotal() } });
    }

    const ipHash = hashIp(getClientIp(req));

    try {
      await prisma.site_visitors.upsert({
        where: { ip_hash: ipHash },
        create: { ip_hash: ipHash, user_agent: userAgent.slice(0, 500) },
        update: { visit_count: { increment: 1 }, last_visit: new Date() },
      });
    } catch (e: any) {
      // Concurrent insert of same visitor (unique violation) -> safe to ignore
      if (e?.code !== "P2002") throw e;
    }

    const res = NextResponse.json({ success: true, data: { total: await getTotal() } });
    res.cookies.set(COOKIE_NAME, "1", {
      maxAge: 60 * 60 * 24 * 365,
      httpOnly: true,
      sameSite: "lax",
      secure: process.env.NODE_ENV === "production",
      path: "/",
    });
    return res;
  } catch (err) {
    console.error(err);
    return NextResponse.json({ success: false, data: { total: 0 } }, { status: 500 });
  }
}