import { FC, useEffect, useState } from 'react';
import { Modal } from '../../../components/modal/Modal';
import { PrimaryButton } from '../../../components/button/PrimaryButton';
import { SecondaryButton } from '../../../components/button/SecondaryButton';
import { Input } from '../../../components/input/Input';
import { useAppDispatch, useAppSelector } from '../../../redux/hooks';
import {
    setMissionsStatus,
    uploadMission,
} from '../../../redux/slices/missions';
import { toastSuccess } from '../../../lib/toastNotification';
import { cn } from '../../../lib/cn';
import { Link } from 'react-router-dom';
import { NumberInput } from '../../../components/input/NumberInput';
import { DropDownList, DropDownListItem } from '../../../components/input/DropDownList';

interface ModalCreateProps {
    active: boolean;
    setActive: (value: boolean) => void;
}

const ModalCreate: FC<ModalCreateProps> = ({ active, setActive }) => {
    type TagsMode = 'fromArchive' | 'none' | 'custom';
    const [difficulty, setDifficulty] = useState<number>(1);
    const [file, setFile] = useState<File | null>(null);
    const [tagInput, setTagInput] = useState<string>('');
    const [tags, setTags] = useState<string[]>([]);
    const [tagsMode, setTagsMode] = useState<TagsMode>('fromArchive');

    const status = useAppSelector((state) => state.missions.statuses.upload);
    const dispatch = useAppDispatch();

    const [clickSubmit, setClickSubmit] = useState<boolean>(false);

    const normalizeTags = (raw: string[]): string[] => {
        const result: string[] = [];
        const seen = new Set<string>();
        for (const t of raw) {
            const trimmed = t.trim();
            if (!trimmed) continue;
            const key = trimmed.toLowerCase();
            if (seen.has(key)) continue;
            seen.add(key);
            result.push(trimmed);
        }
        return result;
    };

    const addTag = () => {
        const parts = tagInput.split(',').map((v) => v.trim());
        const next = normalizeTags([...tags, ...parts]);
        setTags(next);
        setTagInput('');
    };

    const removeTag = (tagToRemove: string) => {
        setTags(tags.filter((tag) => tag !== tagToRemove));
    };

    const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
        if (e.target.files && e.target.files[0]) {
            setFile(e.target.files[0]);
        }
    };

    const handleSubmit = async () => {
        setClickSubmit(true);
        if (!file) return;

        const payloadTags =
            tagsMode === 'custom' ? normalizeTags(tags) : undefined;

        dispatch(
            uploadMission({
                missionFile: file,
                difficulty,
                tags: payloadTags,
            }),
        );
    };

    useEffect(() => {
        if (status === 'successful') {
            toastSuccess('Миссия создана!');
            setDifficulty(1);
            setTags([]);
            setFile(null);
            setTagInput('');
            setTagsMode('fromArchive');
            dispatch(setMissionsStatus({ key: 'upload', status: 'idle' }));
            setActive(false);
        }
    }, [status]);

    useEffect(() => {
        if (active == true) {
            setClickSubmit(false);
        }
        dispatch(setMissionsStatus({ key: 'upload', status: 'idle' }));
    }, [active]);

    const getDifficultyErrorMessage = (): string => {
        if (!clickSubmit) return '';
        if (!Number.isFinite(difficulty) || difficulty < 1)
            return 'Укажите сложность (минимум 1)';
        return '';
    };

    const tagsModeItems: DropDownListItem[] = [
        { text: 'Теги: из архива', value: 'fromArchive' },
        { text: 'Теги: без тегов', value: 'none' },
        { text: 'Теги: свои', value: 'custom' },
    ];

    const isTagsMode = (v: string): v is TagsMode =>
        v === 'fromArchive' || v === 'none' || v === 'custom';

    const currentTagsModeItem =
        tagsModeItems.find((i) => i.value === tagsMode) ?? tagsModeItems[0];

    useEffect(() => {
        if (tagsMode === 'none') {
            setTags([]);
            setTagInput('');
        }
    }, [tagsMode]);

    return (
        <Modal
            className="bg-liquid-background border-liquid-lighter border-[2px] p-[25px] rounded-[20px] text-liquid-white"
            onOpenChange={setActive}
            open={active}
            backdrop="blur"
        >
            <div className="w-[500px]">
                <div className="font-bold text-[30px]">Добавить задачу</div>

                <NumberInput
                    name="difficulty"
                    className="mt-[10px]"
                    label="Сложность"
                    defaultState={difficulty}
                    minValue={1}
                    maxValue={3500}
                    onChange={(v) => setDifficulty(v)}
                    placeholder="1"
                    error={getDifficultyErrorMessage()}
                />

                <div className="mt-4">
                    <label className="block mb-2">Файл задачи</label>
                    <label className="cursor-pointer inline-flex items-center justify-center px-4 py-2 bg-liquid-lighter hover:bg-liquid-dark transition-colors rounded-[10px] text-liquid-white font-medium">
                        {file ? file.name : 'Выбрать файл'}
                        <input
                            type="file"
                            onChange={handleFileChange}
                            accept=".zip"
                            className="hidden"
                        />
                    </label>
                    {
                        <div
                            className={cn(
                                'text-liquid-red text-[14px] h-auto text-left mt-[5px] whitespace-pre-line overflow-hidden ',
                                (!clickSubmit || file) && 'h-0 mt-0',
                            )}
                        >
                            Необходимо выбрать файл задачи
                        </div>
                    }
                </div>

                {/* Теги */}
                <div className="mb-[50px] max-w-[600px]">
                    <div className="mt-[20px]">
                        <div className="text-[18px] text-liquid-white font-medium h-[23px] mb-[10px]">
                            Режим тегов
                        </div>
                        <DropDownList
                            items={tagsModeItems}
                            defaultState={currentTagsModeItem}
                            onChange={(v) => {
                                if (isTagsMode(v)) setTagsMode(v);
                            }}
                            weight="w-full"
                        />
                        {tagsMode === 'none' && (
                            <div className="text-liquid-red text-[14px] mt-[8px] whitespace-pre-line">
                                Пустой список тегов сейчас не поддерживается в multipart.
                                Будет использован режим “из архива”.
                            </div>
                        )}
                    </div>

                    {tagsMode === 'custom' && (
                        <>
                            <div className="grid grid-cols-[1fr,140px] items-end gap-2">
                                <Input
                                    name="missionTags"
                                    autocomplete="missionTags"
                                    className="mt-[20px] max-w-[600px]"
                                    type="text"
                                    label="Теги (через запятую)"
                                    onChange={(v) => setTagInput(v)}
                                    defaultState={tagInput}
                                    placeholder="arrays, dp"
                                    onKeyDown={(e) => {
                                        if (e.key === 'Enter') addTag();
                                    }}
                                />
                                <PrimaryButton
                                    onClick={addTag}
                                    text="Добавить"
                                    className="h-[40px] w-[140px]"
                                />
                            </div>
                            <div className="flex flex-wrap gap-[10px] mt-2">
                                {tags.map((tag) => (
                                    <div
                                        key={tag}
                                        className="flex items-center gap-1 bg-liquid-lighter px-3 py-1 rounded-full"
                                    >
                                        <span>{tag}</span>
                                        <button
                                            onClick={() => removeTag(tag)}
                                            className="text-liquid-red font-bold ml-[5px]"
                                        >
                                            ×
                                        </button>
                                    </div>
                                ))}
                            </div>
                        </>
                    )}
                </div>

                <div>
                    Создать пакет задачи можно на платформе{' '}
                    <Link
                        to={'https://polygon.codeforces.com'}
                        target="_blank"
                        className="text-[#7489ff] hover:text-[#8c9dfd] transition-color duration-300"
                    >
                        polygon
                    </Link>
                </div>

                <div className="flex flex-row w-full items-center justify-end mt-[20px] gap-[20px]">
                    <PrimaryButton
                        onClick={handleSubmit}
                        text={status === 'loading' ? 'Загрузка...' : 'Создать'}
                        disabled={status === 'loading'}
                    />
                    <SecondaryButton
                        onClick={() => setActive(false)}
                        text="Отмена"
                    />
                </div>
            </div>
        </Modal>
    );
};

export default ModalCreate;
