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

type ProfileRequestBody = {
  user_id?: unknown;
  holder_name?: unknown;
  document_type?: unknown;
  document_number?: unknown;
  payout_method?: unknown;
  pix_key_type?: unknown;
  pix_key?: unknown;
  bank_name?: unknown;
  bank_code?: unknown;
  agency_number?: unknown;
  agency_digit?: unknown;
  account_number?: unknown;
  account_digit?: unknown;
  account_type?: unknown;
  notes?: unknown;
  active?: unknown;
};

const VALID_DOCUMENT_TYPES = new Set(["cpf", "cnpj"]);
const VALID_PAYOUT_METHODS = new Set(["pix", "bank_transfer"]);
const VALID_PIX_KEY_TYPES = new Set(["cpf", "cnpj", "email", "phone", "random"]);
const VALID_ACCOUNT_TYPES = new Set(["checking", "savings", "payment"]);

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

export async function GET(req: Request) {
  const supabase = await createClient();
  const {
    data: { user },
  } = await supabase.auth.getUser();

  if (!user) return NextResponse.json({ error: "Não autenticado." }, { status: 401 });

  const ctx = await getCompanyContext(supabase, user);
  const canProfileManage = canCompany(ctx, user.id, "commissions.profile");
  const canRead = canCompany(ctx, user.id, "commissions.read");
  const canReadSelf = canCompany(ctx, user.id, "commissions.self");
  if (!canProfileManage && !canRead && !canReadSelf) {
    return NextResponse.json({ error: "Sem permissão." }, { status: 403 });
  }

  const requestedUserId = new URL(req.url).searchParams.get("user_id")?.trim() || "";
  const effectiveUserId = canProfileManage || canRead ? requestedUserId : user.id;

  const { data: memberships, error: membershipsError } = await supabase
    .from("company_users")
    .select("user_id,email,role,active")
    .eq("company_id", ctx.companyId)
    .eq("active", true)
    .order("created_at", { ascending: true });

  if (membershipsError) {
    return NextResponse.json({ error: "Falha ao listar funcionários da empresa." }, { status: 500 });
  }

  const users = ((memberships ?? []) as Array<{ user_id: string; email: string; role: string; active: boolean }>).map((item) => ({
    user_id: item.user_id,
    email: item.email,
    role: item.role,
  }));

  if (ctx.ownerId && !users.some((item) => item.user_id === ctx.ownerId)) {
    users.unshift({
      user_id: ctx.ownerId,
      email: user.id === ctx.ownerId ? user.email || ctx.ownerId : ctx.ownerId,
      role: "owner",
    });
  }

  let profileQuery = supabase
    .from("employee_payout_profiles")
    .select(
      "id,company_id,user_id,holder_name,document_type,document_number,payout_method,pix_key_type,pix_key,bank_name,bank_code,agency_number,agency_digit,account_number,account_digit,account_type,active,verified_at,notes,created_at,updated_at"
    )
    .eq("company_id", ctx.companyId)
    .order("updated_at", { ascending: false });

  if (effectiveUserId) {
    profileQuery = profileQuery.eq("user_id", effectiveUserId);
  }

  const { data: profiles, error: profilesError } = await profileQuery;
  if (profilesError) {
    return NextResponse.json({ error: "Falha ao listar perfis de repasse." }, { status: 500 });
  }

  return NextResponse.json({
    users,
    profiles: profiles ?? [],
  });
}

export async function PUT(req: Request) {
  const supabase = await createClient();
  const {
    data: { user },
  } = await supabase.auth.getUser();

  if (!user) return NextResponse.json({ error: "Não autenticado." }, { status: 401 });

  const ctx = await getCompanyContext(supabase, user);
  const canProfileManage = canCompany(ctx, user.id, "commissions.profile");
  const canReadSelf = canCompany(ctx, user.id, "commissions.self");
  if (!canProfileManage && !canReadSelf) {
    return NextResponse.json({ error: "Sem permissão." }, { status: 403 });
  }

  const body = (await req.json().catch(() => null)) as ProfileRequestBody | null;
  const requestedUserId = asTrimmedString(body?.user_id);
  const targetUserId = canProfileManage ? requestedUserId : user.id;
  if (!targetUserId) {
    return NextResponse.json({ error: "Funcionário inválido para atualizar o perfil." }, { status: 400 });
  }

  const holderName = asTrimmedString(body?.holder_name);
  const documentType = asTrimmedString(body?.document_type);
  const documentNumber = asTrimmedString(body?.document_number);
  const payoutMethod = asTrimmedString(body?.payout_method) || "pix";
  const pixKeyType = asTrimmedString(body?.pix_key_type);
  const pixKey = asTrimmedString(body?.pix_key);
  const bankName = asTrimmedString(body?.bank_name);
  const bankCode = asTrimmedString(body?.bank_code);
  const agencyNumber = asTrimmedString(body?.agency_number);
  const agencyDigit = asTrimmedString(body?.agency_digit);
  const accountNumber = asTrimmedString(body?.account_number);
  const accountDigit = asTrimmedString(body?.account_digit);
  const accountType = asTrimmedString(body?.account_type);
  const notes = asTrimmedString(body?.notes);
  const active = body?.active !== false;

  if (!VALID_PAYOUT_METHODS.has(payoutMethod)) {
    return NextResponse.json({ error: "Método de repasse inválido." }, { status: 400 });
  }

  if (documentType && !VALID_DOCUMENT_TYPES.has(documentType)) {
    return NextResponse.json({ error: "Tipo de documento inválido." }, { status: 400 });
  }

  if (pixKeyType && !VALID_PIX_KEY_TYPES.has(pixKeyType)) {
    return NextResponse.json({ error: "Tipo de chave Pix inválido." }, { status: 400 });
  }

  if (accountType && !VALID_ACCOUNT_TYPES.has(accountType)) {
    return NextResponse.json({ error: "Tipo de conta inválido." }, { status: 400 });
  }

  if (payoutMethod === "pix" && !pixKey) {
    return NextResponse.json({ error: "Informe a chave Pix para o repasse." }, { status: 400 });
  }

  if (payoutMethod === "bank_transfer" && (!bankName || !accountNumber)) {
    return NextResponse.json({ error: "Informe banco e conta para transferência." }, { status: 400 });
  }

  if (targetUserId !== ctx.ownerId) {
    const { data: membership, error: membershipError } = await supabase
      .from("company_users")
      .select("user_id,active")
      .eq("company_id", ctx.companyId)
      .eq("user_id", targetUserId)
      .maybeSingle();

    if (membershipError) {
      return NextResponse.json({ error: "Falha ao validar funcionário." }, { status: 500 });
    }

    if (!membership?.user_id) {
      return NextResponse.json({ error: "Funcionário não pertence à empresa." }, { status: 400 });
    }
  }

  const now = new Date().toISOString();
  const payload = {
    company_id: ctx.companyId,
    user_id: targetUserId,
    holder_name: holderName || null,
    document_type: documentType || null,
    document_number: documentNumber || null,
    payout_method: payoutMethod,
    pix_key_type: pixKeyType || null,
    pix_key: pixKey || null,
    bank_name: bankName || null,
    bank_code: bankCode || null,
    agency_number: agencyNumber || null,
    agency_digit: agencyDigit || null,
    account_number: accountNumber || null,
    account_digit: accountDigit || null,
    account_type: accountType || null,
    active,
    notes: notes || null,
    updated_at: now,
  };

  const { error } = await supabase.from("employee_payout_profiles").upsert(payload, {
    onConflict: "company_id,user_id",
  });

  if (error) {
    return NextResponse.json({ error: error.message || "Falha ao salvar perfil de repasse." }, { status: 500 });
  }

  return NextResponse.json({
    ok: true,
    message: "Perfil de repasse salvo com sucesso.",
  });
}
