import { NextResponse } from "next/server";
import { createClient } from "@/lib/supabase-server";
import { createAdminClient } from "@/lib/supabase-admin";
import { isOwnerUser } from "@/lib/owner-auth";
import type { PostgrestError } from "@supabase/supabase-js";

function normalizeString(value: unknown) {
  return typeof value === "string" ? value.trim() : "";
}

function normalizeDigits(value: unknown) {
  return String(value || "").replace(/\D/g, "");
}

function normalizeBoolean(value: unknown, fallback: boolean) {
  if (typeof value === "boolean") return value;
  return fallback;
}

function normalizeNumber(value: unknown, fallback: number) {
  const n = Number(value);
  return Number.isFinite(n) ? n : fallback;
}

function getDatabaseErrorMessage(error: PostgrestError | null | undefined, fallback: string) {
  if (!error) return fallback;
  if (error.code === "42P01") {
    return "A tabela de fornecedores patrocinados ainda não existe no banco. Rode a migration 92_create_sponsored_suppliers.sql.";
  }
  if (error.code === "42703") {
    return "Um dos novos campos do fornecedor patrocinado ainda não existe no banco. Rode as migrations 93_add_sponsored_supplier_discount.sql e 94_add_sponsored_supplier_media_and_description.sql.";
  }
  if (error.code === "23505") {
    return "Já existe um fornecedor patrocinado com este CNPJ.";
  }
  return error.message || fallback;
}

async function ensureOwner() {
  const supabase = await createClient();
  const {
    data: { user },
  } = await supabase.auth.getUser();

  if (!user || !isOwnerUser({ id: user.id, email: user.email })) {
    return { ok: false as const, status: 403, user: null };
  }

  return { ok: true as const, status: 200, user };
}

function buildPayload(body: Record<string, unknown> | null, current?: Record<string, unknown>) {
  const name = normalizeString(body?.name ?? current?.name);
  const cnpj = normalizeDigits(body?.cnpj ?? current?.cnpj).slice(0, 14);
  const email = normalizeString(body?.email ?? current?.email).toLowerCase();
  const phone = normalizeDigits(body?.phone ?? current?.phone).slice(0, 11);

  if (!name) throw new Error("Nome do fornecedor é obrigatório.");
  if (cnpj.length !== 14) throw new Error("CNPJ inválido.");
  if (!email) throw new Error("E-mail é obrigatório.");
  if (phone.length < 10) throw new Error("Telefone inválido.");

  return {
    name,
    legal_name: normalizeString(body?.legal_name ?? current?.legal_name) || null,
    cnpj,
    category: normalizeString(body?.category ?? current?.category) || null,
    city: normalizeString(body?.city ?? current?.city) || null,
    email,
    phone,
    payment_terms_primary: normalizeString(body?.payment_terms_primary ?? current?.payment_terms_primary) || "30 dias",
    payment_terms_secondary: normalizeString(body?.payment_terms_secondary ?? current?.payment_terms_secondary) || "Boleto",
    subscriber_discount: normalizeString(body?.subscriber_discount ?? current?.subscriber_discount) || null,
    image_url: normalizeString(body?.image_url ?? current?.image_url) || null,
    description: normalizeString(body?.description ?? current?.description) || null,
    website_url: normalizeString(body?.website_url ?? current?.website_url) || null,
    notes: normalizeString(body?.notes ?? current?.notes) || null,
    active: normalizeBoolean(body?.active, typeof current?.active === "boolean" ? Boolean(current.active) : true),
    position: normalizeNumber(body?.position ?? current?.position, 0),
    updated_at: new Date().toISOString(),
  };
}

export async function GET() {
  const auth = await ensureOwner();
  if (!auth.ok) return NextResponse.json({ error: "Sem permissão." }, { status: auth.status });

  const admin = createAdminClient();
  const { data, error } = await admin
    .from("sponsored_suppliers")
    .select("id,name,legal_name,cnpj,category,city,email,phone,payment_terms_primary,payment_terms_secondary,subscriber_discount,image_url,description,website_url,notes,active,position,created_at,updated_at")
    .order("position", { ascending: true })
    .order("created_at", { ascending: false });

  if (error) {
    console.error("[owner:sponsored-suppliers:GET]", error);
    return NextResponse.json({ error: getDatabaseErrorMessage(error, "Não foi possível carregar os fornecedores patrocinados.") }, { status: 400 });
  }

  return NextResponse.json({ ok: true, suppliers: data || [] });
}

export async function POST(request: Request) {
  const auth = await ensureOwner();
  if (!auth.ok) return NextResponse.json({ error: "Sem permissão." }, { status: auth.status });

  const body = (await request.json().catch(() => null)) as Record<string, unknown> | null;

  try {
    const payload = buildPayload(body);
    const admin = createAdminClient();
    const { data, error } = await admin.from("sponsored_suppliers").insert(payload).select("id").single();
    if (error || !data?.id) {
      console.error("[owner:sponsored-suppliers:POST]", error);
      return NextResponse.json({ error: getDatabaseErrorMessage(error, "Não foi possível salvar o fornecedor patrocinado.") }, { status: 400 });
    }
    return NextResponse.json({ ok: true, id: data.id });
  } catch (error) {
    return NextResponse.json(
      { error: error instanceof Error ? error.message : "Não foi possível salvar o fornecedor patrocinado." },
      { status: 400 }
    );
  }
}

export async function PATCH(request: Request) {
  const auth = await ensureOwner();
  if (!auth.ok) return NextResponse.json({ error: "Sem permissão." }, { status: auth.status });

  const body = (await request.json().catch(() => null)) as Record<string, unknown> | null;
  const id = normalizeString(body?.id);
  if (!id) return NextResponse.json({ error: "ID inválido." }, { status: 400 });

  const admin = createAdminClient();
  const { data: current, error: currentError } = await admin.from("sponsored_suppliers").select("*").eq("id", id).maybeSingle();
  if (currentError) {
    console.error("[owner:sponsored-suppliers:PATCH:current]", currentError);
    return NextResponse.json({ error: getDatabaseErrorMessage(currentError, "Não foi possível carregar o fornecedor patrocinado.") }, { status: 400 });
  }
  if (!current) {
    return NextResponse.json({ error: "Fornecedor patrocinado não encontrado." }, { status: 404 });
  }

  try {
    const payload = buildPayload(body, current as Record<string, unknown>);
    const { error } = await admin.from("sponsored_suppliers").update(payload).eq("id", id);
    if (error) {
      console.error("[owner:sponsored-suppliers:PATCH]", error);
      return NextResponse.json({ error: getDatabaseErrorMessage(error, "Não foi possível atualizar o fornecedor patrocinado.") }, { status: 400 });
    }
    return NextResponse.json({ ok: true });
  } catch (error) {
    return NextResponse.json(
      { error: error instanceof Error ? error.message : "Não foi possível atualizar o fornecedor patrocinado." },
      { status: 400 }
    );
  }
}

export async function DELETE(request: Request) {
  const auth = await ensureOwner();
  if (!auth.ok) return NextResponse.json({ error: "Sem permissão." }, { status: auth.status });

  const { searchParams } = new URL(request.url);
  const id = normalizeString(searchParams.get("id"));
  if (!id) return NextResponse.json({ error: "ID inválido." }, { status: 400 });

  const admin = createAdminClient();
  const { error } = await admin.from("sponsored_suppliers").delete().eq("id", id);
  if (error) {
    console.error("[owner:sponsored-suppliers:DELETE]", error);
    return NextResponse.json({ error: getDatabaseErrorMessage(error, "Não foi possível deletar o fornecedor patrocinado.") }, { status: 400 });
  }

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