import { NextResponse } from "next/server";
import { createClient } from "@/lib/supabase-server";
import { canCompany, getCompanyContext } from "@/lib/company-context";
import { validar, type CorpoCompromisso } from "@/lib/agenda/validacao";

/**
 * Edicao e remocao de compromisso.
 *
 * Grava pelo cliente do usuario para as policies da tabela valerem. O `.eq`
 * pelo id sozinho ja seria filtrado pelo RLS, mas checar antes deixa a
 * resposta honesta: "nao encontrado" em vez de um sucesso que nao alterou
 * linha nenhuma.
 */

async function contexto(req: Request) {
  const supabase = await createClient();
  const {
    data: { user },
  } = await supabase.auth.getUser();
  if (!user) return { erro: NextResponse.json({ error: "Nao autenticado." }, { status: 401 }) };

  const companyCtx = await getCompanyContext(supabase, user);
  if (!canCompany(companyCtx, user.id, "agenda.board.write")) {
    return { erro: NextResponse.json({ error: "Sem permissão para editar compromisso." }, { status: 403 }) };
  }
  return { supabase, user, companyCtx };
}

export async function PATCH(req: Request, ctx: { params: Promise<{ id: string }> }) {
  const { id } = await ctx.params;
  const c = await contexto(req);
  if (c.erro) return c.erro;

  const corpo = (await req.json().catch(() => null)) as CorpoCompromisso | null;
  const check = validar(corpo);
  if (!check.ok) return NextResponse.json({ error: check.erro }, { status: 400 });

  const { data: existente } = await c.supabase!
    .from("agenda_events")
    .select("id")
    .eq("id", id)
    .maybeSingle();

  if (!existente) {
    return NextResponse.json({ error: "Compromisso não encontrado." }, { status: 404 });
  }

  const companyId = c.companyCtx!.ownerId ?? c.user!.id;
  const { data: categoria } = await c.supabase!
    .from("agenda_categories")
    .select("id")
    .eq("id", check.dados.category_id)
    .eq("company_id", companyId)
    .eq("is_system", false)
    .maybeSingle();
  if (!categoria) {
    return NextResponse.json({ error: "Categoria inválida." }, { status: 400 });
  }

  if (check.dados.client_id) {
    const tenantIds = c.companyCtx!.tenantIds?.length ? c.companyCtx!.tenantIds : [c.user!.id];
    const { data: cliente } = await c.supabase!
      .from("clients")
      .select("id")
      .eq("id", check.dados.client_id)
      .in("user_id", tenantIds)
      .maybeSingle();
    if (!cliente) {
      return NextResponse.json({ error: "Cliente inválido." }, { status: 400 });
    }
  }

  const { error } = await c.supabase!
    .from("agenda_events")
    .update({ ...check.dados, updated_at: new Date().toISOString() })
    .eq("id", id);

  if (error) {
    return NextResponse.json({ error: "Não foi possível salvar o compromisso." }, { status: 400 });
  }

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

export async function DELETE(req: Request, ctx: { params: Promise<{ id: string }> }) {
  const { id } = await ctx.params;
  const c = await contexto(req);
  if (c.erro) return c.erro;

  const { error } = await c.supabase!.from("agenda_events").delete().eq("id", id);
  if (error) {
    return NextResponse.json({ error: "Não foi possível apagar o compromisso." }, { status: 400 });
  }
  return NextResponse.json({ ok: true });
}
