import React, { useState, useEffect } from 'react';
import {
  Edit3,
  Trash2,
  GraduationCap,
  Check,
  X,
  Hand,
  Download,
  Plus,
} from 'lucide-react';
import Table from '@/components/Table';
import Popup from '@/components/Popup';
import ToggleSwitch from '@/components/Form/ToggleSwitch';
import SelectChoice from '@/components/Form/SelectChoice';
import { DndProvider, useDrop } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';
import InputText from '@/components/Form/InputText';
import SpecialityItem from '@/components/Structure/Configuration/SpecialityItem';
import TeacherItem from './TeacherItem';
import logger from '@/utils/logger';
import { useEstablishment } from '@/context/EstablishmentContext';
import SectionHeader from '@/components/SectionHeader';
import EmptyState from '@/components/EmptyState';
import { exportToCSV } from '@/utils/exportCSV';

const ItemTypes = {
  SPECIALITY: 'speciality',
};

const SpecialitiesDropZone = ({
  teacher,
  handleSpecialitiesChange,
  specialities,
  isEditing,
}) => {
  const [localSpecialities, setLocalSpecialities] = useState(
    teacher.specialities_details || []
  );

  useEffect(() => {}, [specialities]);

  useEffect(() => {
    setLocalSpecialities(teacher.specialities_details || []);
  }, [teacher.specialities_details]);

  useEffect(() => {
    handleSpecialitiesChange(
      localSpecialities.map((speciality) => speciality.id)
    );
  }, [localSpecialities]);

  const [{ isOver, canDrop }, drop] = useDrop({
    accept: ItemTypes.SPECIALITY,
    drop: (item) => {
      const specialityDetails = specialities.find(
        (speciality) => speciality.id === item.id
      );
      const exists = localSpecialities.some(
        (speciality) => speciality.id === item.id
      );
      if (!exists) {
        setLocalSpecialities((prevSpecialities) => {
          const updatedSpecialities = [
            ...prevSpecialities,
            {
              id: item.id,
              name: specialityDetails.name,
              color_code: specialityDetails.color_code,
            },
          ];
          return updatedSpecialities;
        });
      }
    },
    collect: (monitor) => ({
      isOver: !!monitor.isOver(),
      canDrop: !!monitor.canDrop(),
    }),
    canDrop: () => {
      return isEditing;
    },
  });

  const handleRemoveSpeciality = (id) => {
    setLocalSpecialities((prevSpecialities) => {
      const updatedSpecialities = prevSpecialities.filter(
        (speciality) => speciality.id !== id
      );
      return updatedSpecialities;
    });
  };

  return (
    <div
      ref={drop}
      className={`p-2 rounded-md flex flex-col items-center ${isEditing ? 'border-2 border-dashed border-blue-500 bg-blue-50' : ''} ${
        isOver && canDrop ? 'border-2 border-solid border-blue-300' : ''
      }`}
    >
      {isEditing && (
        <div className="mb-2 text-blue-500 font-semibold flex items-center space-x-2">
          <Hand className="w-5 h-5" /> {/* Ajoutez l'icône Hand */}
          <span>Déposez une spécialité ici</span>
        </div>
      )}
      {localSpecialities.map((speciality, index) => (
        <div
          key={`${speciality.id}-${index}`}
          className="flex items-center space-x-2 mb-2"
        >
          <SpecialityItem
            key={speciality.id}
            speciality={speciality}
            isDraggable={false}
          />
          {isEditing && (
            <button
              type="button"
              onClick={() => handleRemoveSpeciality(speciality.id)}
              className="text-red-500 hover:text-red-700"
            >
              <X className="w-4 h-4" />
            </button>
          )}
        </div>
      ))}
    </div>
  );
};

const TeachersSection = ({
  teachers,
  allTeachers,
  setTeachers,
  specialities,
  profiles,
  handleCreate,
  handleEdit,
  handleDelete,
}) => {
  const [editingTeacher, setEditingTeacher] = useState(null);
  const [newTeacher, setNewTeacher] = useState(null);
  const [formData, setFormData] = useState({});
  const [localErrors, setLocalErrors] = useState({});
  const [popupVisible, setPopupVisible] = useState(false);
  const [popupMessage, setPopupMessage] = useState('');

  const [removePopupVisible, setRemovePopupVisible] = useState(false);
  const [removePopupMessage, setRemovePopupMessage] = useState('');
  const [removePopupOnConfirm, setRemovePopupOnConfirm] = useState(() => {});
  const ITEMS_PER_PAGE = 10;
  const [currentPage, setCurrentPage] = useState(1);
  useEffect(() => {
    setCurrentPage(1);
  }, [teachers]);
  useEffect(() => {
    if (newTeacher) setCurrentPage(1);
  }, [newTeacher]);
  const totalPages = Math.ceil(teachers.length / ITEMS_PER_PAGE);
  const pagedTeachers = teachers.slice(
    (currentPage - 1) * ITEMS_PER_PAGE,
    currentPage * ITEMS_PER_PAGE
  );

  const { selectedEstablishmentId, profileRole } = useEstablishment();

  // --- UTILS ---

  // Retourne le profil existant pour un email
  const getUsedProfileForEmail = (email) => {
    // On cherche tous les profils dont l'email correspond
    const matchingProfiles = profiles.filter((p) => p.email === email);

    // On retourne le premier profil correspondant (ou undefined)
    const result =
      matchingProfiles.length > 0 ? matchingProfiles[0] : undefined;

    return result;
  };

  // Met à jour le formData et newTeacher si besoin
  const updateFormData = (data) => {
    setFormData((prev) => ({ ...prev, ...data }));
    if (newTeacher) setNewTeacher((prev) => ({ ...prev, ...data }));
  };

  // Récupération des messages d'erreur pour un champ donné
  const getError = (field) => {
    return localErrors?.[field]?.[0];
  };

  // --- HANDLERS ---

  const handleEmailChange = (e) => {
    const email = e.target.value;
    const existingProfile = getUsedProfileForEmail(email);

    if (existingProfile) {
      logger.info(
        `Adresse email déjà utilisée pour le profil ${existingProfile.id}`
      );
    }

    updateFormData({
      associated_profile_email: email,
      existingProfileId: existingProfile ? existingProfile.id : null,
    });
  };

  const handleAddTeacher = () => {
    setNewTeacher({
      id: Date.now(),
      last_name: '',
      first_name: '',
      associated_profile_email: '',
      specialities: [],
      role_type: 0,
    });
    setFormData({
      last_name: '',
      first_name: '',
      associated_profile_email: '',
      specialities: [],
      role_type: 0,
    });
  };

  // Export CSV
  const handleExportCSV = () => {
    const exportColumns = [
      { key: 'id', label: 'ID' },
      { key: 'last_name', label: 'Nom' },
      { key: 'first_name', label: 'Prénom' },
      { key: 'associated_profile_email', label: 'Email' },
      {
        key: 'specialities_details',
        label: 'Spécialités',
        transform: (value) =>
          value ? value.map((s) => s.name).join(', ') : '',
      },
      {
        key: 'role_type',
        label: 'Profil',
        transform: (value) => (value === 1 ? 'Administrateur' : 'Enseignant'),
      },
      { key: 'updated_date_formatted', label: 'Date de mise à jour' },
    ];
    const filename = `enseignants_${new Date().toISOString().split('T')[0]}`;
    exportToCSV(teachers, exportColumns, filename);
  };

  const handleRemoveTeacher = (id) => {
    logger.debug('[DELETE] Suppression teacher id:', id);
    return handleDelete(id)
      .then(() => {
        setTeachers((prevTeachers) =>
          prevTeachers.filter((teacher) => teacher.id !== id)
        );
        logger.debug('[DELETE] Teacher supprimé:', id);
      })
      .catch(logger.error);
  };

  const handleSaveNewTeacher = () => {
    if (
      formData.last_name &&
      formData.first_name &&
      formData.associated_profile_email
    ) {
      const data = {
        last_name: formData.last_name,
        first_name: formData.first_name,
        profile_role_data: {
          establishment: selectedEstablishmentId,
          role_type: formData.role_type || 0,
          is_active: true,
          ...(formData.existingProfileId
            ? { profile: formData.existingProfileId }
            : {
                profile_data: {
                  email: formData.associated_profile_email,
                  username: formData.associated_profile_email,
                  password: 'Provisoire01!',
                },
              }),
        },
        specialities: formData.specialities || [],
      };

      handleCreate(data)
        .then((createdTeacher) => {
          // Recherche du profile associé dans profiles
          let newProfileId = undefined;
          let foundProfile = undefined;
          if (
            createdTeacher &&
            createdTeacher.profile_role &&
            createdTeacher.profile
          ) {
            newProfileId = createdTeacher.profile;
            foundProfile = profiles.find((p) => p.id === newProfileId);
          }

          setTeachers([createdTeacher, ...teachers]);
          setNewTeacher(null);
          setLocalErrors({});
          setFormData((prev) => ({
            ...prev,
            existingProfileId: newProfileId,
          }));
        })
        .catch((error) => {
          logger.error('Error:', error.message);
          if (error.details) setLocalErrors(error.details);
        });
    } else {
      setPopupMessage('Tous les champs doivent être remplis et valides');
      setPopupVisible(true);
    }
  };

  const handleUpdateTeacher = (id, updatedData) => {
    if (
      updatedData.last_name &&
      updatedData.first_name &&
      updatedData.associated_profile_email
    ) {
      const profileRoleData = {
        id: updatedData.profile_role,
        establishment: selectedEstablishmentId,
        role_type: updatedData.role_type || 0,
        profile: updatedData.existingProfileId,
      };

      handleEdit(id, {
        last_name: updatedData.last_name,
        first_name: updatedData.first_name,
        profile_role_data: profileRoleData,
        specialities: updatedData.specialities || [],
      })
        .then((updatedTeacher) => {
          setTeachers((prevTeachers) =>
            prevTeachers.map((teacher) =>
              teacher.id === id ? { ...teacher, ...updatedTeacher } : teacher
            )
          );
          setEditingTeacher(null);
          setFormData({});
        })
        .catch((error) => {
          logger.error('Error:', error.message);
          if (error.details) setLocalErrors(error.details);
        });
    } else {
      setPopupMessage('Tous les champs doivent être remplis et valides');
      setPopupVisible(true);
    }
  };

  const handleChange = (e) => {
    const { name, value, type, checked } = e.target;
    let parsedValue = type === 'checkbox' ? (checked ? 1 : 0) : value;
    updateFormData({ [name]: parsedValue });
  };

  const handleSpecialitiesChange = (selectedSpecialities) => {
    updateFormData({ specialities: selectedSpecialities });
  };

  const handleEditTeacher = (teacher) => {
    setEditingTeacher(teacher.id);
    setFormData({
      ...teacher,
      associated_profile_email: teacher.associated_profile_email,
      role_type: teacher.role_type,
    });
  };

  const renderTeacherCell = (teacher, column) => {
    const isEditing = editingTeacher === teacher.id;
    const isCreating = newTeacher && newTeacher.id === teacher.id;
    const currentData = isEditing ? formData : newTeacher;

    if (isEditing || isCreating) {
      switch (column) {
        case 'NOM - PRENOM':
          return (
            <div className="flex justify-center space-x-2">
              <InputText
                name="last_name"
                value={currentData.last_name}
                onChange={handleChange}
                placeholder="Nom de l'enseignant"
                errorMsg={getError('last_name')}
              />
              <InputText
                name="first_name"
                value={currentData.first_name}
                onChange={handleChange}
                placeholder="Prénom de l'enseignant"
                errorMsg={getError('first_name')}
              />
            </div>
          );
        case 'EMAIL':
          return (
            <InputText
              name="associated_profile_email"
              type="email"
              value={currentData.associated_profile_email || ''}
              onChange={handleEmailChange}
              placeholder="Adresse email de l'enseignant"
              errorMsg={getError('email')}
              enable={!isEditing}
            />
          );
        case 'SPECIALITES':
          return (
            <SpecialitiesDropZone
              teacher={currentData}
              handleSpecialitiesChange={handleSpecialitiesChange}
              specialities={specialities}
              isEditing={isEditing || isCreating}
            />
          );
        case 'ADMINISTRATEUR':
          return (
            <div className="flex justify-center">
              <ToggleSwitch
                name="role_type"
                checked={currentData.role_type === 1}
                onChange={handleChange}
              />
            </div>
          );
        case 'ACTIONS':
          return (
            <div className="flex justify-center space-x-2">
              <button
                type="button"
                onClick={() =>
                  isEditing
                    ? handleUpdateTeacher(editingTeacher, formData)
                    : handleSaveNewTeacher()
                }
                className="text-primary hover:text-secondary"
              >
                <Check className="w-5 h-5" />
              </button>
              <button
                type="button"
                onClick={() =>
                  isEditing ? setEditingTeacher(null) : setNewTeacher(null)
                }
                className="text-red-500 hover:text-red-700"
              >
                <X className="w-5 h-5" />
              </button>
            </div>
          );
        default:
          return null;
      }
    } else {
      switch (column) {
        case 'NOM - PRENOM':
          return <TeacherItem key={teacher.id} teacher={teacher} />;
        case 'EMAIL':
          return teacher.associated_profile_email;
        case 'SPECIALITES':
          return (
            <div className="flex justify-center space-x-2 flex-wrap">
              {(teacher.specialities_details ?? []).map((speciality) => (
                <SpecialityItem
                  key={speciality.id}
                  speciality={speciality}
                  isDraggable={false}
                />
              ))}
            </div>
          );
        case 'ADMINISTRATEUR':
          if (teacher.associated_profile_email) {
            const badgeClass =
              teacher.role_type === 1
                ? 'bg-red-100 text-red-600'
                : 'bg-blue-100 text-blue-600';
            const label = teacher.role_type === 1 ? 'OUI' : 'NON';
            return (
              <div
                key={teacher.id}
                className="flex justify-center items-center space-x-2"
              >
                <span
                  className={`px-3 py-1 rounded-full font-bold ${badgeClass}`}
                >
                  {label}
                </span>
              </div>
            );
          } else {
            return <i>Non définie</i>;
          }
        case 'MISE A JOUR':
          return teacher.updated_date_formatted;
        case 'ACTIONS':
          return (
            <div className="flex justify-center space-x-2">
              <button
                type="button"
                onClick={() => handleEditTeacher(teacher)}
                className="text-blue-500 hover:text-blue-700"
              >
                <Edit3 className="w-5 h-5" />
              </button>
              <button
                type="button"
                onClick={() => {
                  setRemovePopupVisible(true);
                  setRemovePopupMessage(
                    "Attention ! \nVous êtes sur le point de supprimer l'enseignant " +
                      teacher.last_name +
                      ' ' +
                      teacher.first_name +
                      ".\nÊtes-vous sûr(e) de vouloir poursuivre l'opération ?"
                  );
                  setRemovePopupOnConfirm(() => () => {
                    handleRemoveTeacher(teacher.id)
                      .then((data) => {
                        logger.debug('Success:', data);
                        setPopupMessage(
                          "L'enseignant " +
                            teacher.last_name +
                            ' ' +
                            teacher.first_name +
                            ' a été correctement supprimé'
                        );
                        setPopupVisible(true);
                        setRemovePopupVisible(false);
                      })
                      .catch((error) => {
                        logger.error('Error archiving data:', error);
                        setPopupMessage(
                          "Erreur lors de la suppression de l'enseignant " +
                            teacher.last_name +
                            ' ' +
                            teacher.first_name
                        );
                        setPopupVisible(true);
                        setRemovePopupVisible(false);
                      });
                  });
                }}
                className="text-red-500 hover:text-red-700"
              >
                <Trash2 className="w-5 h-5" />
              </button>
            </div>
          );
        default:
          return null;
      }
    }
  };

  const columns = [
    { name: 'NOM - PRENOM', label: 'Nom et prénom' },
    { name: 'EMAIL', label: 'Email' },
    { name: 'SPECIALITES', label: 'Spécialités' },
    { name: 'ADMINISTRATEUR', label: 'Profil' },
    { name: 'MISE A JOUR', label: 'Mise à jour' },
    ...(profileRole !== 0 ? [{ name: 'ACTIONS', label: 'Actions' }] : []),
  ];

  return (
    <DndProvider backend={HTML5Backend}>
      <div className="space-y-4">
        {(pagedTeachers.length > 0 || newTeacher) && (
          <SectionHeader
            icon={GraduationCap}
            title="Liste des enseignants.es"
            description="Gérez les enseignants.es de votre école"
            button={profileRole !== 0}
            onClick={handleAddTeacher}
            secondaryButton={
              <button
                onClick={handleExportCSV}
                className="flex items-center gap-2 px-4 py-2 text-sm font-medium text-secondary bg-primary/10 rounded-lg hover:bg-primary/20 transition-colors"
                title="Exporter en CSV"
              >
                <Download className="w-4 h-4" />
                Exporter
              </button>
            }
          />
        )}
        <Table
          data={newTeacher ? [newTeacher, ...pagedTeachers] : pagedTeachers}
          columns={columns}
          renderCell={renderTeacherCell}
          emptyMessage={
            <EmptyState
              icon={GraduationCap}
              title="Aucun enseignant enregistré"
              description="Ajoutez un enseignant pour lui attribuer des spécialités et le rattacher aux classes."
              actionLabel={
                profileRole !== 0 ? 'Ajouter un enseignant' : undefined
              }
              onAction={profileRole !== 0 ? handleAddTeacher : undefined}
              actionIcon={profileRole !== 0 ? Plus : undefined}
            />
          }
          itemsPerPage={ITEMS_PER_PAGE}
          currentPage={currentPage}
          totalPages={totalPages}
          onPageChange={setCurrentPage}
        />
        <Popup
          isOpen={popupVisible}
          message={popupMessage}
          onConfirm={() => setPopupVisible(false)}
          onCancel={() => setPopupVisible(false)}
          uniqueConfirmButton={true}
        />
        <Popup
          isOpen={removePopupVisible}
          message={removePopupMessage}
          onConfirm={removePopupOnConfirm}
          onCancel={() => setRemovePopupVisible(false)}
        />
      </div>
    </DndProvider>
  );
};

export default TeachersSection;
