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 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(() => {
        console.log('item', { item, complete: isCompleteItem(item) });
        setIsEntryMode(!isCompleteItem(item));
    }, [item])

    useEffect(() => {
        if (isCompleteItem(inputItem)) {
            console.log('inputItem', { inputItem, barcode: `${inputItem?.product}${inputItem?.date}${inputItem?.processor}${inputItem?.weight}` });
            setItem(barcodeToProduct(`${inputItem?.product}${inputItem?.date}${inputItem?.processor}${inputItem?.weight}`));
            setInputItem(null);
        }
    }, [inputItem]);

    const getDateString = (date: Date) => {
        const yyyy = date.getFullYear();
        let mm: number | string = date.getMonth() + 1;
        let dd: number | string = date.getDate();

        if (dd < 10) {
            dd = '0' + dd;
        } 
        
        if (mm < 10) {
            mm = '0' + mm;
        }
        return `${yyyy}-${mm}-${dd}`;
    }

    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" 
                        type="date"
                        value={!!item ? getDateString(ordinalToDate(item.date)) : undefined}
                        contentEditable={isEntryMode}
                        onChange={isEntryMode ? (e) => {
                            setInputItem({ ...inputItem || {}, date: `${dateToOrdinal(new Date(e.currentTarget.valueAsNumber))}` }) 
                        } : undefined} 
                    />
                </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>
                        {isEntryMode ? (
                            <div className={styles.inputWithButton}>
                                <input
                                    id="weight"
                                    contentEditable={false}
                                    tabIndex={-1}
                                    ref={weightRef}
                                />
                                <button 
                                    onClick={(e) => {
                                        const weight = faker.number.int({ min: 1000, max: 1999 });
                                        if (weightRef.current) {
                                            weightRef.current.value = `${weight / 100} lbs`; 
                                        }
                                        setInputItem({ ...inputItem || {}, weight }) 
                                    }} 
                                    tabIndex={0}
                                >
                                    Weight from Scale
                                </button>
                            </div>
                        ) : (
                            <input
                                id="weight" 
                                value={!!item ? `${item?.weight} lbs.` : ''} 
                                contentEditable={false}
                                tabIndex={-1}
                                readOnly
                            />
                        )}
                </div>
            </div>
        </div>
    );
}