import { type PaymentType, type Platform, type Skill, type SkillLevel } from "@prisma/client"
import { type Dispatch, type SetStateAction, useEffect, useState } from "react";

type QuestionTypes = Platform | Skill | SkillLevel | PaymentType | string;

interface Option<T> {
    label: string,
    value: T,
}

interface Question<T> {
    for: string,
    header: string,
    options: Option<T>[]
}

const questions: Question<QuestionTypes>[] = [
    {
        for: "ages",
        header: "Age of Patient",
        options: [
            {
                label: "Child",
                value: "0-9",
            },
            {
                label: "Teen",
                value: "10-20",
            },
            {
                label: "Adult",
                value: "21-100",
            },
        ],
    },
    {
        for: "platforms",
        header: "Desired Platforms",
        options: [
            {
                label: "Apple (iOS)",
                value: "APP_IOS",
            },
            {
                label: "Android",
                value: "APP_ANDROID",
            },
            {
                label: "Web-Based",
                value: "WEBSITE",
            },
            {
                label: "PDF (printable)",
                value: "PDF",
            }
        ]
    },
    {
        for: "skill_levels",
        header: "Skill Level",
        options: [
            {
                label: "Beginner",
                value: "BEGINNER",
            },
            {
                label: "Intermediate",
                value: "INTERMEDIATE",
            },
            {
                label: "Advanced",
                value: "ADVANCED",
            }
        ]
    },
    {
        for: "skills",
        header: "Skills Practiced",
        options: [
            {
                label: "Phonemes",
                value: "PHONEMES",
            },
            {
                label: "Words",
                value: "WORDS",
            },
            {
                label: "Sentence",
                value: "SENTENCES",
            },
            {
                label: "Discourse/Complex",
                value: "DISCOURSE",
            },
            {
                label: "Music",
                value: "MUSIC",
            },
            {
                label: "Environmental Sounds",
                value: "ENVIRONMENT",
            },
        ]
    }
]

const ChoiceQuestion = ({question, formData, updateFormData}: {question: Question<QuestionTypes>, formData: Record<string, QuestionTypes[]>, updateFormData: Dispatch<SetStateAction<Record<string, QuestionTypes[]>>>}) => {    
    const OptionToggle = ({option}: {option: Option<QuestionTypes>}) => {
        const selected = formData[question.for]?.includes(option.value) ?? false;
        
        const handleToggle = () => {
            const newFormData = {
                ...formData
            };

            if (!newFormData[question.for]) {
                newFormData[question.for] = [option.value];
            } else if (newFormData[question.for]?.includes(option.value)) {
                newFormData[question.for] = newFormData[question.for]?.filter(function(item) {
                    return item !== option.value
                }) ?? [];
            } else {
                newFormData[question.for] = [...newFormData[question.for] ?? [], option.value];
            }

            updateFormData(newFormData);
        }

        return (
            <button type="button" onClick={handleToggle} className={"w-64 shadow rounded-lg border border-neutral-400 " + (selected ? "bg-amber-200" : "bg-white")}>
                {option.label}
            </button>
        )
    }

    useEffect(() => {
        if (!formData[question.for]) {
            const newFormData = {...formData};
            newFormData[question.for] = [];

            updateFormData(newFormData);
        }
    });

    const htmlOptions: JSX.Element[] = []
    const optionButtons: JSX.Element[] = []

    question.options.forEach((option, index) => {
        optionButtons.push(<OptionToggle key={index} option={option} />)
        htmlOptions.push(<option key={index} selected={formData[question.for]?.includes(option.value)} value={option.value.toString()}>{option.label}</option>)
    });
    
    return (
        <div className="text-center border-b border-neutral-400 py-4 mx-auto">
            <label htmlFor={question.for} className="font-bold text-xl mb-2">{question.header}</label>
            <select className="hidden" name={question.for} multiple>
                {htmlOptions}
            </select>
            <div className="flex flex-col">
                {optionButtons}
            </div>
        </div>
    )
}

const SearchForm = ({questions}: {questions: Question<QuestionTypes>[]}) => {    
    const [formData, setFormData] = useState<(Record<string, QuestionTypes[]>)>({});
    
    const questionComponents = questions.map((question, index) => {
        return <ChoiceQuestion key={index} question={question} formData={formData} updateFormData={setFormData} />
    })

    return (
        <form action="/resources" className="py-4 flex flex-col">
            {questionComponents}
            <button className="mt-4 font-bold text-xl py-2 px-4 bg-white mx-auto rounded-xl border border-neutral-400 hover:border-neutral-800">search</button>
        </form>
    )
}

const SearchPage = () => {
    return <>
        <div className="w-full max-w-xl mx-auto mt-4 mb-4 rounded-xl overflow-hidden bg-neutral-200 drop-shadow-md">
            <div className="px-4 py-2 bg-gradient-to-t from-neutral-900 to-neutral-700 mx-auto overflow-hidden border border-neutral-400">
                <h1 className="text-gray-300 font-bold">Search</h1>
            </div>
            <div>
                <SearchForm questions={questions} />
            </div>
        </div>
    </>
}

export default SearchPage