import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import clsx from 'clsx';

import { useSupplyChainData } from '@/app/lib/context/SupplyChain/hooks';
import { Defect, defectToLabel } from '@/app/lib/defect.enum';
import { useBinHandler } from './hooks';

import styles from './DetailForm.module.scss';

export function DetailsForm() {
    const { farms } = useSupplyChainData();

    const [farm, setFarm] = useState<string | null>(null);
    const [defect, setDefect] = useState<Defect | null>(null);

    const binHandler = useBinHandler();

    // Track keyboard focus state
    const [focusedDefect, setFocusedDefect] = useState<number | null>(null);

    // Refs for accessibility
    const addFarmRef = useRef<HTMLButtonElement>(null);
    const selectRef = useRef<HTMLSelectElement>(null);
    const defectRefs = useRef<(HTMLButtonElement | null)[]>([]);
    const defectsWrapRef = useRef<HTMLFieldSetElement>(null);
    const submitRef = useRef<HTMLButtonElement>(null);

    const waiReasonDescId = 'waiReasonDescription';
    const defectCodes = Object.keys(Defect).slice(0, Object.keys(Defect).length / 2).map((code) => parseInt(code));

    const handleDefectKeydown = useCallback((event: React.KeyboardEvent<HTMLFieldSetElement>) => {
        if (focusedDefect !== null) {
            if (event.key === 'ArrowDown') {
                setFocusedDefect(focusedDefect + 1 > defectRefs.current.length - 1 ? 0 : focusedDefect + 1);
            }
            if (focusedDefect !== null && event.key === 'ArrowUp') {
                setFocusedDefect(focusedDefect - 1 < 0 ? defectRefs.current.length - 1 : focusedDefect - 1);
            }
        } else {
            if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {
                setFocusedDefect(0);
            }
        }
    }, [focusedDefect]);

    useEffect(() => {
        if (submitRef.current) {
            submitRef.current.focus();
        }
    }, [defect]);

    useEffect(() => {
        if (focusedDefect !== null && defectRefs.current[focusedDefect]) {
            defectRefs.current[focusedDefect]?.focus();
        }
    }, [focusedDefect]);

    useEffect(() => {
        if (selectRef.current) {
            selectRef.current.focus();
        }
    }, []);

    return (
        <div className={styles.detailForm}>
            <fieldset className={styles.fieldset} onKeyDown={(e) => e.key === 'ArrowRight' && addFarmRef.current?.click()}>
                <legend>Farm Information</legend>
                <div className={styles.selectWrap}>
                    <label  htmlFor="farm">Select source farm</label>
                    <select name="farm" id="farm" onChange={(event) => setFarm(event.target.value)} ref={selectRef} defaultValue="">
                        <option value="" disabled>Select a farm</option>
                        {farms.map((farm) => <option key={farm._id} value={farm._id}>{farm.name}</option>)}
                    </select>
                    <button onClick={() => alert('Users could add a farm where one does not exist!')} tabIndex={-1} ref={addFarmRef}>Add new farm</button>
                </div>
            </fieldset>
            <fieldset  className={styles.fieldset} onKeyDown={handleDefectKeydown} ref={defectsWrapRef}>
                <legend id={waiReasonDescId}>Select a reason for binning</legend>
                <div className={styles.buttonWrap}>
                    {defectCodes.map((code, i) => (
                        <button 
                            key={code}
                            className={clsx(styles.defectBtn, defect === code && styles.selected)}
                            aria-describedby={waiReasonDescId}
                            onClick={() => setDefect(code)}
                            ref={(el) => defectRefs.current[code] = el}
                            tabIndex={i === 0 ? 0 : -1}
                        >
                            {defectToLabel(code)}
                        </button>
                    ))}
                </div>
            </fieldset>
            <button className={styles.submitBtn} disabled={defect === null} onClick={() => binHandler(farm, defect as Defect)} ref={submitRef}>Bin It!</button>
        </div>
    );
}

