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

/*
  Anexo da conversa, lado do cliente.

  O arquivo mora numa pasta privada (migration 161): nao existe endereco
  publico para ele. Quem abre passa por aqui, e a rota confere se a pessoa e
  parte daquela conversa:
  - a conversa do pedido ou do orcamento: o cliente logado no portal da loja,
    dono da conversa;
  - o chat da vitrine: o visitante que abriu aquele chat (a chave dele fica no
    cookie `ktl_visitante`, o mesmo que o chat usa).
  Recado interno da equipe e conversa da equipe nunca saem por aqui.
*/

export const dynamic = "force-dynamic";

const VALIDADE_DO_ENDERECO_S = 300;

type Mensagem = {
  id: string;
  thread_id: string;
  attachment_path: string | null;
  internal: boolean | null;
  deleted_at: string | null;
};

type Conversa = {
  id: string;
  user_id: string;
  kind: string;
  client_id: string | null;
  visitor_key: string | null;
};

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

export async function GET(_req: Request, context: { params: Promise<{ id: string }> }) {
  const { id } = await context.params;
  const naoEncontrado = () => NextResponse.json({ error: "Anexo nao encontrado." }, { status: 404 });
  if (!/^[0-9a-f-]{36}$/i.test(texto(id))) return naoEncontrado();

  const admin = createAdminClient();
  const { data: mensagemBruta } = await admin
    .from("chat_messages")
    .select("id,thread_id,attachment_path,internal,deleted_at")
    .eq("id", id)
    .maybeSingle();
  const mensagem = mensagemBruta as Mensagem | null;
  if (!mensagem?.id || !mensagem.attachment_path || mensagem.deleted_at || mensagem.internal) return naoEncontrado();

  const { data: conversaBruta } = await admin
    .from("chat_threads")
    .select("id,user_id,kind,client_id,visitor_key")
    .eq("id", mensagem.thread_id)
    .maybeSingle();
  const conversa = conversaBruta as Conversa | null;
  if (!conversa?.id || conversa.kind === "team") return naoEncontrado();

  const cookieStore = await cookies();
  let pode = false;

  /* O visitante do chat da vitrine. */
  const chaveDoVisitante = texto(cookieStore.get("ktl_visitante")?.value);
  if (conversa.kind === "visitor" && chaveDoVisitante && conversa.visitor_key && chaveDoVisitante === conversa.visitor_key) {
    pode = true;
  }

  /* O cliente logado no portal desta loja, dono da conversa. */
  const sessaoDoPortal = texto(cookieStore.get("ks_client_portal")?.value);
  if (!pode && sessaoDoPortal && conversa.client_id) {
    const { data: loja } = await admin.from("profiles").select("slug").eq("id", conversa.user_id).maybeSingle();
    const slug = texto((loja as { slug?: string | null } | null)?.slug);
    if (slug) {
      const { data: sessao } = await admin.rpc("client_portal_get_session", {
        p_slug: slug,
        p_session_token: sessaoDoPortal,
      });
      const clienteId = texto((sessao as { client?: { id?: string } } | null)?.client?.id);
      pode = Boolean(clienteId) && clienteId === conversa.client_id;
    }
  }

  /* A mesma resposta de anexo inexistente: nao confirma que ele existe. */
  if (!pode) return naoEncontrado();

  const { data: assinado, error } = await admin.storage
    .from(BUCKET_PRIVADO_DA_CONVERSA)
    .createSignedUrl(mensagem.attachment_path, VALIDADE_DO_ENDERECO_S);
  if (error || !assinado?.signedUrl) {
    return NextResponse.json({ error: "Nao foi possivel abrir o anexo agora." }, { status: 502 });
  }

  const resposta = NextResponse.redirect(assinado.signedUrl, 302);
  resposta.headers.set("Cache-Control", "private, max-age=240");
  return resposta;
}
