"use client";

import React, { useState, useMemo, useEffect } from "react";
import { X } from "lucide-react";
import {
  convertIsoDatesToGroups,
  formatDateFr,
  parseFrenchedDate,
  formatQuantifiedDates,
} from "@/lib/dateFormatter";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";

interface DatesQuantityModalProps {
  isOpen: boolean;
  onClose: () => void;
  onApply: (result: {
    selectedDates: string[];
    hasMultiMonth: boolean;
    pdfFormatted: string;
    globalQuantity?: number;
    globalDuration?: "3" | "4";
    totalHours?: number; // Total des heures saisies (pour jours_travail)
    totalQuantities?: number; // Somme de toutes les quantités saisies par jour
  }) => void;
  selectedDates: string[]; // format input "12/10, 13/10, ..."
  dateType: "representations" | "repetitions" | "jours_travail" | "heures_repetitions"; // Type de dates pour déterminer le libellé
  minDate?: string;
  maxDate?: string;
  allowSkipHoursByDay?: boolean; // Permet de cocher "Ne pas appliquer d'heures par jour"
  repetitionDuration?: "3" | "4"; // Durée des services de répétition (3 ou 4 heures)
}

interface DateGroupWithQuantity {
  displayFr: string; // "le 12/10" ou "du 14/10 au 17/10"
  startIso: string;
  endIso?: string;
  isRange: boolean;
  quantity: number | string;
  unit: string; // "représentation(s)", "service(s) de répétition", "heure(s)"
}

export default function DatesQuantityModal({
  isOpen,
  onClose,
  onApply,
  selectedDates,
  dateType,
  minDate,
  maxDate,
  allowSkipHoursByDay = false,
  repetitionDuration,
}: DatesQuantityModalProps) {
  const yearContext = minDate || maxDate || new Date().toISOString().slice(0, 10);

  // Convertir les dates sélectionnées en ISO pour grouper
  const selectedIsos = useMemo(() => {
    return selectedDates
      .map((d) => parseFrenchedDate(d.trim(), yearContext))
      .filter((iso) => iso.length === 10);
  }, [selectedDates, yearContext]);

  // Générer les groupes de dates
  const dateGroups = useMemo(() => convertIsoDatesToGroups(selectedIsos), [selectedIsos]);

  // État pour les quantités saisies par date ISO (object { iso: qty })
  const initialQuantities = useMemo(() => {
    const map: Record<string, number | string> = {};
    selectedIsos.forEach((iso) => {
      map[iso] = 1;
    });
    return map;
  }, [selectedIsos]);

  const [quantities, setQuantities] = useState<Record<string, number | string>>(initialQuantities);

  // État pour la checkbox "Ne pas appliquer d'heures par jour"
  const [skipHoursByDay, setSkipHoursByDay] = useState<boolean>(false);
  
  // État pour le nombre global saisi quand skipHoursByDay est coché
  const [globalQuantity, setGlobalQuantity] = useState<string>("");
  
  // État pour la durée des services quand c'est des répétitions sans détail
  const [globalDuration, setGlobalDuration] = useState<"3" | "4">(repetitionDuration || "4");

  // État pour le champ "Appliquer à toutes les dates"
  const [applyToAllValue, setApplyToAllValue] = useState<string>("");

  // Erreur de validation
  const [validationError, setValidationError] = useState<string>("");

  // Réinitialiser les quantités quand on coche "Ne pas appliquer d'heures par jour"
  useEffect(() => {
    if (skipHoursByDay) {
      // Vider toutes les quantités
      const emptyQuantities: Record<string, number | string> = {};
      selectedIsos.forEach((iso) => {
        emptyQuantities[iso] = "";
      });
      setQuantities(emptyQuantities);
      setApplyToAllValue("");
      setValidationError("");
    } else {
      // Réinitialiser le nombre global
      setGlobalQuantity("");
    }
  }, [skipHoursByDay, selectedIsos]);

  // Déterminer le libellé et les unités disponibles
  function getDefaultUnit(type: string, isRange: boolean): string {
    switch (type) {
      case "representations":
        return "représentation(s)";
      case "repetitions":
        return "service(s) de répétition";
      case "jours_travail":
        return isRange ? "heure(s) par jour" : "heure(s)";
      case "heures_repetitions":
        return isRange ? "heure(s) par jour" : "heure(s)";
      default:
        return "";
    }
  }

  function getUnitLabel(type: string, isRange: boolean): string {
    switch (type) {
      case "representations":
        return "représentation(s)";
      case "repetitions":
        return "service(s) de répétition";
      case "jours_travail":
        return isRange ? "heure(s) par jour" : "heure(s)";
      case "heures_repetitions":
        return isRange ? "heure(s) par jour" : "heure(s)";
      default:
        return "";
    }
  }

  function getSkipCheckboxLabel(type: string): { title: string; description: string } {
    switch (type) {
      case "representations":
        return {
          title: "Ne pas appliquer de représentations par jour",
          description: "Vous pouvez choisir d'afficher le détail des représentations par jour sur le contrat de travail, ou uniquement le nombre global de représentations."
        };
      case "repetitions":
        return {
          title: "Ne pas appliquer de répétitions par jour",
          description: "Vous pouvez choisir d'afficher le détail des répétitions par jour sur le contrat de travail, ou uniquement le nombre global de répétitions."
        };
      case "jours_travail":
      case "heures_repetitions":
      default:
        return {
          title: "Ne pas appliquer d'heures par jour",
          description: "Vous pouvez choisir d'afficher le détail des heures de travail par jour sur le contrat de travail, ou uniquement le nombre global d'heures."
        };
    }
  }

  const skipCheckboxText = getSkipCheckboxLabel(dateType);

  // Générer le texte formaté au format PDFMonkey en regroupant consécutifs avec même qty
  const pdfFormatted = useMemo(() => {
    if (!selectedIsos || selectedIsos.length === 0) return "";
    
    // Si on ne veut pas de détails par jour, générer un format simplifié
    if (skipHoursByDay) {
      // Grouper les dates consécutives sans quantités
      const groups = convertIsoDatesToGroups(selectedIsos);
      const parts = groups.map(g => {
        if (g.type === "range") {
          // Le displayFr est déjà formaté comme "du DD/MM au DD/MM"
          // On le garde tel quel, pas besoin de manipulation
          return g.displayFr;
        }
        // Pour les dates isolées : "le DD/MM"
        return g.displayFr;
      });
      return parts.join(' ; ') + '.';
    }
    
    return formatQuantifiedDates(selectedIsos, quantities, dateType, repetitionDuration);
  }, [selectedIsos, quantities, dateType, skipHoursByDay, repetitionDuration]);

  const handleQuantityChange = (iso: string, value: string) => {
    // Gestion de la valeur vide: on permet l'effacement temporaire
    if (value === "") {
      setValidationError("");
      setQuantities({ ...quantities, [iso]: "" });
      return;
    }

    const n = parseInt(value, 10) || 0;
    
    // Validation selon le type de dates
    if (dateType === "heures_repetitions" || dateType === "jours_travail") {
      // Pour les heures, accepter n'importe quel nombre >= 1
      if (n < 1) {
        setValidationError(`La quantité doit être au moins 1`);
        return;
      }
    } else {
      // Pour les représentations et services de répétition : limiter à 1-3
      if (n < 1 || n > 3) {
        setValidationError(`La quantité doit être entre 1 et 3`);
        return;
      }
    }
    
    setValidationError("");
    setQuantities({ ...quantities, [iso]: n });
  };

  const handleApplyToAll = () => {
    if (!applyToAllValue || applyToAllValue === "") {
      setValidationError("Veuillez saisir une quantité");
      return;
    }

    const n = parseInt(applyToAllValue, 10);
    
    // Validation selon le type de dates
    if (dateType === "heures_repetitions" || dateType === "jours_travail") {
      if (n < 1) {
        setValidationError(`La quantité doit être au moins 1`);
        return;
      }
    } else {
      if (n < 1 || n > 3) {
        setValidationError(`La quantité doit être entre 1 et 3`);
        return;
      }
    }

    // Appliquer la valeur à toutes les dates
    const newQuantities: Record<string, number | string> = {};
    selectedIsos.forEach((iso) => {
      newQuantities[iso] = n;
    });
    setQuantities(newQuantities);
    setValidationError("");
    setApplyToAllValue(""); // Réinitialiser le champ
  };

  const handleApply = () => {
    let globalQty: number | undefined = undefined;
    let globalDur: "3" | "4" | undefined = undefined;
    let totalHrs: number | undefined = undefined;
    let totalQtys: number | undefined = undefined;
    
    // Si on ne veut pas d'heures par jour, valider le nombre global
    if (skipHoursByDay) {
      const qty = parseInt(globalQuantity, 10);
      if (!globalQuantity || isNaN(qty) || qty < 1) {
        setValidationError("Veuillez saisir un nombre global valide (>= 1)");
        return;
      }
      globalQty = qty;
      
      // Pour les répétitions, récupérer aussi la durée
      if (dateType === "repetitions") {
        globalDur = globalDuration;
      }
    } else {
      // Vérifier que toutes les quantités sont > 0 ET calculer la somme totale
      let sum = 0;
      for (const iso of selectedIsos) {
        const qty = quantities[iso];
        if (!qty || qty === "" || (typeof qty === "number" && qty < 1)) {
          setValidationError("Toutes les quantités doivent être >= 1");
          return;
        }
        // Calculer le total de TOUTES les quantités
        const qtyNum = typeof qty === "number" ? qty : parseInt(String(qty), 10);
        if (!isNaN(qtyNum)) {
          sum += qtyNum;
        }
      }
      
      // Stocker la somme totale pour les représentations/répétitions
      if (dateType === "representations" || dateType === "repetitions") {
        totalQtys = sum;
      }
      
      // Si c'est des jours de travail, on retourne le total d'heures
      if (dateType === "jours_travail" && sum > 0) {
        totalHrs = sum;
      }
    }

    if (!pdfFormatted) {
      setValidationError("Erreur lors du formatage des dates");
      return;
    }

    onApply({
      selectedDates: selectedDates,
      hasMultiMonth: selectedIsos.length > 0 && checkMultiMonth(selectedIsos),
      pdfFormatted,
      globalQuantity: globalQty,
      globalDuration: dateType === "repetitions" ? globalDuration : globalDur,
      totalHours: totalHrs,
      totalQuantities: totalQtys,
    });

    onClose();
  };

  function checkMultiMonth(isos: string[]): boolean {
    if (isos.length <= 1) return false;
    const months = new Set(isos.map((iso) => iso.slice(0, 7))); // YYYY-MM
    return months.size > 1;
  }

  if (!isOpen) return null;

  return (
    <>
      {/* Overlay */}
      <div 
        className="fixed inset-0 bg-black/50 z-[100]" 
        onClick={(e) => {
          e.stopPropagation();
          onClose();
        }} 
      />

      {/* Modale */}
      <div className="fixed inset-0 z-[101] flex items-center justify-center p-4 pointer-events-none">
        <div 
          className="bg-white rounded-2xl shadow-2xl w-full max-w-md max-h-[80vh] flex flex-col pointer-events-auto"
          onClick={(e) => e.stopPropagation()}
        >
          {/* Header */}
          <div className="flex items-center justify-between p-4 border-b bg-gradient-to-r from-indigo-50 to-purple-50">
            <h2 className="text-lg font-semibold text-slate-900">
              Indiquez les quantités
            </h2>
            <button
              onClick={onClose}
              className="p-1 hover:bg-white/50 rounded-lg transition"
            >
              <X className="w-5 h-5 text-slate-500" />
            </button>
          </div>

          {/* Contenu */}
          <div className="flex-1 overflow-y-auto p-4 space-y-4">
            {/* Card option pour ne pas appliquer d'heures par jour */}
            {allowSkipHoursByDay && (
              <div className="p-4 rounded-lg border border-indigo-200 bg-indigo-50 space-y-3">
                <label className="flex items-start gap-3 cursor-pointer">
                  <input
                    type="checkbox"
                    checked={skipHoursByDay}
                    onChange={(e) => setSkipHoursByDay(e.target.checked)}
                    className="mt-1 w-4 h-4 rounded border-indigo-300 text-indigo-600 focus:ring-indigo-500"
                  />
                  <div className="flex-1">
                    <div className="font-medium text-indigo-900">
                      {skipCheckboxText.title}
                    </div>
                    <div className="text-xs text-indigo-700 mt-1">
                      {skipCheckboxText.description}
                    </div>
                  </div>
                </label>
                
                {/* Champ de saisie du nombre global si coché */}
                {skipHoursByDay && (
                  <div className="space-y-2">
                    <label className="block text-sm font-medium text-indigo-900">
                      {dateType === "representations" && "Nombre total de représentations"}
                      {dateType === "repetitions" && "Nombre total de services de répétition"}
                      {(dateType === "jours_travail" || dateType === "heures_repetitions") && "Nombre total d'heures"}
                    </label>
                    <Input
                      type="number"
                      min={1}
                      placeholder="Saisissez le nombre"
                      value={globalQuantity}
                      onChange={(e) => setGlobalQuantity(e.target.value)}
                      className="bg-white"
                    />
                    
                    {/* Durée pour les répétitions */}
                    {dateType === "repetitions" && (
                      <div className="mt-2">
                        <label className="block text-sm font-medium text-indigo-900 mb-1">
                          Durée des services de répétition
                        </label>
                        <div className="flex items-center gap-4">
                          <label className="inline-flex items-center gap-2 text-sm cursor-pointer">
                            <input
                              type="radio"
                              checked={globalDuration === "3"}
                              onChange={() => setGlobalDuration("3")}
                              className="text-indigo-600"
                            />
                            3 heures
                          </label>
                          <label className="inline-flex items-center gap-2 text-sm cursor-pointer">
                            <input
                              type="radio"
                              checked={globalDuration === "4"}
                              onChange={() => setGlobalDuration("4")}
                              className="text-indigo-600"
                            />
                            4 heures
                          </label>
                        </div>
                      </div>
                    )}
                  </div>
                )}
              </div>
            )}

            {validationError && (
              <div className="p-3 bg-red-50 border border-red-200 rounded-lg text-sm text-red-800">
                {validationError}
              </div>
            )}

            {/* Champ pour appliquer à toutes les dates */}
            {!skipHoursByDay && selectedIsos.length > 1 && (
              <div className="p-4 rounded-lg border border-emerald-200 bg-emerald-50 space-y-2">
                <div className="font-medium text-emerald-900 text-sm mb-2">
                  Appliquer la même quantité à toutes les dates
                </div>
                <div className="flex items-center gap-2">
                  <Input
                    type="number"
                    min={1}
                    max={dateType === "heures_repetitions" || dateType === "jours_travail" ? undefined : 3}
                    placeholder={dateType === "heures_repetitions" || dateType === "jours_travail" ? "≥1" : "1-3"}
                    value={applyToAllValue}
                    onChange={(e) => setApplyToAllValue(e.target.value)}
                    className="w-24"
                  />
                  <span className="text-sm text-emerald-700">{getUnitLabel(dateType, false)}</span>
                  <button
                    type="button"
                    onClick={handleApplyToAll}
                    className="ml-auto bg-emerald-600 hover:bg-emerald-700 text-white text-sm px-3 py-1.5 rounded-md font-medium transition-colors"
                  >
                    Appliquer
                  </button>
                </div>
              </div>
            )}

            {/* Durée des services de répétitions */}
            {dateType === "repetitions" && (
              <div className="p-4 rounded-lg border border-indigo-200 bg-indigo-50 space-y-3">
                <div className="font-medium text-indigo-900 text-sm">
                  Durée des services de répétitions
                </div>
                <div className="flex items-center gap-4">
                  <label className="inline-flex items-center gap-2 text-sm cursor-pointer">
                    <input
                      type="radio"
                      checked={globalDuration === "3"}
                      onChange={() => setGlobalDuration("3")}
                      className="text-indigo-600"
                    />
                    3 heures
                  </label>
                  <label className="inline-flex items-center gap-2 text-sm cursor-pointer">
                    <input
                      type="radio"
                      checked={globalDuration === "4"}
                      onChange={() => setGlobalDuration("4")}
                      className="text-indigo-600"
                    />
                    4 heures
                  </label>
                </div>
                <div className="text-xs text-indigo-700 leading-relaxed">
                  La durée des services de répétitions dépend de votre CCN et du type de profession. Consultez les minima pour plus d'infos ou contactez-nous en cas de doute.
                </div>
              </div>
            )}
            
            {dateGroups.length === 0 ? (
              <div className="text-center py-8 text-slate-500">
                Aucune date sélectionnée
              </div>
            ) : skipHoursByDay ? (
              // Si on ne veut pas d'heures par jour, afficher juste la liste des dates sans input
              <div className="space-y-2">
                <div className="text-sm font-medium text-slate-700 mb-2">
                  Dates sélectionnées :
                </div>
                {selectedIsos.map((iso) => (
                  <div key={iso} className="p-2 border rounded-lg bg-slate-50 text-sm text-slate-700">
                    {formatDateFr(iso)}
                  </div>
                ))}
              </div>
            ) : (
              // Afficher la liste des dates individuelles pour permettre quantité par date
              selectedIsos.map((iso) => (
                <div key={iso} className="p-3 border rounded-lg bg-slate-50 space-y-2">
                  <div className="text-sm font-medium text-slate-700">{formatDateFr(iso)}</div>
                  <div className="flex items-center gap-2">
                    <Input
                      type="number"
                      min={1}
                      max={dateType === "heures_repetitions" || dateType === "jours_travail" ? undefined : 3}
                      placeholder={dateType === "heures_repetitions" || dateType === "jours_travail" ? "≥1" : "1-3"}
                      value={quantities[iso] ?? ""}
                      onChange={(e) => handleQuantityChange(iso, e.target.value)}
                      className="w-20"
                    />
                    <span className="text-sm text-slate-600">{getUnitLabel(dateType, false)}</span>
                  </div>
                </div>
              ))
            )}

            {/* Aperçu du texte généré */}
            {pdfFormatted && (
              <div className="mt-4 p-3 bg-blue-50 border border-blue-200 rounded-lg">
                <div className="text-xs font-semibold text-blue-900 mb-1">
                  Aperçu:
                </div>
                <div className="text-sm text-blue-800 font-mono break-words">
                  {pdfFormatted}
                </div>
              </div>
            )}
          </div>

          {/* Footer */}
          <div className="flex gap-2 p-4 border-t bg-slate-50">
            <Button
              variant="outline"
              onClick={onClose}
              className="flex-1"
            >
              Annuler
            </Button>
            <Button
              onClick={handleApply}
              disabled={!pdfFormatted}
              className="flex-1"
            >
              Appliquer
            </Button>
          </div>
        </div>
      </div>
    </>
  );
}
