import React, { useState, useEffect, useMemo, useRef } from 'react';
import { Head } from '@inertiajs/react';
import AppLayout from '@/Layouts/AppLayout';
import {
    MaterialReactTable,
    type MRT_ColumnDef,
    type MRT_PaginationState,
    type MRT_SortingState,
} from 'material-react-table';
import axios from 'axios';
import {toast, Toaster} from 'react-hot-toast';
import type { StockBatch, Supplier } from '@/types';

interface FileWithType {
    file: File;
    fileType: 'invoice' | 'label' | 'other';
}

export default function StockBatches() {
    const [data, setData] = useState<StockBatch[]>([]);
    const [suppliers, setSuppliers] = useState<Supplier[]>([]);
    const [isLoading, setIsLoading] = useState(false);
    const [rowCount, setRowCount] = useState(0);

    const [pagination, setPagination] = useState<MRT_PaginationState>({
        pageIndex: 0,
        pageSize: 10,
    });
    const [sorting, setSorting] = useState<MRT_SortingState>([
        { id: 'updatedAt', desc: true },
    ]);
    const [globalFilter, setGlobalFilter] = useState('');

    const dialogRef = useRef<HTMLDialogElement>(null);

    const defaultFormData = {
        supplierId: null as number | null,
        tracking_number: '' as string,
        arrival_date: '' as string,
    };
    const [formData, setFormData] = useState(defaultFormData);
    const [files, setFiles] = useState<FileWithType[]>([]);

    // inside your component, above the useMemo…
    const formatDate = (value: string, withTime = true) => {
        const d = new Date(value);
        const dd = String(d.getDate()).padStart(2, '0');
        const mm = String(d.getMonth() + 1).padStart(2, '0');
        const yyyy = d.getFullYear();
        if (!withTime) return `${dd}-${mm}-${yyyy}`;
        const hh = String(d.getHours()).padStart(2, '0');
        const mi = String(d.getMinutes()).padStart(2, '0');
        return `${dd}-${mm}-${yyyy} ${hh}:${mi}`;
    };

    const columns = useMemo<MRT_ColumnDef<StockBatch>[]>(() => [
        { accessorKey: 'id', header: 'ID', size: 80 },
        { accessorKey: 'supplier.name', header: 'Supplier', size: 150 },
        { accessorKey: 'tracking_number', header: 'Tracking #', size: 120 },
        {
            accessorKey: 'arrival_date',
            header: 'Arrival Date',
            size: 120,
            Cell: ({ cell }) => formatDate(cell.getValue<string>() || '', false),
        },
        {
            accessorFn: row => row.files?.length ?? 0,
            id: 'files',
            header: 'Files',
            size: 80,
        },
        {
            accessorKey: 'created_at',
            header: 'Created At',
            size: 150,
            Cell: ({ cell }) => formatDate(cell.getValue<string>() || '', true),
        },
        {
            accessorKey: 'updated_at',
            header: 'Updated At',
            size: 150,
            Cell: ({ cell }) => formatDate(cell.getValue<string>() || '', true),
        },
    ], []);

    useEffect(() => {
        fetchSuppliers();
    }, []);

    useEffect(() => {
        fetchData();
    }, [pagination.pageIndex, pagination.pageSize, sorting, globalFilter]);

    async function fetchSuppliers() {
        try {
            const res = await axios.get('/api/stockBatches/options');
            setSuppliers(res.data.suppliers);
        } catch {
            toast.error('Failed to load suppliers');
        }
    }

    async function fetchData() {
        setIsLoading(true);
        try {
            const res = await axios.get('/api/stockBatches', {
                params: {
                    page: pagination.pageIndex + 1,
                    perPage: pagination.pageSize,
                    sortField: sorting[0]?.id,
                    sortOrder: sorting[0]?.desc ? 'desc' : 'asc',
                    filter: globalFilter,
                },
            });
            setData(res.data.data);
            console.log(res.data.data);
            setRowCount(res.data.meta.total);
        } catch {
            toast.error('Failed to load batches');
        } finally {
            setIsLoading(false);
        }
    }

    function openModal() {
        dialogRef.current?.showModal();
    }
    function closeModal() {
        dialogRef.current?.close();
        setFormData(defaultFormData);
        setFiles([]);
    }

    const handleInputChange = (
        e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement>
    ) => {
        const { name, value } = e.target;
        setFormData(prev => ({
            ...prev,
            [name]:
                name === 'supplierId'
                    ? value
                        ? parseInt(value)
                        : null
                    : value,
        }));
    };

    const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
        if (e.target.files) {
            setFiles(
                Array.from(e.target.files).map(file => ({
                    file,
                    fileType: 'other' as const,
                }))
            );
        }
    };

    const handleFileTypeChange = (
        index: number,
        fileType: FileWithType['fileType']
    ) => {
        setFiles(prev =>
            prev.map((f, i) => (i === index ? { ...f, fileType } : f))
        );
    };

    const removeFile = (index: number) => {
        setFiles(prev => prev.filter((_, i) => i !== index));
    };

    const handleSubmit = async (e: React.FormEvent) => {
        e.preventDefault();
        try {
            const fd = new FormData();
            if (formData.supplierId !== null) {
                fd.append('supplier_id', formData.supplierId.toString());
            }
            if (formData.tracking_number) {
                fd.append('tracking_number', formData.tracking_number);
            }
            if (formData.arrival_date) {
                fd.append('arrival_date', formData.arrival_date);
            }
            files.forEach(({ file, fileType }, i) => {
                fd.append(`files[${i}]`, file);
                fd.append(`file_types[${i}]`, fileType);
            });

            await axios.post('/api/stockBatches', fd, {
                headers: { 'Content-Type': 'multipart/form-data' },
            });
            toast.success('Batch created');
            closeModal();
            fetchData();
            // inside your catch block…
        } catch (error: any) {
            if (axios.isAxiosError(error)) {
                // if it’s a 422 validation error
                if (error.response?.status === 422 && error.response.data.errors) {
                    const errs = error.response.data.errors as Record<string, string[]>;
                    // flat-map all the messages and toast each one
                    Object.values(errs)
                        .flat()
                        .forEach(msg => toast.error(msg, {
                            duration: 5000,
                        }));
                } else {
                    // some other HTTP error
                    toast.error(error.response?.statusText || 'Unknown error', {
                        duration: 5000,
                    });
                    toast.error(error.response?.data?.errors || '', {
                        duration: 5000,
                    });
                }
            } else {
                // non-Axios error
                toast.error('Failed to create batch');
            }
        }
    };

    return (
        <AppLayout
            title="Stock Batches"
            renderHeader={() => (
                <h2 className="font-semibold text-xl text-gray-800 dark:text-gray-200 leading-tight">
                    Stock Batches
                </h2>
            )}
        >
            <Head title="Stock Batches" />
            <Toaster
                position="top-center"
                reverseOrder={false}
            />
            <div className="py-12">
                <div className="max-w-7xl mx-auto sm:px-6 lg:px-8">
                    <div className="bg-white dark:bg-gray-800 overflow-hidden shadow-xl sm:rounded-lg p-6">
                        <div className="mb-4 flex justify-between items-center">
                            <h1 className="text-2xl font-bold">Batches</h1>
                            <button onClick={openModal} className="btn btn-primary">
                                Add New Batch
                            </button>
                        </div>
                        <MaterialReactTable
                            columns={columns}
                            data={data}
                            manualPagination
                            manualSorting
                            enableGlobalFilter
                            onPaginationChange={setPagination}
                            onSortingChange={setSorting}
                            onGlobalFilterChange={setGlobalFilter}
                            rowCount={rowCount}
                            state={{ isLoading, pagination, sorting, globalFilter }}
                        />
                    </div>
                </div>
            </div>

            <dialog ref={dialogRef} className="modal">
                <form onSubmit={handleSubmit} className="modal-box p-6">
                    <button
                        type="button"
                        onClick={closeModal}
                        className="btn btn-sm btn-circle btn-ghost absolute right-2 top-2"
                    >
                        ✕
                    </button>
                    <h3 className="font-bold text-lg mb-4">New Stock Batch</h3>

                    <div className="form-control mb-4">
                        <label htmlFor="supplierId" className="label">
                            <span className="label-text">Supplier</span>
                        </label>
                        <select
                            id="supplierId"
                            name="supplierId"
                            value={formData.supplierId ?? ''}
                            onChange={handleInputChange}
                            className="select"
                        >
                            <option value="">Select supplier...</option>
                            {suppliers.map(s => (
                                <option key={s.id} value={s.id}>
                                    {s.name}
                                </option>
                            ))}
                        </select>
                    </div>

                    <div className="form-control mb-4">
                        <label htmlFor="tracking_number" className="label">
                            <span className="label-text">Tracking Number</span>
                        </label>
                        <input
                            id="tracking_number"
                            name="tracking_number"
                            type="text"
                            value={formData.tracking_number}
                            onChange={handleInputChange}
                            className="input"
                        />
                    </div>

                    <div className="form-control mb-4">
                        <label htmlFor="arrival_date" className="label">
                            <span className="label-text">Arrival Date</span>
                        </label>
                        <input
                            id="arrival_date"
                            name="arrival_date"
                            type="date"
                            value={formData.arrival_date}
                            onChange={handleInputChange}
                            className="input"
                        />
                    </div>

                    <div className="form-control mb-4">
                        <label htmlFor="files" className="label">
                            <span className="label-text">Upload Files</span>
                        </label>
                        <input
                            id="files"
                            type="file"
                            multiple
                            onChange={handleFileChange}
                            className="file-input"
                        />
                    </div>

                    {files.map((f, idx) => (
                        <div key={idx} className="flex items-center mb-2 space-x-2">
                            <span>{f.file.name}</span>
                            <select
                                value={f.fileType}
                                onChange={e =>
                                    handleFileTypeChange(idx, e.target.value as FileWithType['fileType'])
                                }
                                className="select select-sm"
                            >
                                <option value="invoice">Invoice</option>
                                <option value="label">Label</option>
                                <option value="other">Other</option>
                            </select>
                            <button
                                type="button"
                                onClick={() => removeFile(idx)}
                                className="btn btn-sm btn-error"
                            >
                                Remove
                            </button>
                        </div>
                    ))}

                    <div className="modal-action">
                        <button type="submit" className="btn btn-primary">
                            Create Batch
                        </button>
                    </div>
                </form>
            </dialog>
        </AppLayout>
    );
}
