import { Button, Group, Stack, Text, Box, Transition } from "@mantine/core";
import classes from './InputChain.module.css'
import { useEffect, useState } from "react";

interface InputChainProps {
    text: string;
    hidden: number;
    onPassed: () => void;
    onNotPassed?: () => void;
    size?: string;
    w?: number;
}

export function InputChainHidden(props : InputChainProps) {
    const text = props.text;
    if(text.trim() == ""){
        return (<></>);
    }
    
    const words = text.split(" ");
    const [hiddenIndices, setHiddenIndices] = useState<number[]>([]);
    const [selectedWords, setSelectedWords] = useState<(string | null)[]>([]);
    const [availableWords, setAvailableWords] = useState<string[]>([]);
    const [wrongIndices, setWrongIndices] = useState<number[]>([]);
    const [correctIndices, setCorrectIndices] = useState<number[]>([]);
    const [mounted, setMounted] = useState(false);

    useEffect(() => {
        let hidden : number[] = [];
        while (hidden.length < props.hidden) {
            let num = Math.floor(Math.random() * words.length);
            if(hidden.indexOf(num) == -1){
                hidden.push(num);
            }
        }
        hidden.sort((a, b) => a - b);
        setHiddenIndices(hidden);
        
        const hiddenWords = hidden.map(idx => words[idx]);
        const shuffled = [...hiddenWords].sort(() => Math.random() - 0.5);
        setAvailableWords(shuffled);
        setSelectedWords(new Array(hidden.length).fill(null));
        
        setTimeout(() => setMounted(true), 100);
    }, []);

    const handleWordClick = (word: string) => {
        const firstEmptyIndex = selectedWords.findIndex(w => w === null);
        if (firstEmptyIndex !== -1) {
            const newSelected = [...selectedWords];
            newSelected[firstEmptyIndex] = word;
            setSelectedWords(newSelected);
            setAvailableWords(availableWords.filter(w => w !== word));
            checkIfPassed(newSelected);
            validateWords(newSelected);
        }
    };

    const handleRemoveWord = (index: number) => {
        const word = selectedWords[index];
        if (word) {
            const newSelected = [...selectedWords];
            newSelected[index] = null;
            setSelectedWords(newSelected);
            setAvailableWords([...availableWords, word]);
            if(props.onNotPassed){
                props.onNotPassed();
            }
            validateWords(newSelected);
        }
    };

    const validateWords = (selected: (string | null)[]) => {
        const wrong: number[] = [];
        const correct: number[] = [];
        selected.forEach((word, idx) => {
            if (word !== null) {
                if (word === words[hiddenIndices[idx]]) {
                    correct.push(idx);
                } else {
                    wrong.push(idx);
                }
            }
        });
        setWrongIndices(wrong);
        setCorrectIndices(correct);
    };

    const checkIfPassed = (selected: (string | null)[]) => {
        const allFilled = selected.every(w => w !== null);
        if (allFilled) {
            const isCorrect = selected.every((word, idx) => 
                word === words[hiddenIndices[idx]]
            );
            if (isCorrect) {
                props.onPassed();
            } else if(props.onNotPassed) {
                props.onNotPassed();
            }
        } else {
            if(props.onNotPassed){
                props.onNotPassed();
            }
        }
    };

    return (
        <Stack gap="sm">
            {/* Target area - where words should be placed */}
            <Transition mounted={mounted} transition="slide-up" duration={400} timingFunction="ease">
                {(styles) => (
                    <Box className={classes.targetArea} style={styles}>
                        <Text size="sm" mb="xs" c="dimmed">
                            Click the words in the correct order:
                        </Text>
                        <Group gap="xs">
                            {words.map((word, i) => {
                                const hiddenIdx = hiddenIndices.indexOf(i);
                                const isHidden = hiddenIdx !== -1;
                                
                                if (!isHidden) {
                                    return (
                                        <Box key={i} className={classes.staticWord}>
                                            <Text size="sm" c="dimmed">{i + 1}.</Text>
                                            <Text size="sm">{word}</Text>
                                        </Box>
                                    );
                                }
                                
                                const isWrong = wrongIndices.includes(hiddenIdx);
                                const isCorrect = correctIndices.includes(hiddenIdx);
                                
                                return (
                                    <Button
                                        key={i}
                                        variant={selectedWords[hiddenIdx] ? "filled" : "default"}
                                        size="sm"
                                        className={classes.targetSlot}
                                        color={isWrong ? "red" : isCorrect ? "green" : undefined}
                                        onClick={() => selectedWords[hiddenIdx] && handleRemoveWord(hiddenIdx)}
                                    >
                                        <Text size="sm" c={selectedWords[hiddenIdx] ? 'white' : 'dimmed'} mr={4}>{i + 1}.</Text>
                                        {selectedWords[hiddenIdx] || "_____"}
                                    </Button>
                                );
                            })}
                        </Group>
                    </Box>
                )}
            </Transition>

            {/* Available words area */}
            <Transition mounted={mounted} transition="slide-up" duration={500} timingFunction="ease">
                {(transitionStyles) => (
                    <Box mih={100} className={classes.availableArea} style={transitionStyles}>
                        <Text size="sm" mb="xs" c="dimmed">
                            Available words:
                        </Text>
                        <Group gap="xs">
                            {availableWords.map((word, idx) => (
                                <Button
                                    key={`${word}-${idx}`}
                                    variant="light"
                                    size="sm"
                                    onClick={() => handleWordClick(word)}
                                    className={classes.availableWord}
                                >
                                    {word}
                                </Button>
                            ))}
                        </Group>
                    </Box>
                )}
            </Transition>
        </Stack>
    );
}