import { CheckIcon, DeleteIcon, FolderIcon, VisibilityIcon } from '@bigcommerce/big-design-icons';
import { Box, Button, Form, FormGroup, Input, Modal, Panel, Table } from '@bigcommerce/big-design';
import { useMemo, useState } from 'react';
import { useHoseAssemblyRequests } from '../../../lib/hooks';

const Index = () => {
    const { requests, mutateRequests } = useHoseAssemblyRequests();
    const [isDetailsOpen, setIsDetailsOpen] = useState(false);
    const [activeRequest, setActiveRequest] = useState<any | null>(null);

    const [exportFromDate, setExportFromDate] = useState('');
    const [exportToDate, setExportToDate] = useState('');
    const [isExportingBulk, setIsExportingBulk] = useState(false);
    const [isExportingSingle, setIsExportingSingle] = useState(false);
    const [exportError, setExportError] = useState<string | null>(null);

    const canBulkExport = useMemo(() => {
        return Boolean(exportFromDate && exportToDate);
    }, [exportFromDate, exportToDate]);

    const downloadCsv = async (payload: any, fallbackFileName: string) => {
        const res = await fetch('/api/hose/requests', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify(payload),
        });

        if (!res.ok) {
            let message = 'Failed to export';
            try {
                const json = await res.json();
                if (typeof json?.message === 'string') message = json.message;
            } catch {
            }
            throw new Error(message);
        }

        const blob = await res.blob();
        const url = window.URL.createObjectURL(blob);

        const contentDisposition = res.headers.get('content-disposition') || '';
        const match = /filename="?([^";]+)"?/i.exec(contentDisposition);
        const fileName = match?.[1] || fallbackFileName;

        const a = document.createElement('a');
        a.href = url;
        a.download = fileName;
        document.body.appendChild(a);
        a.click();
        a.remove();

        window.URL.revokeObjectURL(url);
    };

    const formatPart = (r: any, title: string, key: string) => {
        const label = r?.[`${key}_label_resolved`] ?? r?.[`${key}_label`] ?? '';
        const code = r?.[`${key}_code_resolved`] ?? r?.[`${key}_code`] ?? '';
        const labelText = String(label || '').trim();
        const codeText = String(code || '').trim();

        if (!labelText && !codeText) {
            return `${title}: -`;
        }
        if (labelText && codeText) {
            return `${title}: ${labelText} (${codeText})`;
        }

        return `${title}: ${labelText || codeText}`;
    };

    const exportSingle = async (id: number) => {
        setExportError(null);
        setIsExportingSingle(true);
        try {
            await downloadCsv(
                { action: 'export_single', id },
                `hose-request_${id}.csv`
            );
        } catch (error: any) {
            const message = typeof error?.message === 'string' ? error.message : 'Failed to export request';
            setExportError(message);
        } finally {
            setIsExportingSingle(false);
        }
    };

    const exportBulk = async () => {
        if (!exportFromDate || !exportToDate) return;

        setExportError(null);
        setIsExportingBulk(true);
        try {
            await downloadCsv(
                { action: 'export_bulk', fromDate: exportFromDate, toDate: exportToDate },
                `hose-requests_${exportFromDate}_to_${exportToDate}.csv`
            );
        } catch (error: any) {
            const message = typeof error?.message === 'string' ? error.message : 'Failed to export requests';
            setExportError(message);
        } finally {
            setIsExportingBulk(false);
        }
    };

    const loadDetails = async (id: number) => {
        const details = await fetch('/api/hose/requests', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify({ action: 'details', id }),
        }).then((response) => response.json());

        setActiveRequest(details?.request ?? null);
        setIsDetailsOpen(true);
    };

    const updateStatus = async (id: number, status: 'new' | 'processed' | 'archived') => {
        const result = await fetch('/api/hose/requests', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify({ action: 'status', id, status }),
        }).then((response) => response.json());

        if (Array.isArray(result?.requests)) {
            mutateRequests({ requests: result.requests }, false);
        }

        if (activeRequest && Number(activeRequest?.id) === Number(id)) {
            setActiveRequest({ ...activeRequest, status });
        }
    };

    const deleteRequest = async (id: number) => {
        const confirmed = window.confirm('Delete this request? This cannot be undone.');
        if (!confirmed) return;

        const result = await fetch('/api/hose/requests', {
            method: 'DELETE',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify({ id }),
        }).then((response) => response.json());

        if (Array.isArray(result?.requests)) {
            mutateRequests({ requests: result.requests }, false);
        }

        if (activeRequest && Number(activeRequest?.id) === Number(id)) {
            setIsDetailsOpen(false);
            setActiveRequest(null);
        }
    };

    const formatDate = (value: any) => {
        if (!value) return '';
        const d = new Date(value);
        if (Number.isNaN(d.getTime())) return String(value);

        const day = String(d.getDate()).padStart(2, '0');
        const month = String(d.getMonth() + 1).padStart(2, '0');
        const year = d.getFullYear();
        const hours = String(d.getHours()).padStart(2, '0');
        const minutes = String(d.getMinutes()).padStart(2, '0');

        return `${day}/${month}/${year} ${hours}:${minutes}`;
    };

    const getSummary = (r: any) => {
        const standard = r?.hose_standard_code_resolved || r?.hose_standard_code || '';
        const swivel = r?.hose_swivel_code_resolved || r?.hose_swivel_code || '';
        const gas = r?.hose_gas_code_resolved || r?.hose_gas_code || '';
        const type = r?.hose_type_code_resolved || r?.hose_type_code || '';
        const inlet = r?.hose_inlet_code_resolved || r?.hose_inlet_code || '';
        const outlet = r?.hose_outlet_code_resolved || r?.hose_outlet_code || '';
        const length = r?.hose_length_code_resolved || r?.hose_length_code || '';

        const partCode = `${swivel}${gas}${type}${inlet}${outlet}${length}`;
        const parts = [standard, partCode].filter(Boolean);

        return parts.join(' / ');
    };

    return (
        <Panel
            header="Hose Requests"
            description="Storefront customer hose assembly requests"
        >
            <Box marginTop="large">
                <Box marginBottom="large">
                    <Form fullWidth={true} onSubmit={(e) => {
                        e.preventDefault();
                        exportBulk();
                    }}>
                        <Box style={{ display: 'flex', flexDirection: 'row', flexWrap: 'wrap', alignItems: 'flex-end', gap: 12 }}>
                            <Box style={{ minWidth: 220 }}>
                                <FormGroup>
                                    <Input
                                        label="From"
                                        type="date"
                                        value={exportFromDate}
                                        onChange={(e) => setExportFromDate(e.target.value)}
                                        placeholder="YYYY-MM-DD"
                                    />
                                </FormGroup>
                            </Box>
                            <Box style={{ minWidth: 220 }}>
                                <FormGroup>
                                    <Input
                                        label="To"
                                        type="date"
                                        value={exportToDate}
                                        onChange={(e) => setExportToDate(e.target.value)}
                                        placeholder="YYYY-MM-DD"
                                    />
                                </FormGroup>
                            </Box>
                            <Box>
                                <Button
                                    type="submit"
                                    variant="secondary"
                                    disabled={!canBulkExport || isExportingBulk}
                                    isLoading={isExportingBulk}
                                >
                                    Export CSV
                                </Button>
                            </Box>
                        </Box>
                    </Form>
                    {exportError && (
                        <Box marginTop="medium" style={{ color: '#d14343' }}>
                            {exportError}
                        </Box>
                    )}
                </Box>
                <Box style={{ overflowX: 'auto', WebkitOverflowScrolling: 'touch' }}>
                    <Table
                        columns={[
                            { header: 'ID', hash: 'id', render: ({ id }) => id },
                            { header: 'Created', hash: 'created_at', render: ({ created_at }) => formatDate(created_at) },
                            { header: 'Customer', hash: 'customer', render: ({ customer_name, customer_email }) => `${customer_name} (${customer_email})` },
                            { header: 'Mobile', hash: 'customer_mobile', render: ({ customer_mobile }) => customer_mobile },
                            { header: 'Qty', hash: 'quantity', render: ({ quantity }) => quantity },
                            { header: 'Summary', hash: 'summary', render: (item) => getSummary(item) },
                            { header: 'Status', hash: 'status', render: ({ status }) => status },
                            {
                                header: 'Action',
                                hash: 'action',
                                render: ({ id, status }) => (
                                    <Box style={{ display: 'flex', flexDirection: 'row', gap: 4 }}>
                                        <Button
                                            variant="subtle"
                                            iconOnly={<VisibilityIcon />}
                                            aria-label="View request"
                                            title="View"
                                            onClick={() => loadDetails(Number(id))}
                                        />
                                        {status !== 'processed' && status !== 'archived' && (
                                            <Button
                                                variant="subtle"
                                                iconOnly={<CheckIcon />}
                                                aria-label="Mark processed"
                                                title="Mark processed"
                                                onClick={() => updateStatus(Number(id), 'processed')}
                                            />
                                        )}
                                        {status !== 'archived' && (
                                            <Button
                                                variant="subtle"
                                                iconOnly={<FolderIcon />}
                                                aria-label="Archive"
                                                title="Archive"
                                                onClick={() => updateStatus(Number(id), 'archived')}
                                            />
                                        )}
                                        <Button
                                            variant="subtle"
                                            iconOnly={<DeleteIcon />}
                                            aria-label="Delete request"
                                            title="Delete"
                                            onClick={() => deleteRequest(Number(id))}
                                        />
                                    </Box>
                                ),
                            },
                        ]}
                        items={requests}
                        keyField="id"
                        stickyHeader
                    />
                </Box>
            </Box>

            <Modal
                actions={[
                    {
                        text: 'Close',
                        variant: 'subtle',
                        onClick: () => setIsDetailsOpen(false),
                    },
                    {
                        text: 'Export CSV',
                        variant: 'secondary',
                        onClick: () => {
                            if (activeRequest?.id) exportSingle(Number(activeRequest.id));
                        },
                        disabled: !activeRequest?.id || isExportingSingle,
                        isLoading: isExportingSingle,
                    },
                ]}
                closeOnClickOutside={true}
                closeOnEscKey={true}
                header={`Request Details${activeRequest?.id ? ` #${activeRequest.id}` : ''}`}
                isOpen={isDetailsOpen}
                onClose={() => setIsDetailsOpen(false)}
            >
                <Box>
                    {activeRequest ? (
                        <Box>
                            <Box marginBottom="medium"><strong>Status:</strong> {activeRequest.status}</Box>
                            <Box marginBottom="medium"><strong>Created:</strong> {formatDate(activeRequest.created_at)}</Box>
                            <Box marginBottom="medium"><strong>Customer:</strong> {activeRequest.customer_name} ({activeRequest.customer_email})</Box>
                            <Box marginBottom="medium"><strong>Mobile:</strong> {activeRequest.customer_mobile}</Box>
                            <Box marginBottom="medium"><strong>Quantity:</strong> {activeRequest.quantity}</Box>

                            <Box marginBottom="medium"><strong>Parts:</strong></Box>
                            <Box marginBottom="xSmall">{formatPart(activeRequest, 'Standard', 'hose_standard')}</Box>
                            <Box marginBottom="xSmall">{formatPart(activeRequest, 'Gas', 'hose_gas')}</Box>
                            <Box marginBottom="xSmall">{formatPart(activeRequest, 'Hose Type', 'hose_type')}</Box>
                            <Box marginBottom="xSmall">{formatPart(activeRequest, 'Swivel', 'hose_swivel')}</Box>
                            <Box marginBottom="xSmall">{formatPart(activeRequest, 'Inlet', 'hose_inlet')}</Box>
                            <Box marginBottom="xSmall">{formatPart(activeRequest, 'Outlet', 'hose_outlet')}</Box>
                            <Box marginBottom="medium">{formatPart(activeRequest, 'Length', 'hose_length')}</Box>

                            <Box marginBottom="medium"><strong>Summary:</strong> {getSummary(activeRequest)}</Box>
                        </Box>
                    ) : (
                        <Box>No details found.</Box>
                    )}
                </Box>
            </Modal>
        </Panel>
    );
};

export default Index;
