import React, { useState, useRef, useCallback } from 'react';
import TreeView from '@/components/Structure/Competencies/TreeView';
import SectionHeader from '@/components/SectionHeader';
import { Award, CheckCircle } from 'lucide-react';
import SelectChoice from '@/components/Form/SelectChoice';
import CheckBox from '@/components/Form/CheckBox';
import Button from '@/components/Form/Button';
import { useEstablishment } from '@/context/EstablishmentContext';
import {
  createEstablishmentCompetencies,
  deleteEstablishmentCompetencies,
} from '@/app/actions/schoolAction';
import { useCsrfToken } from '@/context/CsrfContext';
import { useNotification } from '@/context/NotificationContext';

const cycles = [
  { id: 1, label: 'Cycle 1' },
  { id: 2, label: 'Cycle 2' },
  { id: 3, label: 'Cycle 3' },
  { id: 4, label: 'Cycle 4' },
];

export default function CompetenciesList({
  establishmentCompetencies,
  onChangeCycle,
}) {
  const [selectedCycle, setSelectedCycle] = useState(cycles[0].id);
  const [showSelectedOnlyByCycle, setShowSelectedOnlyByCycle] = useState({
    1: true,
    2: true,
    3: true,
    4: true,
  });
  const [expandAllByCycle, setExpandAllByCycle] = useState({
    1: false,
    2: false,
    3: false,
    4: false,
  });
  const [hasSelectionByCycle, setHasSelectionByCycle] = useState({
    1: false,
    2: false,
    3: false,
    4: false,
  });
  const { selectedEstablishmentId, profileRole } = useEstablishment();
  const csrfToken = useCsrfToken();
  const { showNotification } = useNotification();

  // Référence vers le composant TreeView pour récupérer les compétences sélectionnées
  const treeViewRef = useRef();

  // Met à jour l'état de sélection à chaque changement dans TreeView
  const handleSelectionChange = useCallback(
    (selectedCompetencies) => {
      setHasSelectionByCycle((prev) => ({
        ...prev,
        [selectedCycle]: selectedCompetencies.length > 0,
      }));
    },
    [selectedCycle]
  );

  // Filtrage : si showSelectedOnly, on affiche uniquement les compétences de l'établissement (state !== "none")
  // sinon, on affiche toutes les compétences du cycle
  const filteredData = (establishmentCompetencies.data || []).map(
    (domaine) => ({
      ...domaine,
      categories: domaine.categories.map((cat) => ({
        ...cat,
        competences: showSelectedOnlyByCycle[selectedCycle]
          ? cat.competences.filter((c) => c.state !== 'none')
          : cat.competences,
      })),
    })
  );

  const showSelectedOnly = showSelectedOnlyByCycle[selectedCycle];
  const expandAll = expandAllByCycle[selectedCycle];

  const handleShowSelectedOnlyChange = () => {
    setShowSelectedOnlyByCycle((prev) => ({
      ...prev,
      [selectedCycle]: !prev[selectedCycle],
    }));
  };

  const handleExpandAllChange = () => {
    setExpandAllByCycle((prev) => ({
      ...prev,
      [selectedCycle]: !prev[selectedCycle],
    }));
  };

  const handleCycleChange = (e) => {
    const value = Number(e.target.value);
    setSelectedCycle(value);
    setHasSelectionByCycle((prev) => ({
      ...prev,
      [value]: false,
    }));
    // Réinitialise la sélection visuelle dans le TreeView
    if (treeViewRef.current && treeViewRef.current.clearSelection) {
      treeViewRef.current.clearSelection();
    }
    onChangeCycle(value);
  };

  const handleSubmit = () => {
    if (!treeViewRef.current || !treeViewRef.current.getSelectedCompetencies)
      return;

    const selectedIds = treeViewRef.current.getSelectedCompetencies();

    const toCreate = [];
    const toDelete = [];

    const selectedCustomKeys = new Set(
      (establishmentCompetencies.data || []).flatMap((domaine) =>
        domaine.categories.flatMap((cat) =>
          cat.competences
            .filter(
              (c) =>
                c.state === 'custom' &&
                (selectedIds.includes(String(c.competence_id)) ||
                  selectedIds.includes(Number(c.competence_id)))
            )
            .map((c) => `${cat.categorie_id}__${c.nom.trim().toLowerCase()}`)
        )
      )
    );

    (establishmentCompetencies.data || []).forEach((domaine) => {
      domaine.categories.forEach((cat) => {
        cat.competences.forEach((competence) => {
          const isSelected =
            selectedIds.includes(String(competence.competence_id)) ||
            selectedIds.includes(Number(competence.competence_id));
          const key = `${cat.categorie_id}__${competence.nom.trim().toLowerCase()}`;

          // "none" sélectionné => à créer, sauf si une custom du même nom/catégorie est déjà sélectionnée
          if (
            competence.state === 'none' &&
            isSelected &&
            !selectedCustomKeys.has(key)
          ) {
            toCreate.push({
              category_id: cat.categorie_id,
              establishment_id: selectedEstablishmentId,
              nom: competence.nom,
            });
          } else if (competence.state === 'custom' && isSelected) {
            // Suppression d'une compétence custom
            toDelete.push({
              competence_id: competence.competence_id, // id de EstablishmentCompetency
              nom: competence.nom,
              category_id: cat.categorie_id,
              establishment_id: selectedEstablishmentId,
            });
          }
        });
      });
    });

    const afterSuccess = () => {
      if (treeViewRef.current && treeViewRef.current.clearSelection) {
        treeViewRef.current.clearSelection();
      }
      setHasSelectionByCycle((prev) => ({
        ...prev,
        [selectedCycle]: false,
      }));
      onChangeCycle(selectedCycle);
      showNotification('Opération effectuée avec succès', 'success', 'Succès');
    };

    if (toCreate.length > 0 && toDelete.length > 0) {
      Promise.all([
        createEstablishmentCompetencies(toCreate, csrfToken),
        deleteEstablishmentCompetencies(
          toDelete.map((item) => item.competence_id),
          csrfToken
        ),
      ])
        .then(afterSuccess)
        .catch((error) => {
          showNotification(
            error.message ||
              'Erreur apparue lors de la mise à jour des compétences',
            'error',
            'Erreur'
          );
        });
    } else if (toCreate.length > 0) {
      createEstablishmentCompetencies(toCreate, csrfToken)
        .then(afterSuccess)
        .catch((error) => {
          showNotification(
            error.message ||
              'Erreur apparue lors de la mise à jour des compétences',
            'error',
            'Erreur'
          );
        });
    } else if (toDelete.length > 0) {
      deleteEstablishmentCompetencies(
        toDelete.map((item) => item.competence_id),
        csrfToken
      )
        .then(afterSuccess)
        .catch((error) => {
          showNotification(
            error.message ||
              'Erreur apparue lors de la mise à jour des compétences',
            'error',
            'Erreur'
          );
        });
    }
  };

  const hasSelection = hasSelectionByCycle[selectedCycle];

  return (
    <div className="h-full flex flex-col">
      <SectionHeader
        icon={Award}
        title="Liste des compétences"
        description="Gérez les compétences par cycle"
      />
      {/* Zone filtres centrée et plus large */}
      <div className="mb-6 flex justify-center">
        <div className="w-full max-w-3xl flex flex-col gap-4 p-6 rounded-lg border border-primary/20 shadow-sm bg-white/80 backdrop-blur-sm">
          <div className="flex flex-col sm:flex-row sm:items-start gap-8">
            {/* Select cycle */}
            <div className="flex-1 min-w-[220px]">
              <SelectChoice
                name="cycle"
                label="Cycle"
                placeHolder="Sélectionnez un cycle"
                choices={cycles.map((cycle) => ({
                  value: cycle.id,
                  label: cycle.label,
                }))}
                selected={selectedCycle}
                callback={handleCycleChange}
              />
            </div>
            {/* Cases à cocher l'une sous l'autre */}
            <div className="flex flex-col gap-4 min-w-[220px]">
              <CheckBox
                item={{ id: 'showSelectedOnly' }}
                formData={{ showSelectedOnly }}
                handleChange={handleShowSelectedOnlyChange}
                fieldName="showSelectedOnly"
                itemLabelFunc={() => 'Uniquement les compétences sélectionnées'}
                horizontal={false}
              />
              <CheckBox
                item={{ id: 'expandAll' }}
                formData={{ expandAll }}
                handleChange={handleExpandAllChange}
                fieldName="expandAll"
                itemLabelFunc={() => 'Tout dérouler'}
                horizontal={false}
              />
            </div>
          </div>
        </div>
      </div>
      {/* Zone scrollable pour le TreeView */}
      <div className="flex-1 min-h-0 overflow-y-auto">
        <TreeView
          ref={treeViewRef}
          data={filteredData}
          expandAll={expandAll}
          onSelectionChange={handleSelectionChange}
        />
      </div>
      {/* Bouton submit centré en bas */}
      <div className="flex justify-center mb-2 mt-6">
        {profileRole !== 0 && (
          <Button
            text="Sauvegarder"
            className={`px-6 py-2 rounded-md shadow ${
              !hasSelection
                ? 'bg-gray-300 text-gray-500 cursor-not-allowed'
                : 'bg-primary text-white hover:bg-primary'
            }`}
            onClick={handleSubmit}
            primary
            disabled={!hasSelection}
          />
        )}
      </div>
      {/* Légende en dessous du bouton, alignée à gauche */}
      <div className="flex flex-row items-center gap-4 mb-4">
        <span className="flex items-center gap-2 text-secondary font-bold">
          <CheckCircle className="w-4 h-4 text-primary" />
          Compétence requise
        </span>
        <span className="flex items-center gap-2 text-primary font-semibold">
          Compétence sélectionnée ou créée
        </span>
        <span className="flex items-center gap-2 text-gray-500">
          Compétence ignorée
        </span>
      </div>
    </div>
  );
}
