import { useContext, useEffect, useRef, useState } from 'react';
import { faker } from '@faker-js/faker';

import { dateToOrdinal, ordinalToDate } from '@/app/lib/ordinalDate';
import { Product } from '@/app/lib/product.enum';
import { SupplyChainContext } from '@/app/lib/context/SupplyChain/SupplyChainContext';
import { ParsedBarcode, barcodeToProduct } from '@/app/lib/barcode';

import { BinnerContext } from '../../context/BinnerContext';
import { useGetProcessorByBarcodeId } from '../../hooks';

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

export function ProductInfo() {
    const { item, setItem } = useContext(BinnerContext);
    const { processors } = useContext(SupplyChainContext);
    const [inputItem, setInputItem] = useState<Partial<ParsedBarcode> | null>(null);
    const dateRef = useRef<HTMLInputElement>(null);
    const weightRef = useRef<HTMLInputElement>(null);
    const getProcessorByBarcodeId = useGetProcessorByBarcodeId();

    const isCompleteItem = (item: Partial<ParsedBarcode> | null) => item && !!(item?.product && item?.date && item?.processor && item?.weight);

    const [isEntryMode, setIsEntryMode] = useState(!isCompleteItem(item));

    useEffect(() => {
        setIsEntryMode(!isCompleteItem(item));
    }, [item])

    useEffect(() => {
        if (isCompleteItem(inputItem)) {
            setItem(barcodeToProduct(`${inputItem?.product}${inputItem?.date}${inputItem?.processor}${inputItem?.weight}`));
            setInputItem(null);
        }
        setIsEntryMode(!isCompleteItem(inputItem));
    }, [inputItem])

    return (
        <div className={styles.productInfo}>
            <div className={styles.attributes}>
                <div className={styles.card}>
                    <label htmlFor="product">Product</label>
                    {isEntryMode ? (
                        <select 
                            id="product" 
                            defaultValue="" 
                            onChange={(e) => setInputItem({ ...inputItem || {}, product: e.currentTarget.value })}
                        >
                            <option value="">Select a product</option>
                            {Object.keys(Product).map((product) => (
                                <option key={product} value={Product[product]}>{product}</option>
                            ))}
                        </select>
                    ) : (
                        <input id="product" value={item?.product!} contentEditable={false} />
                    )}
                </div>
                <div className={styles.card}>
                    <label htmlFor="date">Packaged Date</label>
                    <input
                        id="date" value={!!item ? ordinalToDate(item.date).toDateString() : ''}
                        contentEditable={isEntryMode}
                        ref={dateRef}
                        onChange={(e) => {
                            dateRef.current.value = e.currentTarget.value; 
                            setInputItem({ ...inputItem || {}, date: dateToOrdinal(new Date(e.currentTarget.value)) }) 
                        }} 
                    />
                </div>
                <div className={styles.card}>
                    <label htmlFor="processor">Processor</label>
                    {isEntryMode ? (
                        <select
                            id="processor"
                            defaultValue=""
                            onChange={(e) => setInputItem({ ...inputItem || {}, processor: e.currentTarget.value })}
                        >
                            <option value="">Select a processor</option>
                            {processors.map((processor) => (
                                <option key={processor._id} value={processor.barcode_id}>{processor.name}</option>
                            ))}
                        </select>
                    ) : (
                        <input id="processor" value={!!item ? (getProcessorByBarcodeId(item.processor)?.name ?? 'unknown/invalid processor') : ''} contentEditable={false} />
                    )}
                </div>
                <div className={styles.card}>
                    <label htmlFor="weight">Weight</label>
                    <div className={styles.inputWithButton}>
                        <input
                            id="weight" 
                            value={!!item ? `${item.weight} lbs.` : ''} 
                            contentEditable={false}
                            tabIndex={-1} 
                            ref={weightRef}
                        />
                        {isEntryMode && (
                            <button 
                                onClick={(e) => {
                                    const weight = faker.number.int({ min: 1000, max: 1999 });
                                    weightRef.current.value = `${weight / 100} lbs`; setInputItem({ ...inputItem || {}, weight }) 
                                }} 
                                tabIndex={0}
                            >
                                Weight from Scale
                            </button>
                        )}
                    </div>
                </div>
            </div>
        </div>
    );
}