import React, { useState, useEffect } from 'react';
import { Download, Edit3, Trash2, FolderPlus, Signature, AlertTriangle } from 'lucide-react';
import Modal from '@/components/Modal';
import Table from '@/components/Table';
import FileUploadDocuSeal from '@/components/Structure/Files/FileUploadDocuSeal';
import { BASE_URL } from '@/utils/Url';
import {
  // GET
  fetchRegistrationFileGroups,
  fetchRegistrationSchoolFileMasters,
  fetchRegistrationSchoolFileTemplates,
  fetchRegistrationParentFileMasters,
  // POST
  createRegistrationFileGroup,
  createRegistrationSchoolFileMaster,
  createRegistrationParentFileMaster,
  // PUT
  editRegistrationFileGroup,
  editRegistrationSchoolFileMaster,
  editRegistrationParentFileMaster,
  // DELETE
  deleteRegistrationFileGroup,
  deleteRegistrationSchoolFileMaster,
  deleteRegistrationParentFileMaster,

  removeTemplate
} from '@/app/actions/registerFileGroupAction';
import RegistrationFileGroupForm from '@/components/Structure/Files/RegistrationFileGroupForm';
import logger from '@/utils/logger';
import ParentFilesSection from '@/components/Structure/Files/ParentFilesSection';
import SectionHeader from '@/components/SectionHeader';
import Popup from '@/components/Popup';
import Loader from '@/components/Loader';
import { useNotification } from '@/context/NotificationContext';
import AlertMessage from '@/components/AlertMessage';

export default function FilesGroupsManagement({
  csrfToken,
  selectedEstablishmentId,
  apiDocuseal
}) {
  const [schoolFileMasters, setSchoolFileMasters] = useState([]);
  const [schoolFileTemplates, setSchoolFileTemplates] = useState([]);
  const [parentFiles, setParentFileMasters] = useState([]);
  const [groups, setGroups] = useState([]);
  const [selectedGroup, setSelectedGroup] = useState(null);
  const [isModalOpen, setIsModalOpen] = useState(false);
  const [isEditing, setIsEditing] = useState(false);
  const [fileToEdit, setFileToEdit] = useState(null);
  const [isGroupModalOpen, setIsGroupModalOpen] = useState(false);
  const [groupToEdit, setGroupToEdit] = useState(null);
  const [reloadTemplates, setReloadTemplates] = useState(false);

  const [removePopupVisible, setRemovePopupVisible] = useState(false);
  const [removePopupMessage, setRemovePopupMessage] = useState('');
  const [removePopupOnConfirm, setRemovePopupOnConfirm] = useState(() => {});
  const [isLoading, setIsLoading] = useState(false);
  const { showNotification } = useNotification();

  const handleReloadTemplates = () => {
    setReloadTemplates(true);
  };

  const transformFileData = (file, groups) => {
    const groupInfos = file.groups.map(
      (groupId) =>
        groups.find((g) => g.id === groupId) || {
          id: groupId,
          name: 'Groupe inconnu',
        }
    );
    return {
      ...file,
      groups: groupInfos,
    };
  };

  useEffect(() => {
    if (selectedEstablishmentId) {
      Promise.all([
        fetchRegistrationSchoolFileMasters(),
        fetchRegistrationFileGroups(selectedEstablishmentId),
        fetchRegistrationSchoolFileTemplates(),
        fetchRegistrationParentFileMasters(),
      ])
        .then(
          ([
            dataSchoolFileMasters,
            groupsData,
            dataSchoolFileTemplates,
            dataParentFileMasters,
          ]) => {
            setGroups(groupsData);
            setSchoolFileTemplates(dataSchoolFileTemplates);
            setParentFileMasters(dataParentFileMasters);
            // Transformer chaque fichier pour inclure les informations complètes du groupe
            const transformedFiles = dataSchoolFileMasters.map((file) =>
              transformFileData(file, groupsData)
            );
            setSchoolFileMasters(transformedFiles);
          }
        )
        .catch((err) => {
          logger.debug(err.message);
        })
        .finally(() => {
          setReloadTemplates(false);
        });
    }
  }, [reloadTemplates, selectedEstablishmentId]);

  const deleteTemplateMaster = (templateMaster) => {
    setRemovePopupVisible(true);
    setRemovePopupMessage(
      `Attentions ! \nVous êtes sur le point de supprimer le document "${templateMaster.name}".\nÊtes-vous sûr(e) de vouloir poursuivre l'opération ?`
    );
    setRemovePopupOnConfirm(() => () => {
      setIsLoading(true);
      // Supprimer les clones associés via l'API DocuSeal
      const removeClonesPromises = [
        ...schoolFileTemplates
          .filter((template) => template.master === templateMaster.id)
          .map((template) =>
            removeTemplate(template.id, selectedEstablishmentId, apiDocuseal)
          ),
        removeTemplate(templateMaster.id, selectedEstablishmentId, apiDocuseal),
      ];

      // Attendre que toutes les suppressions dans DocuSeal soient terminées
      Promise.all(removeClonesPromises)
        .then((responses) => {
          const allSuccessful = responses.every((response) => response && response.id);
          if (allSuccessful) {
            logger.debug('Master et clones supprimés avec succès de DocuSeal.');

            // Supprimer le template master de la base de données
            deleteRegistrationSchoolFileMaster(templateMaster.id, csrfToken)
              .then((response) => {
                if (response.ok) {
                  setSchoolFileMasters(
                    schoolFileMasters.filter(
                      (fichier) => fichier.id !== templateMaster.id
                    )
                  );
                  showNotification(
                    `Le document "${templateMaster.name}" a été correctement supprimé.`,
                    'success',
                    'Succès'
                  );

                  setRemovePopupVisible(false);
                  setIsLoading(false);
                } else {
                  showNotification(
                    `Erreur lors de la suppression du document "${templateMaster.name}".`,
                    'error',
                    'Erreur'
                  );
                  setRemovePopupVisible(false);
                  setIsLoading(false);
                }
              })
              .catch((error) => {
                logger.error('Error deleting file from database:', error);
                showNotification(
                  `Erreur lors de la suppression du document "${templateMaster.name}".`,
                  'error',
                  'Erreur'
                );
                setRemovePopupVisible(false);
                setIsLoading(false);
              });
          } else {
            showNotification(
              `Erreur lors de la suppression du document "${templateMaster.name}".`,
              'error',
              'Erreur'
            );
            setRemovePopupVisible(false);
            setIsLoading(false);
          }
        })
        .catch((error) => {
          logger.error('Error removing template from DocuSeal:', error);
          showNotification(
            `Erreur lors de la suppression du document "${templateMaster.name}".`,
            'error',
            'Erreur'
          );
          setRemovePopupVisible(false);
          setIsLoading(false);
        });
    });
  };

  const editTemplateMaster = (file) => {
    setIsEditing(true);
    setFileToEdit(file);
    setIsModalOpen(true);
  };

  const handleCreateTemplateMaster = ({ name, group_ids, id, is_required }) => {
    const data = {
      name: name,
      id: id,
      groups: group_ids,
      is_required: is_required,
    };
    logger.debug(data);

    createRegistrationSchoolFileMaster(data, csrfToken)
      .then((data) => {
        // Transformer le nouveau fichier avec les informations du groupe
        const transformedFile = transformFileData(data, groups);
        setSchoolFileMasters((prevFiles) => [...prevFiles, transformedFile]);
        setIsModalOpen(false);
      })
      .catch((error) => {
        logger.error('Error uploading file:', error);
      });
  };

  const handleEditTemplateMaster = ({ name, group_ids, id, is_required }) => {
    const data = {
      name: name,
      id: id,
      groups: group_ids,
      is_required: is_required,
    };
    logger.debug(data);

    editRegistrationSchoolFileMaster(id, data, csrfToken)
      .then((data) => {
        // Transformer le fichier mis à jour avec les informations du groupe
        const transformedFile = transformFileData(data, groups);
        setSchoolFileMasters((prevFichiers) =>
          prevFichiers.map((f) => (f.id === id ? transformedFile : f))
        );
        setIsModalOpen(false);
      })
      .catch((error) => {
        logger.error('Error editing file:', error);
        showNotification(
          'Erreur lors de la modification du fichier',
          'error',
          'Erreur'
        );
      });
  };

  const handleGroupSubmit = (groupData) => {
    if (groupToEdit) {
      editRegistrationFileGroup(groupToEdit.id, groupData, csrfToken)
        .then((updatedGroup) => {
          setGroups(
            groups.map((group) =>
              group.id === groupToEdit.id ? updatedGroup : group
            )
          );
          setGroupToEdit(null);
          setIsGroupModalOpen(false);
        })
        .catch((error) => {
          logger.error('Error handling group:', error);
          showNotification(
            "Erreur lors de l'opération sur le groupe",
            'error',
            'Erreur'
          );
        });
    } else {
      // Ajouter l'établissement sélectionné lors de la création d'un nouveau groupe
      const newGroupData = {
        ...groupData,
        establishment: selectedEstablishmentId,
      };

      createRegistrationFileGroup(newGroupData, csrfToken)
        .then((newGroup) => {
          setGroups([...groups, newGroup]);
          setIsGroupModalOpen(false);
        })
        .catch((error) => {
          logger.error('Error handling group:', error);
          showNotification(
            "Erreur lors de l'opération sur le groupe",
            'error',
            'Erreur'
          );
        });
    }
  };

  const handleGroupEdit = (group) => {
    setGroupToEdit(group);
    setIsGroupModalOpen(true);
  };

  const handleGroupDelete = (groupId) => {
    // Vérifier si des schoolFileMasters utilisent ce groupe
    const filesInGroup = schoolFileMasters.filter(
      (file) => file.group && file.group.id === groupId
    );
    if (filesInGroup.length > 0) {
      showNotification(
        "Impossible de supprimer ce groupe car il contient déjà des formulaires. Veuillez d'abord retirer tous les formules de ce groupe.",
        'error',
        'Erreur'
      );
      return;
    }

    setRemovePopupVisible(true);
    setRemovePopupMessage(
      'Attentions ! \nÊtes-vous sûr de vouloir supprimer ce groupe ?'
    );
    setRemovePopupOnConfirm(() => () => {
      setIsLoading(true);
      deleteRegistrationFileGroup(groupId, csrfToken)
        .then((response) => {
          if (response.status === 409) {
            throw new Error('Ce groupe est lié à des inscriptions existantes.');
          }
          if (!response.ok) {
            throw new Error('Erreur lors de la suppression du groupe.');
          }
          setGroups(groups.filter((group) => group.id !== groupId));
          setRemovePopupVisible(false);
          setIsLoading(false);
          showNotification('Groupe supprimé avec succès.', 'success', 'Succès');
        })
        .catch((error) => {
          logger.error('Error deleting group:', error);
          setRemovePopupVisible(false);
          setIsLoading(false);
          showNotification(
            error.message ||
              "Erreur lors de la suppression du groupe. Vérifiez qu'aucune inscription n'utilise ce groupe.",
            'error',
            'Erreur'
          );
        });
    });
  };

  const handleCreate = (newParentFile) => {
    return createRegistrationParentFileMaster(newParentFile, csrfToken)
      .then((response) => {
        const createdFile = response;
        // Ajouter le nouveau fichier parent à la liste existante
        setParentFileMasters((prevFiles) => [...prevFiles, createdFile]);
        logger.debug('Document parent créé avec succès:', createdFile);
        return createdFile;
      })
      .catch((error) => {
        logger.error('Erreur lors de la création du document parent:', error);
        showNotification(
          'Une erreur est survenue lors de la création du document parent.',
          'error',
          'Erreur'
        );
        throw error;
      });
  };

  const handleEdit = (id, updatedFile) => {
    return editRegistrationParentFileMaster(id, updatedFile, csrfToken)
      .then((response) => {
        const modifiedFile = response.data; // Extraire les données mises à jour
        // Mettre à jour la liste des fichiers parents
        setParentFileMasters((prevFiles) =>
          prevFiles.map((file) => (file.id === id ? modifiedFile : file))
        );
        logger.debug('Document parent mis à jour avec succès:', modifiedFile);
        return modifiedFile; // Retourner le fichier mis à jour
      })
      .catch((error) => {
        logger.error(
          'Erreur lors de la modification du document parent:',
          error
        );
        showNotification(
          'Une erreur est survenue lors de la modification du document parent.',
          'error',
          'Erreur'
        );
        throw error;
      });
  };

  const handleDelete = (id) => {
    return deleteRegistrationParentFileMaster(id, csrfToken)
      .then(() => {
        // Mettre à jour la liste des fichiers parents en supprimant l'élément correspondant
        setParentFileMasters((prevFiles) =>
          prevFiles.filter((file) => file.id !== id)
        );
        logger.debug('Document parent supprimé avec succès:', id);
      })
      .catch((error) => {
        logger.error('Erreur lors de la suppression du fichier parent:', error);
      });
  };

  const filteredFiles = schoolFileMasters.filter((file) => {
    if (!selectedGroup) return true;
    return (
      file.groups &&
      file.groups.some((group) => group.id === parseInt(selectedGroup))
    );
  });

  const columnsFiles = [
    { name: 'Nom du formulaire', transform: (row) => row.name },
    {
      name: "Dossiers d'inscription",
      transform: (row) =>
        row.groups && row.groups.length > 0
          ? row.groups.map((group) => group.name).join(', ')
          : 'Aucun',
    },
    {
      name: 'Actions',
      transform: (row) => (
        <div className="flex items-center justify-center gap-2">
          {row.file && (
            <a
              href={`${BASE_URL}${row.file}`}
              target="_blank"
              className="text-blue-500 hover:text-blue-700"
            >
              <Download className="w-5 h-5" />
            </a>
          )}
          <button
            onClick={() => editTemplateMaster(row)}
            className="text-blue-500 hover:text-blue-700"
          >
            <Edit3 className="w-5 h-5" />
          </button>
          <button
            onClick={() => deleteTemplateMaster(row)}
            className="text-red-500 hover:text-red-700"
          >
            <Trash2 className="w-5 h-5" />
          </button>
        </div>
      ),
    },
  ];

  const columnsGroups = [
    { name: 'Nom du dossier', transform: (row) => row.name },
    { name: 'Description', transform: (row) => row.description },
    {
      name: 'Actions',
      transform: (row) => (
        <div className="flex items-center justify-center gap-2">
          <button
            onClick={() => handleGroupEdit(row)}
            className="text-blue-500 hover:text-blue-700"
          >
            <Edit3 className="w-5 h-5" />
          </button>
          <button
            onClick={() => handleGroupDelete(row.id)}
            className="text-red-500 hover:text-red-700"
          >
            <Trash2 className="w-5 h-5" />
          </button>
        </div>
      ),
    },
  ];

  if (isLoading) {
    return <Loader />;
  }

  return (
    <div className="w-full">
      {/* Modal pour les fichiers */}
      <Modal
        isOpen={isModalOpen}
        setIsOpen={(isOpen) => {
          setIsModalOpen(isOpen);
          if (!isOpen) {
            setFileToEdit(null);
          }
        }}
        title={isEditing ? 'Modification du document' : 'Ajouter un document'}
        modalClassName="w-4/5 h-4/5"
      >
        <FileUploadDocuSeal
          handleCreateTemplateMaster={handleCreateTemplateMaster}
          handleEditTemplateMaster={handleEditTemplateMaster}
          fileToEdit={fileToEdit}
          onSuccess={handleReloadTemplates}
        />
      </Modal>

      {/* Modal pour les groupes */}
      <Modal
        isOpen={isGroupModalOpen}
        setIsOpen={setIsGroupModalOpen}
        title={
          groupToEdit ? 'Modifier le dossier' : "Création d'un nouveau dossier"
        }
      >
        <RegistrationFileGroupForm
          onSubmit={handleGroupSubmit}
          initialData={groupToEdit}
        />
      </Modal>

      {/* Section Groupes de fichiers */}
      <div className="mt-8 w-3/5">
        <SectionHeader
          icon={FolderPlus}
          title="Dossiers d'inscriptions"
          description="Gérez les dossiers d'inscription pour organiser vos documents."
          button={true}
          buttonOpeningModal={true}
          onClick={() => setIsGroupModalOpen(true)}
        />
        <Table
          data={groups}
          columns={columnsGroups}
          emptyMessage={
            <AlertMessage
              type="warning"
              title="Aucun dossier d'inscription enregistré"
              message="Veuillez procéder à la création d'un nouveau dossier d'inscription"
            />
          }
        />
      </div>

      {/* Section Fichiers */}
      <div className="mt-12 mb-4 w-3/5">
        <SectionHeader
          icon={Signature}
          title="Formulaires à remplir"
          description="Gérez les formulaires nécessitant une signature électronique."
          button={apiDocuseal}
          buttonOpeningModal={true}
          onClick={() => {
            setIsModalOpen(true);
            setIsEditing(false);
          }}
        />
        <div className="mb-4">
          <span
            className={`inline-flex items-center px-3 py-1 rounded-full text-sm font-semibold ${
              !apiDocuseal && 'bg-red-100 text-red-700 border border-red-300'
            }`}
          >
            {!apiDocuseal && (
              <AlertTriangle className="w-4 h-4 mr-2 text-red-500" />
            )}
            {!apiDocuseal && 'Clé API Docuseal manquante'}
          </span>
        </div>
        <Table
          data={filteredFiles}
          columns={columnsFiles}
          emptyMessage={
            <AlertMessage
              type="warning"
              title="Aucun formulaire enregistré"
              message="Veuillez procéder à la création d'un nouveau formulaire à signer"
            />
          }
        />
      </div>

      {/* Section Pièces à fournir */}
      <ParentFilesSection
        parentFiles={parentFiles}
        setParentFileMasters={setParentFileMasters}
        groups={groups}
        handleCreate={handleCreate}
        handleEdit={handleEdit}
        handleDelete={handleDelete}
      />
      <Popup
        isOpen={removePopupVisible}
        message={removePopupMessage}
        onConfirm={removePopupOnConfirm}
        onCancel={() => setRemovePopupVisible(false)}
      />
    </div>
  );
}
