import { useState, useEffect } from 'react';
import classService from '../services/serviceClasses';

const useClasses = () => {
    const [classes, setClasses] = useState([]);
    const [freeStudent, setStudentOption] = useState([]);
    const [studentSlug, setStudentSlug] = useState({});
    const [loading, setLoading] = useState(true);
    const [error, setError] = useState(null);

    const [selectedClass, setSelectedClass] = useState(null);
    const [formData, setFormData] = useState({
        className: '',
        capacity: '',
    });
    const [assignStudents, setAssignStudents] = useState([]);
    const [assignClass, setAssignClass] = useState('');

    const [show, setShow] = useState(false);
    const [showAssign, setShowAssign] = useState(false);

    const [showLoader, setShowLoader] = useState(false);
    const [loaderState, setLoaderState] = useState({ loading: false, successMessage: '', title: '', description: '', confirmAction: false });

    const resetForm = () =>{
        setFormData({
            className: '',
            capacity: '',
        });
    }

    const handleFormChange = (e) => {
        setFormData({ ...formData, [e.target.name]: e.target.value });
    };

    const assignStudentChange = (selectedOptions) => {
        setAssignStudents(selectedOptions);
    };
    const assignClassChange = (e) => {
        setAssignClass(e.target.value);
    };

    const handleShow = (data) => {
        setSelectedClass(data);
        setFormData({
            className: data?.NAME_CLASS || '',
            capacity: data?.TOTAL_STUDENT || '',
        });
        setShow(true);
    };
    const handleClose = () => {
        setShow(false); 
        setShowAssign(false);
        resetForm(); 
        setSelectedClass(null)
    };
    const handleShowAssign = () => setShowAssign(true);
    
    const handleCloseLoader = () => setShowLoader(false);
    const handleShowLoader = (title, description, loading = false, successMessage = '', confirmAction = false) => {
        setLoaderState({ title, description, loading, successMessage, confirmAction });
        setShowLoader(true);
    };

    const fetchDataStudent = async () => {
        setLoading(true);
        try {
            const studentArray = {};
            const studentForOption = [];
            const dataStudent = await classService.fetchDataFreeStudent();
            dataStudent.payload.map((s, index) => {
                studentArray[s.NISN] = s.NAME_USERS;
                studentForOption[index] = {value: s.NISN, label: `${s.NISN} - ${s.NAME_USERS}`}
            });
            setStudentSlug(studentArray);
            setStudentOption(studentForOption);
        } catch (err) {
            setError(err);
        } finally {
            setLoading(false);
        }
    };

    const createClass = async () => {
        const newClass ={
            NAME_CLASS: formData.className,
            TOTAL_STUDENT: formData.capacity,
        };
        
        handleShowLoader('Created', '', true)
        try {
            const createdClass = await classService.createData(newClass);
            setClasses((prevClasses) => [...prevClasses, createdClass.payload]);
            setLoaderState(prev => ({
                ...prev,
                loading: false,
                successMessage: 'Your new entry has been successfully created and saved.'
            }));
            resetForm();
        } catch (err) {
            setLoaderState(prev => ({
                ...prev,
                title: "ERROR",
                loading: false,
                successMessage: err.response.data.message
            }));
        }
    };

    const editClass = async () => {
        const id = selectedClass.ID_CLASS;
        const data = formData;
        const updateClassData ={
            NAME_CLASS: data.className,
            TOTAL_STUDENT: parseInt(data.capacity),
        };
        handleClose();
        handleShowLoader('Updated', '', true);
        try {
            const classData = await classService.updateData(id, updateClassData);
            setClasses((prevClasses) => 
                prevClasses.map((s) => (s.ID_CLASS === id ? classData.payload : s))
            );
            setLoaderState(prev => ({
                ...prev,
                loading: false,
                successMessage: 'Your data has been successfully updated.'
            }));
        } catch (err) {
            setLoaderState(prev => ({
                ...prev,
                title: "ERROR",
                loading: false,
                successMessage: err.response.data.message
            }));
        }
    };

    const deleteClass = async (id) => {
        handleShowLoader('Deleted', 'Are you sure you want to delete this class?', false, '', true);
        const confirmDelete = async () => {
            handleCloseLoader();
            handleShowLoader('Deleted', '', true);
            try {
                await classService.deleteData(id);
            } catch (err) {
                setError(err);
            }finally{
                setClasses((prevClasses) => prevClasses.filter((s) => s.ID_CLASS !== id));
                setLoaderState(prev => ({
                    ...prev,
                    loading: false,
                    successMessage: 'Your data has been successfully deleted.'
                }));
            }
        }
        setLoaderState(prev => ({ ...prev, handleConfirm: confirmDelete }));
    };

    const assignStudentToClass = async () => {
        handleClose();
        handleShowLoader('Updated', '', true)

        const selectedStudent = assignStudents.map((selectedData) => ({
            NAME_USERS: studentSlug[selectedData.value],
            NISN: selectedData.value
        }));

        const assignData = {
            NAME_CLASS: assignClass,
            STUDENTS: selectedStudent
        };

        try {
            await classService.studentToClass(assignData);
        } catch (err) {
            setError(err);
        }finally{
            fetchDataStudent();
            setLoaderState(prev => ({
                ...prev,
                loading: false,
                successMessage: 'Your data has been successfully updated.'
            }));
        }
    };

    const [search, setSearch] = useState("");
    const [sort, setSort] = useState("");
    const [page, setCurrentPage] = useState(1);
    const [limit, setLimit] = useState(7);
    const [totalPages, setTotalPages] = useState(0);
    const [totalData, setTotalData] = useState(null);
    
    const fetchData = async () => {
        setLoading(true);
        try {
            const data = await classService.fetchData(search, sort, page, limit);
            setTotalPages(data.payload.totalPages);
            setTotalData(data.payload.totalItems);
            setClasses(data.payload.classes);
        } catch (err) {
            setError(err);
        } finally {
            setLoading(false);
        }
    };

    const handleSerachChange = () => {
        fetchData();
        setCurrentPage(1);
    }

    const handlePageChange = (pages) => {
        setCurrentPage(pages);
    }

    const handleLimitsChange = (e) => {
        setLimit(e.target.value);
        setCurrentPage(1);
    }

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

    useEffect(() => {
        fetchData();
    }, [page, limit]);


    return { 
        classes, 
        freeStudent,
        loading, 
        error, 
        formData, 
        show,
        showAssign,
        showLoader,
        loaderState,
        createClass, 
        editClass, 
        deleteClass,
        assignStudentToClass,
        handleFormChange,
        assignStudentChange,
        assignClassChange,
        resetForm,
        handleShow,
        handleShowAssign,
        handleClose,
        handleCloseLoader,

        totalPages,
        totalData,
        setSearch,
        page, 
        handlePageChange,
        handleLimitsChange,
        handleSerachChange
    };
};

export default useClasses;
