import React, { useCallback, useRef, useState } from 'react';
import Image from 'next/image';
import clsx from 'clsx';
import { FaFileUpload, FaCheckCircle, FaLock, FaTimes } from 'react-icons/fa';
import { capitalize } from 'lodash';
import { Module } from '@/interfaces';
import { toast } from 'react-toastify';
import useExamEditorStore from '@/stores/examEditor';
import { LevelPart, ListeningPart, ReadingPart } from '@/interfaces/exam';
import { defaultSectionSettings } from '@/stores/examEditor/defaults';

const WordUploader: React.FC<{ module: Module, setNumberOfLevelParts: React.Dispatch<React.SetStateAction<number>> }> = ({ module, setNumberOfLevelParts }) => {
    const { currentModule, dispatch } = useExamEditorStore();
    const {sectionLabels} = useExamEditorStore(state => state.modules[currentModule]);

    const examInputRef = useRef<HTMLInputElement>(null);
    const solutionsInputRef = useRef<HTMLInputElement>(null);
    const [showUploaders, setShowUploaders] = useState(false);
    const [examFile, setExamFile] = useState<File | null>(null);
    const [solutionsFile, setSolutionsFile] = useState<File | null>(null);

    const handleExamChange = (event: React.ChangeEvent<HTMLInputElement>) => {
        const file = event.target.files?.[0];
        if (file) {
            if (file.type === 'application/msword' ||
                file.type === 'application/vnd.openxmlformats-officedocument.wordprocessingml.document') {
                setExamFile(file);
            }
        }
    };

    const handleSolutionsChange = (event: React.ChangeEvent<HTMLInputElement>) => {
        const file = event.target.files?.[0];
        if (file) {
            if (file.type === 'application/msword' ||
                file.type === 'application/vnd.openxmlformats-officedocument.wordprocessingml.document') {
                setSolutionsFile(file);
            }
        }
    };

    const handleImport = useCallback(async () => {
        try {
            if (!examFile) {
                toast.error('Exam file is required');
                return;
            }

            dispatch({ type: "UPDATE_MODULE", payload: { updates: { importing: true }, module } })

            const formData = new FormData();
            formData.append('exercises', examFile);
            if (solutionsFile) {
                formData.append('solutions', solutionsFile);
            }

            const response = await fetch(`/api/exam/${module}/import/`, {
                method: 'POST',
                body: formData,
            });

            if (!response.ok) {
                toast.error(`An unknown error has occured while import ${module} exam!`);
                return;
            }

            const data = await response.json();

            toast.success(`${capitalize(module)} exam imported successfully!`);

            setExamFile(null);
            setSolutionsFile(null);
            setShowUploaders(false);

            const newSectionsStates = data.parts.map(
                (part: ReadingPart | ListeningPart | LevelPart, index: number) => defaultSectionSettings(module, index + 1, part)
            );

            if (module === "level") {
                // default is 1
                const newLabelCount = data.parts.length - 2;
                setNumberOfLevelParts(newLabelCount);

                const newLabels = Array.from({ length: newLabelCount }, (_, index) => ({
                    id: index + 2,
                    label: `Part ${index + 2}`
                }));

                dispatch({type: "UPDATE_MODULE", payload: { updates: { sectionLabels: [...sectionLabels, ...newLabels] }}})
            }
            
            dispatch({
                type: "UPDATE_MODULE", payload: {
                    updates: {
                        sections: newSectionsStates,
                        minTimer: data.minTimer,
                        importModule: false,
                        importing: false,
                    },
                    module
                }
            });
        } catch (error) {
            toast.error(`Make sure you've imported a valid word document (.docx)!`);
        } finally {
            dispatch({ type: "UPDATE_MODULE", payload: { updates: { importing: false }, module } })
        }
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [
        examFile,
        solutionsFile,
        dispatch,
        currentModule
    ]);

    return (
        <>
            {!showUploaders ? (
                <div
                    onClick={() => setShowUploaders(true)}
                    className="flex flex-col items-center gap-6 h-full justify-center p-8 border-2 border-blue-200 rounded-xl
                     bg-gradient-to-b from-blue-50 to-blue-100
                     hover:from-blue-100 hover:to-blue-200
                     cursor-pointer transition-all duration-300
                     shadow-sm hover:shadow-md group"
                >
                    <div className="transform group-hover:scale-105 transition-transform duration-300">
                        <Image
                            src="/microsoft-word-icon.png"
                            width={200}
                            height={100}
                            alt="Upload Word"
                            className="drop-shadow-md"
                        />
                    </div>
                    <span className="text-lg font-bold text-stone-600 group-hover:text-stone-800 transition-colors duration-300">
                        Upload {capitalize(module)} Exam
                    </span>
                </div>
            ) : (
                <div className="flex flex-col h-full gap-4 p-6 justify-between border-2 border-blue-200 rounded-xl bg-white shadow-md">
                    <div className='flex flex-col flex-1 justify-center gap-8'>
                        <div
                            onClick={() => examInputRef.current?.click()}
                            className={clsx(
                                "relative p-6 border-2 border-dashed rounded-lg cursor-pointer transition-all duration-300",
                                examFile ? "border-green-300 bg-green-50" : "border-gray-300 hover:border-blue-400 hover:bg-blue-50"
                            )}
                        >
                            <div className="flex items-center gap-3">
                                <FaFileUpload className={clsx(
                                    "w-8 h-8",
                                    examFile ? "text-green-500" : "text-gray-400"
                                )} />
                                <div className="flex-grow">
                                    <h3 className="font-semibold text-gray-700">Exam Document</h3>
                                    <p className="text-sm text-gray-500">Required</p>
                                </div>
                                {examFile && (
                                    <div className="flex items-center gap-2">
                                        <FaCheckCircle className="w-6 h-6 text-green-500" />
                                        <button
                                            onClick={(e) => {
                                                e.stopPropagation();
                                                setExamFile(null);
                                            }}
                                            className="p-1.5 hover:bg-green-100 rounded-full transition-colors duration-200"
                                        >
                                            <FaTimes className="w-4 h-4 text-green-600" />
                                        </button>
                                    </div>
                                )}
                            </div>
                            {examFile && (
                                <div className="mt-2 text-sm text-green-600 font-medium">
                                    {examFile.name}
                                </div>
                            )}
                            <input
                                type="file"
                                ref={examInputRef}
                                onChange={handleExamChange}
                                accept=".doc,.docx"
                                className="hidden"
                            />
                        </div>

                        <div
                            onClick={() => solutionsInputRef.current?.click()}
                            className={clsx(
                                "relative p-6 border-2 border-dashed rounded-lg cursor-pointer transition-all duration-300",
                                solutionsFile ? "border-green-300 bg-green-50" : "border-gray-300 hover:border-blue-400 hover:bg-blue-50"
                            )}
                        >
                            <div className="flex items-center gap-3">
                                <FaFileUpload className={clsx(
                                    "w-8 h-8",
                                    solutionsFile ? "text-green-500" : "text-gray-400"
                                )} />
                                <div className="flex-grow">
                                    <h3 className="font-semibold text-gray-700">Solutions Document</h3>
                                    <p className="text-sm text-gray-500">Optional</p>
                                </div>
                                {solutionsFile ? (
                                    <div className="flex items-center gap-2">
                                        <FaCheckCircle className="w-6 h-6 text-green-500" />
                                        <button
                                            onClick={(e) => {
                                                e.stopPropagation();
                                                setSolutionsFile(null);
                                            }}
                                            className="p-1.5 hover:bg-green-100 rounded-full transition-colors duration-200"
                                        >
                                            <FaTimes className="w-4 h-4 text-green-600" />
                                        </button>
                                    </div>
                                ) : (
                                    <span className="text-xs text-gray-400 font-medium px-2 py-1 bg-gray-100 rounded">
                                        OPTIONAL
                                    </span>
                                )}
                            </div>
                            {solutionsFile && (
                                <div className="mt-2 text-sm text-green-600 font-medium">
                                    {solutionsFile.name}
                                </div>
                            )}
                            <input
                                type="file"
                                ref={solutionsInputRef}
                                onChange={handleSolutionsChange}
                                accept=".doc,.docx"
                                className="hidden"
                            />
                        </div>
                    </div>

                    <div className="flex gap-4">
                        <button
                            onClick={() => setShowUploaders(false)}
                            className={
                                clsx("px-6 py-2.5 text-sm font-semibold text-gray-700 bg-white border-2 border-gray-200",
                                    "rounded-lg hover:bg-gray-50 hover:border-gray-300",
                                    "transition-all duration-300 min-w-[120px]",
                                    "focus:outline-none focus:ring-2 focus:ring-gray-200 focus:ring-offset-2",
                                    "active:scale-95")}
                        >
                            <span className="flex items-center justify-center gap-2">
                                <FaTimes className="w-4 h-4" />
                                Cancel
                            </span>
                        </button>

                        <button
                            onClick={handleImport}
                            disabled={!examFile}
                            className={clsx(
                                "flex-grow px-6 py-2.5 text-sm font-semibold rounded-lg",
                                "transition-all duration-300 min-w-[120px]",
                                "focus:outline-none focus:ring-2 focus:ring-offset-2",
                                "flex items-center justify-center gap-2",
                                examFile
                                    ? "bg-gradient-to-r from-blue-500 to-blue-600 text-white hover:from-blue-600 hover:to-blue-700 active:scale-95 focus:ring-blue-500"
                                    : "bg-gradient-to-r from-gray-100 to-gray-200 text-gray-400 cursor-not-allowed border-2 border-gray-200"
                            )}
                        >
                            {examFile ? (
                                <>
                                    <FaFileUpload className="w-4 h-4" />
                                    Import Files
                                </>
                            ) : (
                                <>
                                    <FaLock className="w-4 h-4" />
                                    Upload Exam First
                                </>
                            )}
                        </button>
                    </div>
                </div>
            )}
        </>
    );
};

export default WordUploader;
