// app/api/staff/payslips/create/route.ts
import { createSbServer } from "@/lib/supabaseServer";
import { NextRequest, NextResponse } from "next/server";

export async function POST(request: NextRequest) {
  try {
    const sb = createSbServer();
    
    // Vérifier l'authentification
    const { data: { user } } = await sb.auth.getUser();
    if (!user) {
      return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
    }

    // Vérifier que c'est un staff
    const { data: me } = await sb
      .from("staff_users")
      .select("is_staff")
      .eq("user_id", user.id)
      .maybeSingle();

    if (!me?.is_staff) {
      return NextResponse.json({ error: "Forbidden" }, { status: 403 });
    }

    const body = await request.json();
    const {
      contract_id,
      period_start,
      period_end,
      pay_date,
      pay_number: requestedPayNumber,
      gross_amount,
      net_amount,
      net_after_withholding,
      employer_cost,
    } = body;

    // Validation
    if (!contract_id || !period_start || !period_end) {
      return NextResponse.json(
        { error: "contract_id, period_start et period_end sont requis" },
        { status: 400 }
      );
    }

    // Récupérer les infos du contrat pour obtenir l'organization_id et les dates
    const { data: contract, error: contractError } = await sb
      .from("cddu_contracts")
      .select("org_id, start_date, end_date")
      .eq("id", contract_id)
      .single();

    if (contractError || !contract) {
      return NextResponse.json(
        { error: "Contrat non trouvé" },
        { status: 404 }
      );
    }

    // Déterminer si le contrat est mono-mois ou multi-mois
    const contractStartDate = new Date(contract.start_date);
    const contractEndDate = new Date(contract.end_date);
    const isMultiMonth = contractStartDate.getMonth() !== contractEndDate.getMonth() || 
                         contractStartDate.getFullYear() !== contractEndDate.getFullYear();

    console.log("[POST /api/staff/payslips/create] Contract dates:", {
      start_date: contract.start_date,
      end_date: contract.end_date,
      isMultiMonth
    });

    // Calculer period_month (format YYYY-MM-01 - premier jour du mois basé sur period_start)
    const periodStartDate = new Date(period_start);
    const period_month = `${periodStartDate.getFullYear()}-${String(periodStartDate.getMonth() + 1).padStart(2, '0')}-01`;

    // Vérifier si une paie existe déjà pour ce contrat et ce mois
    const { data: existingPayslips, error: checkError } = await sb
      .from("payslips")
      .select("id, pay_number, period_month")
      .eq("contract_id", contract_id)
      .order("pay_number", { ascending: false });

    if (checkError) {
      console.error("[POST /api/staff/payslips/create] Error checking existing payslips:", checkError);
    }

    // Si contrat mono-mois et une paie existe déjà, interdire la création
    if (!isMultiMonth && existingPayslips && existingPayslips.length > 0) {
      const monthYear = new Date(period_month).toLocaleDateString('fr-FR', { month: 'long', year: 'numeric' });
      return NextResponse.json(
        { error: `Une fiche de paie existe déjà pour ce contrat mono-mois (${monthYear})` },
        { status: 409 }
      );
    }

    // Si contrat multi-mois, vérifier si une paie existe pour CE mois précis
    if (isMultiMonth && existingPayslips && existingPayslips.length > 0) {
      const existingForThisMonth = existingPayslips.find(p => p.period_month === period_month);
      if (existingForThisMonth) {
        const monthYear = new Date(period_month).toLocaleDateString('fr-FR', { month: 'long', year: 'numeric' });
        return NextResponse.json(
          { error: `Une fiche de paie existe déjà pour ce mois (${monthYear})` },
          { status: 409 }
        );
      }
    }

    // Déterminer le numéro de paie
    let pay_number = 1;
    if (isMultiMonth) {
      if (requestedPayNumber !== undefined && requestedPayNumber !== null) {
        // Utiliser le numéro fourni
        pay_number = requestedPayNumber;
      } else if (existingPayslips && existingPayslips.length > 0) {
        // Trouver le numéro de paie le plus élevé et ajouter 1
        const maxPayNumber = Math.max(...existingPayslips.map(p => p.pay_number || 0));
        pay_number = maxPayNumber + 1;
      }
      console.log("[POST /api/staff/payslips/create] Multi-month contract, setting pay_number to:", pay_number);
    } else {
      // Pour les contrats mono-mois, toujours 1
      pay_number = 1;
    }

    console.log("[POST /api/staff/payslips/create] Creating payslip with data:", {
      contract_id,
      organization_id: contract.org_id,
      period_start,
      period_end,
      period_month,
      pay_date,
      pay_number
    });

    // Créer la fiche de paie
    const { data: payslip, error: createError } = await sb
      .from("payslips")
      .insert({
        contract_id,
        organization_id: contract.org_id,
        period_start,
        period_end,
        period_month,
        pay_date: pay_date || null,
        pay_number,
        gross_amount: gross_amount || null,
        net_amount: net_amount || null,
        net_after_withholding: net_after_withholding || null,
        employer_cost: employer_cost || null,
        processed: false,
        transfer_done: false,
      })
      .select()
      .single();

    if (createError) {
      console.error("[POST /api/staff/payslips/create] Database error:", createError);
      
      // Gérer l'erreur de contrainte d'unicité
      if (createError.code === '23505' && createError.message.includes('payslips_contract_id_period_month_key')) {
        const monthYear = new Date(period_month).toLocaleDateString('fr-FR', { month: 'long', year: 'numeric' });
        return NextResponse.json(
          { error: `Une fiche de paie existe déjà pour ce contrat pour le mois de ${monthYear}` },
          { status: 409 }
        );
      }
      
      return NextResponse.json(
        { error: "Erreur lors de la création de la fiche de paie", details: createError.message },
        { status: 500 }
      );
    }

    console.log("[POST /api/staff/payslips/create] Payslip created successfully:", payslip.id);

    return NextResponse.json({ payslip }, { status: 201 });
  } catch (error) {
    console.error("[POST /api/staff/payslips/create] Error:", error);
    return NextResponse.json({ error: "Internal server error" }, { status: 500 });
  }
}
