import { NextResponse } from "next/server";
import { createSbServer } from "@/lib/supabaseServer";

async function assertStaff(sb: ReturnType<typeof createSbServer>, userId: string) {
  const { data: me } = await sb
    .from("staff_users")
    .select("is_staff")
    .eq("user_id", userId)
    .maybeSingle();
  return !!me?.is_staff;
}

function sanitizeDate(d: any) {
  if (!d) return null;
  const s = String(d);
  const val = s.length >= 10 ? s.slice(0, 10) : s;
  return /\d{4}-\d{2}-\d{2}/.test(val) ? val : null;
}

// Helper function to parse monetary amounts with French decimal notation (comma)
function parseMonetaryAmount(value: any): number | null {
  if (value === null || value === undefined || value === "") return null;
  const str = String(value).trim();
  if (!str) return null;
  
  // Replace comma with dot for proper parseFloat
  const normalized = str.replace(',', '.');
  const parsed = parseFloat(normalized);
  
  return isNaN(parsed) ? null : parsed;
}

// Mapping des noms de champs frontend -> Supabase
const FIELD_MAPPING: Record<string, string> = {
  "dates_repetitions": "jours_repetitions",
  "nb_representations": "cachets_representations", 
  "nb_services_repetition": "services_repetitions",
  "dates_representations": "jours_representations",
  "heures_total": "nombre_d_heures",
  "panier_repas": "paniers_repas"
  // Retirer le mapping brut -> gross_pay
};

const CONTRACT_UPDATABLE_FIELDS = new Set([
  // Champs de base
  "role", "start_date", "end_date", "hours", "gross_pay", "net_pay", "notes",
  "contract_pdf_s3_key", "reference", "structure",
  // Champs de workflow
  "etat_de_la_demande", "contrat_signe", "dpae", "etat_de_la_paie", "aem",
  // Informations contrat
  "production_name", "employee_name", "employee_matricule", "categorie_pro", "profession",
  "objet_spectacle", "contract_number", "analytique",
  // Champs CDDU spécifiques (noms exacts de Supabase)
  "salaire", "type_salaire", "cachets_representations", "services_repetitions", 
  "nombre_d_heures", "jours_representations", "jours_repetitions",
  "jours_travail_non_artiste", "jours_travail", "paniers_repas", "nombre_paniers_repas",
  "n_objet", "type_de_contrat", "type_d_embauche", "date_de_reception_de_la_demande",
  "net", "net_apres_pas", "brut", "cout_employeur", "fin_reelle", "motif_fin_contrat",
  "contrat_signe_par_employeur", "nombre_d_heures_par_jour", "precisions_salaire",
  "autreprecision_duree", "autreprecision_salaire",
  "heure_traitement_demande", "cachets", "heures_de_repet", "heures_annexe_8",
  "date_signature_contrat_salarie", "multi_mois", "panier_repas_ccn", 
  "si_non_montant_par_panier", "date_signature_contrat_employeur", "virement_effectue",
  "indemnite_hebergement", "nombre_indemnite_hebergement", "indemnite_hebergement_ccn",
  "si_non_montant_par_indemnite", "mineur_entre_16_et_18", "civilite_representant_legal",
  "nom_representant_legal", "adresse_representant_legal", "dob_representant_legal", 
  "cob_representant_legal", "periode", "docuseal_template_id", "docuseal_submission_id",
  "motif_cdd", "contract_kind", "date_signature",
  // Temps de travail réel (informatif pour le client)
  "jours_travail_reel",
  "nb_representations_reel",
  "nb_services_repetitions_reel", "nb_heures_repetitions_reel",
  "nb_heures_annexes_reel",
  "nb_cachets_aem_reel", "nb_heures_aem_reel"
]);

export async function GET(_req: Request, { params }: { params: { id: string } }) {
  const supabase = createSbServer();
  const { data: { user }, error: authError } = await supabase.auth.getUser();
  if (authError || !user) {
    return NextResponse.json({ error: "Non authentifié." }, { status: 401 });
  }
  const isStaff = await assertStaff(supabase, user.id);
  if (!isStaff) {
    return NextResponse.json({ error: "Accès réservé au staff." }, { status: 403 });
  }

  const { data: contract, error: cErr } = await supabase
    .from("cddu_contracts")
    .select("*")
    .eq("id", params.id)
    .single();

  if (cErr || !contract) {
    return NextResponse.json({ error: cErr?.message ?? "Contrat introuvable." }, { status: 404 });
  }

  const { data: payslips } = await supabase
    .from("payslips")
    .select("*")
    .eq("contract_id", params.id)
    .order("pay_number", { ascending: true });

  return NextResponse.json({ contract, payslips: payslips ?? [] });
}

export async function PATCH(req: Request, { params }: { params: { id: string } }) {
  const supabase = createSbServer();
  const { data: { user } } = await supabase.auth.getUser();
  if (!user) return NextResponse.json({ error: "Non authentifié." }, { status: 401 });
  const isStaff = await assertStaff(supabase, user.id);
  if (!isStaff) return NextResponse.json({ error: "Accès réservé au staff." }, { status: 403 });

  const body = await req.json().catch(() => ({}));

  // Logging pour debug
  console.log("PATCH body received:", JSON.stringify(body, null, 2));

  if (body?.contract && typeof body.contract === "object") {
    const patch: Record<string, any> = {};
    const skippedFields: string[] = [];
    
    for (const k of Object.keys(body.contract)) {
      // Mapper le nom du champ frontend vers le nom Supabase
      const supabaseFieldName = FIELD_MAPPING[k] || k;
      
      if (!CONTRACT_UPDATABLE_FIELDS.has(supabaseFieldName)) {
        skippedFields.push(k);
        continue;
      }
      let v = body.contract[k];
      
      // Nettoyer les valeurs vides pour les champs numériques
      if (v === "" || v === "null" || v === "undefined") {
        v = null;
      }
      
      // Sanitizer les dates
      if (k === "start_date" || k === "end_date") {
        v = sanitizeDate(v);
      }
      
      // Normaliser les champs monétaires (gérer les virgules françaises)
      if (["gross_pay", "net_pay", "brut", "net", "net_apres_pas", "cout_employeur", "salaire", "paniers_repas", "panier_repas"].includes(supabaseFieldName)) {
        v = parseMonetaryAmount(v);
      }
      
      // Utiliser le nom Supabase dans le patch
      patch[supabaseFieldName] = v;
    }
    
    // Synchronisation des champs brut et gross_pay pour maintenir la cohérence
    if (patch.gross_pay !== undefined) {
      // Si gross_pay est mis à jour (champ "Brut" de l'interface), synchroniser brut seulement si brut n'est pas déjà défini
      if (patch.brut === undefined) {
        patch.brut = patch.gross_pay;
      }
    }
    
    console.log("Fields to update:", patch);
    console.log("Skipped fields:", skippedFields);
    
    if (Object.keys(patch).length > 0) {
      console.log("About to update Supabase with:", patch);
      console.log("Contract ID:", params.id);
      console.log("User ID:", user.id);
      
      const { data, error: uErr, count } = await supabase
        .from("cddu_contracts")
        .update(patch)
        .eq("id", params.id)
        .select("*");
      
      if (uErr) {
        console.log("Supabase update error:", uErr);
        return NextResponse.json({ error: uErr.message }, { status: 400 });
      }
      
      console.log("Update result - data:", data);
      console.log("Update result - count:", count);
      console.log("Update successful for fields:", Object.keys(patch));
    } else {
      console.log("No valid fields to update");
    }
  }

  const { data: contract } = await supabase
    .from("cddu_contracts").select("*").eq("id", params.id).single();

  const { data: payslips } = await supabase
    .from("payslips")
    .select("*")
    .eq("contract_id", params.id)
    .order("pay_number", { ascending: true });

  return NextResponse.json({ contract, payslips: payslips ?? [] });
}
