import { NextResponse } from "next/server";
import { canCompany, getCompanyContext } from "@/lib/company-context";
import { createAdminClient, createClient } from "@/lib/supabase-server";

type MercadoPagoSettings = {
  environment: "sandbox" | "production";
  checkout_enabled: boolean;
  auto_create_order_on_approved_payment: boolean;
  bank_account_id: string | null;
  sandbox_public_key: string;
  sandbox_access_token: string;
  production_public_key: string;
  production_access_token: string;
  statement_descriptor: string;
};

function normalizeText(value: unknown) {
  return String(value || "").trim();
}

function normalizeBoolean(value: unknown, fallback = false) {
  if (typeof value === "boolean") return value;
  if (typeof value === "string") {
    const normalized = value.trim().toLowerCase();
    if (normalized === "true") return true;
    if (normalized === "false") return false;
  }
  return fallback;
}

function parseSettings(raw: unknown): MercadoPagoSettings {
  const settings = raw && typeof raw === "object" && !Array.isArray(raw) ? (raw as Record<string, unknown>) : {};
  return {
    environment: settings.environment === "production" ? "production" : "sandbox",
    checkout_enabled: normalizeBoolean(settings.checkout_enabled, true),
    auto_create_order_on_approved_payment: normalizeBoolean(settings.auto_create_order_on_approved_payment, true),
    bank_account_id: normalizeText(settings.bank_account_id) || null,
    sandbox_public_key: normalizeText(settings.sandbox_public_key),
    sandbox_access_token: normalizeText(settings.sandbox_access_token),
    production_public_key: normalizeText(settings.production_public_key),
    production_access_token: normalizeText(settings.production_access_token),
    statement_descriptor: normalizeText(settings.statement_descriptor).slice(0, 13),
  };
}

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

  if (error || !user) {
    return { ok: false as const, response: NextResponse.json({ error: "Não autenticado." }, { status: 401 }) };
  }

  const ctx = await getCompanyContext(supabase, user);
  if (!canCompany(ctx, user.id, "financial.bank.integrations")) {
    return { ok: false as const, response: NextResponse.json({ error: "Sem permissão." }, { status: 403 }) };
  }

  return { ok: true as const, supabase, user, ctx };
}

export async function GET() {
  const auth = await getAuthContext();
  if (!auth.ok) return auth.response;

  const ownerId = auth.ctx.ownerId || auth.user.id;
  const admin = createAdminClient();

  const [{ data: integration, error: integrationError }, { data: bankAccounts, error: bankAccountsError }] = await Promise.all([
    admin
      .from("integrations")
      .select("id,active,settings,updated_at")
      .eq("provider", "mercado_pago")
      .eq("user_id", ownerId)
      .maybeSingle(),
    admin
      .from("bank_accounts")
      .select("id,name,bank_name,bank_code,active")
      .eq("company_id", auth.ctx.companyId)
      .eq("active", true)
      .order("name", { ascending: true }),
  ]);

  if (integrationError) {
    return NextResponse.json({ error: integrationError.message || "Erro ao carregar integração." }, { status: 500 });
  }

  if (bankAccountsError) {
    return NextResponse.json({ error: bankAccountsError.message || "Erro ao carregar contas bancárias." }, { status: 500 });
  }

  const settings = parseSettings(integration?.settings);
  return NextResponse.json({
    ok: true,
    config: {
      id: integration?.id || null,
      active: integration?.active !== false,
      updated_at: integration?.updated_at || null,
      ...settings,
    },
    bank_accounts: (bankAccounts || []).map((account) => ({
      id: account.id,
      name: account.bank_name ? `${account.name} - ${account.bank_name}` : account.name,
      bank_name: account.bank_name || null,
      bank_code: account.bank_code || null,
    })),
  });
}

export async function PUT(request: Request) {
  const auth = await getAuthContext();
  if (!auth.ok) return auth.response;

  const ownerId = auth.ctx.ownerId || auth.user.id;
  const admin = createAdminClient();
  const body = (await request.json().catch(() => null)) as Record<string, unknown> | null;
  const settings = parseSettings(body);

  if (
    settings.bank_account_id &&
    !(
      await admin
        .from("bank_accounts")
        .select("id")
        .eq("id", settings.bank_account_id)
        .eq("company_id", auth.ctx.companyId)
        .eq("active", true)
        .maybeSingle()
    ).data?.id
  ) {
    return NextResponse.json({ error: "Conta bancária inválida." }, { status: 400 });
  }

  const { data: existing } = await admin
    .from("integrations")
    .select("id")
    .eq("provider", "mercado_pago")
    .eq("user_id", ownerId)
    .maybeSingle();

  if (existing?.id) {
    const { error } = await admin
      .from("integrations")
      .update({
        active: true,
        settings,
        updated_at: new Date().toISOString(),
      })
      .eq("id", existing.id);

    if (error) {
      return NextResponse.json({ error: error.message || "Erro ao salvar integração." }, { status: 500 });
    }
  } else {
    const { error } = await admin.from("integrations").insert({
      user_id: ownerId,
      provider: "mercado_pago",
      token: null,
      refresh_token: null,
      settings,
      active: true,
    });

    if (error) {
      return NextResponse.json({ error: error.message || "Erro ao criar integração." }, { status: 500 });
    }
  }

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