import { cookies } from "next/headers";
import { NextResponse } from "next/server";
import { createAdminClient } from "@/lib/supabase-admin";

/*
  Aparelho do visitante, para a resposta da loja alcancar quem ja fechou a aba.

  Sem conta, a unica credencial e a chave do navegador — a mesma da conversa.
  Guarda-se so o endereco que o proprio navegador gera; desligar e remover a
  linha.
*/

const COOKIE_DO_VISITANTE = "ktl_visitante";

function texto(valor: unknown) {
  return String(valor ?? "").trim();
}

function chaveValida(chave: string) {
  return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(chave);
}

async function chaveDaVez(informada: string) {
  if (chaveValida(informada)) return informada;
  const cookieStore = await cookies();
  const doCookie = texto(cookieStore.get(COOKIE_DO_VISITANTE)?.value);
  return chaveValida(doCookie) ? doCookie : "";
}

async function conversaDaChave(admin: ReturnType<typeof createAdminClient>, slug: string, chave: string) {
  if (!slug || !chave) return null;
  const { data: perfil } = await admin
    .from("profiles")
    .select("id,store_chat_enabled")
    .eq("slug", slug)
    .maybeSingle();

  const loja = perfil as { id?: string; store_chat_enabled?: boolean } | null;
  if (!loja?.id || loja.store_chat_enabled !== true) return null;

  const { data } = await admin
    .from("chat_threads")
    .select("id,user_id")
    .eq("kind", "visitor")
    .eq("user_id", loja.id)
    .eq("visitor_key", chave)
    .maybeSingle();

  return (data as { id: string; user_id: string } | null) || null;
}

export async function POST(request: Request) {
  const corpo = (await request.json().catch(() => null)) as
    | {
        slug?: unknown;
        chave?: unknown;
        assinatura?: { endpoint?: string; keys?: { p256dh?: string; auth?: string } };
        user_agent?: unknown;
      }
    | null;

  const slug = texto(corpo?.slug);
  const chave = await chaveDaVez(texto(corpo?.chave));
  const conversa = await (async () => {
    const admin = createAdminClient();
    return { admin, thread: await conversaDaChave(admin, slug, chave) };
  })();

  if (!conversa.thread) {
    return NextResponse.json({ error: "Comece a conversa antes de ligar o aviso." }, { status: 400 });
  }

  const endpoint = texto(corpo?.assinatura?.endpoint);
  const p256dh = texto(corpo?.assinatura?.keys?.p256dh);
  const auth = texto(corpo?.assinatura?.keys?.auth);
  if (!endpoint || !p256dh || !auth) {
    return NextResponse.json({ error: "Assinatura incompleta." }, { status: 400 });
  }

  const { error } = await conversa.admin.from("visitor_push_subscriptions").upsert(
    {
      thread_id: conversa.thread.id,
      user_id: conversa.thread.user_id,
      visitor_key: chave,
      endpoint,
      p256dh,
      auth,
      user_agent: texto(corpo?.user_agent).slice(0, 300) || null,
      failures: 0,
    },
    { onConflict: "endpoint" }
  );

  if (error) return NextResponse.json({ error: error.message }, { status: 400 });
  return NextResponse.json({ ok: true });
}

export async function DELETE(request: Request) {
  const { searchParams } = new URL(request.url);
  const slug = texto(searchParams.get("slug"));
  const chave = await chaveDaVez(texto(searchParams.get("chave")));
  const endpoint = texto(searchParams.get("endpoint"));

  const admin = createAdminClient();
  const thread = await conversaDaChave(admin, slug, chave);
  if (!thread || !endpoint) return NextResponse.json({ ok: true });

  await admin
    .from("visitor_push_subscriptions")
    .delete()
    .eq("endpoint", endpoint)
    .eq("thread_id", thread.id);

  return NextResponse.json({ ok: true });
}
