import React, { useState, useEffect } from 'react';
import { Plus, Download, Edit3, Trash2, FolderPlus, Signature } from 'lucide-react';
import Modal from '@/components/Modal';
import Table from '@/components/Table';
import FileUpload from '@/components/Structure/Files/FileUpload';
import { BASE_URL } from '@/utils/Url';
import {
  fetchRegistrationFileGroups,
  createRegistrationFileGroup,
  deleteRegistrationFileGroup,
  editRegistrationFileGroup,
  fetchRegistrationTemplateMaster,
  createRegistrationTemplateMaster,
  editRegistrationTemplateMaster,
  deleteRegistrationTemplateMaster,
  fetchRegistrationTemplates
} from '@/app/actions/registerFileGroupAction';
import RegistrationFileGroupForm from '@/components/Structure/Files/RegistrationFileGroupForm';
import logger from '@/utils/logger';

export default function FilesGroupsManagement({ csrfToken, selectedEstablishmentId }) {
  const [templateMasters, setTemplateMasters] = useState([]);
  const [templates, setTemplates] = 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 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([
        fetchRegistrationTemplateMaster(),
        fetchRegistrationFileGroups(selectedEstablishmentId),
        fetchRegistrationTemplates()
      ]).then(([filesTemplateMasters, groupsData, filesTemplates]) => {
        setGroups(groupsData);
        setTemplates(filesTemplates);
        // Transformer chaque fichier pour inclure les informations complètes du groupe
        const transformedFiles = filesTemplateMasters.map(file => transformFileData(file, groupsData));
        setTemplateMasters(transformedFiles);
      }).catch(err => {
        console.log(err.message);
      }).finally(() => {
        setReloadTemplates(false);
      });
    }
  }, [reloadTemplates, selectedEstablishmentId]);

  const deleteTemplateMaster = (templateMaster) => {
    // Supprimer les clones associés via l'API DocuSeal
    const removeClonesPromises = templates
      .filter(template => template.master === templateMaster.id)
      .map(template => removeTemplate(template.id));

    // Ajouter la suppression du master à la liste des promesses
    removeClonesPromises.push(removeTemplate(templateMaster.id));

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

          // Supprimer le template master de la base de données
          deleteRegistrationTemplateMaster(templateMaster.id, csrfToken)
            .then(response => {
              if (response.ok) {
                setTemplateMasters(templateMasters.filter(fichier => fichier.id !== templateMaster.id));
                alert('Fichier supprimé avec succès.');
              } else {
                alert('Erreur lors de la suppression du fichier dans la base de données.');
              }
            })
            .catch(error => {
              console.error('Error deleting file from database:', error);
              alert('Erreur lors de la suppression du fichier dans la base de données.');
            });
        } else {
          alert('Erreur lors de la suppression du master ou des clones dans DocuSeal.');
        }
      })
      .catch(error => {
        console.error('Error removing template from DocuSeal:', error);
        alert('Erreur lors de la suppression du master ou des clones dans DocuSeal.');
      });
  };

  const removeTemplate = (templateId) => {
    return fetch('/api/docuseal/removeTemplate/', {
      method: 'DELETE',
      headers: {
        'Content-Type': 'application/json',
        'X-CSRFToken': csrfToken
      },
      body: JSON.stringify({
        templateId
      })
    })
    .then(response => {
      if (!response.ok) {
        return response.json().then(err => { throw new Error(err.message); });
      }
      return response;
    })
    .catch(error => {
      console.error('Error removing template:', error);
      throw error;
    });
  };

  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);
    
    createRegistrationTemplateMaster(data, csrfToken)
    .then(data => {
      // Transformer le nouveau fichier avec les informations du groupe
      const transformedFile = transformFileData(data, groups);
      setTemplateMasters(prevFiles => [...prevFiles, transformedFile]);
      setIsModalOpen(false);
    })
    .catch(error => {
      console.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);

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

  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 => {
          console.error('Error handling group:', error);
          alert('Erreur lors de l\'opération sur le groupe');
        });
    } else {
      createRegistrationFileGroup(groupData, csrfToken)
        .then(newGroup => {
          setGroups([...groups, newGroup]);
          setIsGroupModalOpen(false);
        })
        .catch(error => {
          console.error('Error handling group:', error);
          alert('Erreur lors de l\'opération sur le groupe');
        });
    }
  };

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

  const handleGroupDelete = (groupId) => {
    // Vérifier si des templateMasters utilisent ce groupe
    const filesInGroup = templateMasters.filter(file => file.group && file.group.id === groupId);
    if (filesInGroup.length > 0) {
      alert('Impossible de supprimer ce groupe car il contient des templateMasters. Veuillez d\'abord retirer tous les templateMasters de ce groupe.');
      return;
    }

    if (window.confirm('Êtes-vous sûr de vouloir supprimer ce groupe ?')) {
      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));
          alert('Groupe supprimé avec succès.');
        })
        .catch(error => {
          console.error('Error deleting group:', error);
          alert(error.message || 'Erreur lors de la suppression du groupe. Vérifiez qu\'aucune inscription n\'utilise ce groupe.');
        });
    }
  };

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

  const columnsFiles = [
    { name: 'Nom du fichier', transform: (row) => row.name },
    { name: 'Groupes', 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 groupe', 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>
    )}
  ];

  return (
    <div>
      <Modal
        isOpen={isModalOpen}
        setIsOpen={(isOpen) => {
          setIsModalOpen(isOpen);
          if (!isOpen) {
            setFileToEdit(null);
          }
        }}
        title={isEditing ? 'Modification du document' : 'Ajouter un document'}
        ContentComponent={() => (
          <FileUpload
            handleCreateTemplateMaster={handleCreateTemplateMaster}
            handleEditTemplateMaster={handleEditTemplateMaster}
            fileToEdit={fileToEdit}
            onSuccess={handleReloadTemplates}
          />
        )}
        modalClassName='w-4/5 h-4/5'
      />
      <Modal
        isOpen={isGroupModalOpen}
        setIsOpen={setIsGroupModalOpen}
        title={groupToEdit ? "Modifier le groupe" : "Ajouter un groupe de templateMasters"}
        ContentComponent={() => (
          <RegistrationFileGroupForm
            onSubmit={handleGroupSubmit}
            initialData={groupToEdit}
          />
        )}
      />
      <div className="mt-8 mb-4">
        <div className="flex justify-between items-center mb-4">
          <h2 className="text-xl font-bold">Groupes de fichiers</h2>
          <button
            onClick={() => setIsGroupModalOpen(true)}
            className="flex items-center bg-blue-600 text-white p-2 rounded-full shadow hover:bg-blue-900 transition duration-200"
          >
            <FolderPlus className="w-5 h-5" />
          </button>
        </div>
        <Table
          data={groups}
          columns={columnsGroups}
          itemsPerPage={5}
          currentPage={1}
          totalPages={Math.ceil(groups.length / 5)}
        />
      </div>
      {groups.length > 0 && (
        <div className="mt-8">
          <div className="flex justify-between items-center mb-4">
            <h2 className="text-xl font-bold">Fichiers</h2>
            <div className="flex items-center gap-4">
              <select
                className="border rounded p-2"
                value={selectedGroup || ''}
                onChange={(e) => setSelectedGroup(e.target.value)}
              >
                <option value="">Tous les groupes</option>
                {groups.map(group => (
                  <option key={group.id} value={group.id}>{group.name}</option>
                ))}
              </select>
              <button
                onClick={() => { setIsModalOpen(true); setIsEditing(false); }}
                className="flex items-center bg-emerald-600 text-white p-2 rounded-full shadow hover:bg-emerald-900 transition duration-200"
              >
                <Plus className="w-5 h-5" />
              </button>
            </div>
          </div>
          <Table
            data={filteredFiles}
            columns={columnsFiles}
            itemsPerPage={10}
            currentPage={1}
            totalPages={Math.ceil(filteredFiles.length / 10)}
          />
        </div>
      )}
    </div>
  );
}
