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

type PlanRequestBody = {
  name?: unknown;
  description?: unknown;
  effective_from?: unknown;
  percent_value?: unknown;
  target_type?: unknown;
  target_user_id?: unknown;
  target_role?: unknown;
};

const VALID_TARGET_ROLES = new Set(["owner", "admin", "manager", "financial", "production", "sales", "viewer"]);

function toNumber(value: unknown) {
  if (typeof value === "number" && Number.isFinite(value)) return value;
  if (typeof value === "string") {
    const normalized = Number(value.replace(",", "."));
    return Number.isFinite(normalized) ? normalized : Number.NaN;
  }
  return Number.NaN;
}

export async function GET() {
  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 canReadSelf = canCompany(ctx, user.id, "commissions.self");
  if (!canCompany(ctx, user.id, "commissions.read") && !canReadSelf) {
    return NextResponse.json({ error: "Sem permissão." }, { status: 403 });
  }

  const { data: plans, error: plansError } = await supabase
    .from("commission_plans")
    .select("id,company_id,name,description,status,created_at,updated_at")
    .eq("company_id", ctx.companyId)
    .order("created_at", { ascending: false });

  if (plansError) {
    return NextResponse.json({ error: "Falha ao listar planos de comissão." }, { status: 500 });
  }

  const planIds = (plans ?? []).map((plan) => plan.id);
  const { data: versions, error: versionsError } = planIds.length
    ? await supabase
        .from("commission_plan_versions")
        .select(
          "id,plan_id,version_number,status,effective_from,effective_to,trigger_type,calculation_basis,rounding_mode,minimum_payout_amount,allow_negative_carry,created_at"
        )
        .eq("company_id", ctx.companyId)
        .in("plan_id", planIds)
        .order("version_number", { ascending: false })
    : { data: [], error: null };

  if (versionsError) {
    return NextResponse.json({ error: "Falha ao listar versões dos planos." }, { status: 500 });
  }

  const versionIds = (versions ?? []).map((version) => version.id);
  const [{ data: rules, error: rulesError }, { data: assignments, error: assignmentsError }] = versionIds.length
    ? await Promise.all([
        supabase
          .from("commission_rules")
          .select(
            "id,plan_version_id,name,rule_type,percent_value,fixed_value,channel,payment_method,min_amount,max_amount,priority,active,created_at"
          )
          .eq("company_id", ctx.companyId)
          .in("plan_version_id", versionIds)
          .order("priority", { ascending: false }),
        supabase
          .from("commission_plan_assignments")
          .select("id,plan_version_id,target_type,target_user_id,target_role,priority,active_from,active_to,created_at")
          .eq("company_id", ctx.companyId)
          .in("plan_version_id", versionIds)
          .order("priority", { ascending: false }),
      ])
    : [{ data: [], error: null }, { data: [], error: null }];

  if (rulesError || assignmentsError) {
    return NextResponse.json({ error: "Falha ao listar regras e vínculos dos planos." }, { status: 500 });
  }

  const versionsByPlan = new Map<string, Array<Record<string, unknown>>>();
  for (const version of versions ?? []) {
    const versionRules = (rules ?? []).filter((rule) => rule.plan_version_id === version.id);
    const versionAssignments = (assignments ?? []).filter((assignment) => assignment.plan_version_id === version.id);
    const current = versionsByPlan.get(version.plan_id) ?? [];
    current.push({
      ...version,
      rules: versionRules,
      assignments: versionAssignments,
    });
    versionsByPlan.set(version.plan_id, current);
  }

  return NextResponse.json({
    plans: (plans ?? []).map((plan) => ({
      ...plan,
      versions: versionsByPlan.get(plan.id) ?? [],
    })),
  });
}

export async function POST(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);
  if (!canCompany(ctx, user.id, "commissions.write")) {
    return NextResponse.json({ error: "Sem permissão para criar plano de comissão." }, { status: 403 });
  }

  const body = (await req.json().catch(() => null)) as PlanRequestBody | null;
  const name = typeof body?.name === "string" ? body.name.trim() : "";
  const description = typeof body?.description === "string" ? body.description.trim() : "";
  const effectiveFrom = typeof body?.effective_from === "string" ? body.effective_from.trim() : "";
  const percentValue = toNumber(body?.percent_value);
  const targetType = body?.target_type === "user" || body?.target_type === "role" ? body.target_type : "company_default";
  const targetUserId = typeof body?.target_user_id === "string" ? body.target_user_id.trim() : "";
  const targetRole = typeof body?.target_role === "string" ? body.target_role.trim() : "";

  if (!name) {
    return NextResponse.json({ error: "Informe o nome do plano." }, { status: 400 });
  }

  if (!/^\d{4}-\d{2}-\d{2}$/.test(effectiveFrom)) {
    return NextResponse.json({ error: "Informe a data inicial do plano." }, { status: 400 });
  }

  if (!Number.isFinite(percentValue) || percentValue <= 0 || percentValue > 100) {
    return NextResponse.json({ error: "Informe um percentual de comissão válido entre 0,01 e 100." }, { status: 400 });
  }

  if (targetType === "user" && !targetUserId) {
    return NextResponse.json({ error: "Selecione o funcionário do plano." }, { status: 400 });
  }

  if (targetType === "role" && !VALID_TARGET_ROLES.has(targetRole)) {
    return NextResponse.json({ error: "Selecione um cargo válido para o plano." }, { status: 400 });
  }

  if (targetType === "user") {
    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 o funcionário do plano." }, { status: 500 });
    }

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

    if (membership && membership.active === false) {
      return NextResponse.json({ error: "Funcionário selecionado está inativo." }, { status: 400 });
    }
  }

  const now = new Date().toISOString();
  const { data: createdPlan, error: planError } = await supabase
    .from("commission_plans")
    .insert({
      company_id: ctx.companyId,
      name,
      description: description || null,
      status: "active",
      created_by: user.id,
      created_at: now,
      updated_at: now,
    })
    .select("id,name")
    .single();

  if (planError || !createdPlan?.id) {
    return NextResponse.json({ error: planError?.message || "Falha ao criar plano." }, { status: 500 });
  }

  const { data: createdVersion, error: versionError } = await supabase
    .from("commission_plan_versions")
    .insert({
      plan_id: createdPlan.id,
      company_id: ctx.companyId,
      version_number: 1,
      status: "published",
      effective_from: effectiveFrom,
      effective_to: null,
      trigger_type: "payment",
      calculation_basis: "received_gross",
      rounding_mode: "half_up",
      minimum_payout_amount: 0,
      allow_negative_carry: false,
      notes: null,
      created_by: user.id,
      created_at: now,
      updated_at: now,
    })
    .select("id")
    .single();

  if (versionError || !createdVersion?.id) {
    await supabase.from("commission_plans").delete().eq("id", createdPlan.id);
    return NextResponse.json({ error: versionError?.message || "Falha ao criar versão do plano." }, { status: 500 });
  }

  const { error: assignmentError } = await supabase.from("commission_plan_assignments").insert({
    company_id: ctx.companyId,
    plan_version_id: createdVersion.id,
    target_type: targetType,
    target_user_id: targetType === "user" ? targetUserId : null,
    target_role: targetType === "role" ? targetRole : null,
    priority: targetType === "user" ? 100 : targetType === "role" ? 50 : 10,
    active_from: effectiveFrom,
    active_to: null,
    created_by: user.id,
    created_at: now,
    updated_at: now,
  });

  if (assignmentError) {
    await supabase.from("commission_plan_versions").delete().eq("id", createdVersion.id);
    await supabase.from("commission_plans").delete().eq("id", createdPlan.id);
    return NextResponse.json({ error: assignmentError.message || "Falha ao vincular o plano." }, { status: 500 });
  }

  const { error: ruleError } = await supabase.from("commission_rules").insert({
    company_id: ctx.companyId,
    plan_version_id: createdVersion.id,
    name: `${name} - Regra padrão`,
    rule_type: "percent",
    percent_value: percentValue,
    fixed_value: null,
    product_id: null,
    category_id: null,
    client_id: null,
    channel: null,
    payment_method: null,
    min_amount: null,
    max_amount: null,
    stack_mode: "replace",
    priority: 100,
    active: true,
    created_by: user.id,
    created_at: now,
    updated_at: now,
  });

  if (ruleError) {
    await supabase.from("commission_plan_assignments").delete().eq("plan_version_id", createdVersion.id);
    await supabase.from("commission_plan_versions").delete().eq("id", createdVersion.id);
    await supabase.from("commission_plans").delete().eq("id", createdPlan.id);
    return NextResponse.json({ error: ruleError.message || "Falha ao criar regra do plano." }, { status: 500 });
  }

  return NextResponse.json({
    ok: true,
    plan_id: createdPlan.id,
    message: "Plano de comissão criado com sucesso.",
  });
}
