import { NextResponse } from "next/server";
import { canCompany } from "@/lib/company-context";
import { createClient } from "@/lib/supabase-server";
import { registerReportAuditLog } from "@/lib/reports/audit";
import { createReportRuntime, getReportOptions, runReport } from "@/lib/reports/service";
import type { ReportRequest } from "@/lib/reports/contracts";

function normalizeRequest(body: Record<string, unknown>): ReportRequest {
  return {
    tab: typeof body.tab === "string" ? (body.tab as ReportRequest["tab"]) : "financial",
    filters: body.filters && typeof body.filters === "object" ? (body.filters as ReportRequest["filters"]) : {},
    page: typeof body.page === "number" ? body.page : 1,
    pageSize: typeof body.pageSize === "number" ? body.pageSize : 25,
    search: typeof body.search === "string" ? body.search : "",
    sort: body.sort && typeof body.sort === "object" ? (body.sort as ReportRequest["sort"]) : null,
    visibleColumnIds: Array.isArray(body.visibleColumnIds)
      ? body.visibleColumnIds.filter((item): item is string => typeof item === "string")
      : undefined,
    custom: body.custom && typeof body.custom === "object" ? (body.custom as ReportRequest["custom"]) : null,
    exportAllRows: body.exportAllRows === true,
    skipAudit: body.skipAudit === true,
  };
}

function normalizeAuditContext(body: Record<string, unknown> | null, fallbackGeneratedBy: string) {
  const raw = body?.auditContext && typeof body.auditContext === "object" ? (body.auditContext as Record<string, unknown>) : null;
  return {
    generatedBy:
      (typeof raw?.generatedBy === "string" && raw.generatedBy.trim()) ||
      fallbackGeneratedBy,
    timezone: (typeof raw?.timezone === "string" && raw.timezone.trim()) || "UTC",
  };
}

export async function GET() {
  try {
    const supabase = await createClient();
    const runtime = await createReportRuntime(supabase);

    if (!canCompany(runtime.ctx, runtime.user.id, "reports.read")) {
      return NextResponse.json({ error: "Sem permissão." }, { status: 403 });
    }

    const payload = await getReportOptions(runtime);
    return NextResponse.json(payload);
  } catch (error) {
    return NextResponse.json(
      { error: error instanceof Error ? error.message : "Falha ao carregar metadata dos relatórios." },
      { status: 500 }
    );
  }
}

export async function POST(req: Request) {
  try {
    const supabase = await createClient();
    const runtime = await createReportRuntime(supabase);

    if (!canCompany(runtime.ctx, runtime.user.id, "reports.read")) {
      return NextResponse.json({ error: "Sem permissão." }, { status: 403 });
    }

    const body = (await req.json().catch(() => null)) as Record<string, unknown> | null;
    const payload = normalizeRequest(body ?? {});
    const report = await runReport(runtime, payload);
    const auditContext = normalizeAuditContext(
      body,
      String(runtime.user.user_metadata?.name || runtime.user.user_metadata?.full_name || runtime.user.email || runtime.user.id)
    );

    if (!payload.skipAudit) {
      await registerReportAuditLog({
        admin: runtime.admin,
        companyId: runtime.ctx.companyId,
        userId: runtime.user.id,
        generatedBy: auditContext.generatedBy,
        timezone: auditContext.timezone,
        eventType: "generate",
        format: "screen",
        report,
        request: payload,
        visibleColumnIds: payload.visibleColumnIds,
      });
    }

    return NextResponse.json(report);
  } catch (error) {
    return NextResponse.json(
      { error: error instanceof Error ? error.message : "Falha ao gerar relatório." },
      { status: 500 }
    );
  }
}
