import { useEffect, useState } from 'react';
import {
    Button,
    Col,
    DatePicker,
    Descriptions,
    Form,
    Input,
    InputNumber,
    Modal,
    Popover,
    Row,
    Select,
    Space,
    Spin,
    Table,
    Tag,
    message,
} from 'antd';
import { DownloadOutlined, EyeOutlined, PlusOutlined, SearchOutlined } from '@ant-design/icons';
import dayjs, { Dayjs } from 'dayjs';
import { AppContainer } from '../../components/AppContainer';
import jwtAxios from '../../api/axiosInstance';
import { ENDPOINTS } from '../../api/endpoints';

const ENTITY_LABEL = 'Supplier Return';
const ENTITY_ENDPOINT = ENDPOINTS.PURCHASE_RETURNS;
const ENTITY_EXPORT_PDF = ENDPOINTS.PURCHASE_RETURNS_EXPORT_PDF;
const ENTITY_EXPORT_EXCEL = ENDPOINTS.PURCHASE_RETURNS_EXPORT_EXCEL;

interface DataRecord {
    key: string;
    id: string;
    returnDate: string;
    quantity: string;
    bags: string;
    returnAmount: string;
    reason: string;
    remarks: string;
    purchase?: {
        lotNo: string;
        supplier?: { name: string };
        vegetable?: { name: string };
    };
}

const { RangePicker } = DatePicker;

export const SupplierReturns = () => {
    const [form] = Form.useForm();
    const [open, setOpen] = useState(false);
    const [searchText, setSearchText] = useState('');
    const [dateRange, setDateRange] = useState<[Dayjs, Dayjs] | null>(null);
    const [data, setData] = useState<DataRecord[]>([]);
    const [loading, setLoading] = useState<boolean>(false);

    const [suppliers, setSuppliers] = useState<{ id: string; name: string }[]>([]);
    const [selectedSupplier, setSelectedSupplier] = useState<string | null>(null);

    const [purchases, setPurchases] = useState<any[]>([]);
    const [selectedPurchase, setSelectedPurchase] = useState<any | null>(null);

    const [pagination, setPagination] = useState({
        current: 1,
        pageSize: Number(import.meta.env.VITE_PAGE_SIZE) || 10,
        total: 0,
    });

    const [exportExcelLoading, setExportExcelLoading] = useState(false);
    const [exportPdfLoading, setExportPdfLoading] = useState(false);

    const [viewOpen, setViewOpen] = useState(false);
    const [viewLoading, setViewLoading] = useState(false);
    const [viewRecord, setViewRecord] = useState<any>(null);

    const fetchSuppliers = async () => {
        try {
            const res = await jwtAxios.get(ENDPOINTS.PURCHASE_META);
            const records = res.data?.result?.suppliers || [];
            setSuppliers(records.map((s: any) => ({
                id: s.id.toString(),
                name: s.name,
            })));
        } catch (err: any) {
            message.error(err.response?.data?.message || 'Failed to fetch suppliers');
        }
    };

    const fetchPurchases = async (supplierId: string) => {
        try {
            // Fetch purchases for this supplier that have remaining stock
            const res = await jwtAxios.get(`${ENDPOINTS.PURCHASE}?supplierId=${supplierId}&limit=1000`);
            const records = res.data?.result?.data || res.data?.result?.items || res.data?.data?.items || res.data?.items || [];
            const availablePurchases = records.filter((p: any) => p.supplierId?.toString() === supplierId.toString() && (Number(p.remainingQuantity) > 0 || Number(p.remainingBags) > 0));
            setPurchases(availablePurchases);
        } catch (err: any) {
            message.error(err.response?.data?.message || 'Failed to fetch purchases');
        }
    };

    const fetchData = async (
        page: number = pagination.current,
        limit: number = pagination.pageSize,
        search: string = searchText,
        range: [Dayjs, Dayjs] | null = dateRange
    ) => {
        setLoading(true);
        try {
            let url = `${ENTITY_ENDPOINT}?page=${page}&limit=${limit}&search=${search}`;
            if (range) {
                url += `&startDate=${range[0].format('YYYY-MM-DD')}&endDate=${range[1].format('YYYY-MM-DD')}`;
            }

            const res = await jwtAxios.get(url);
            const resData = res.data?.result ?? res.data?.data ?? res.data;

            const records = resData.items || resData.data || [];
            const total = resData.total || 0;

            setData(
                records.map((item: any) => ({
                    ...item,
                    key: item.id.toString(),
                }))
            );
            setPagination((prev) => ({ ...prev, current: page, total }));
        } catch (err: any) {
            message.error(err.response?.data?.message || `Failed to fetch ${ENTITY_LABEL.toLowerCase()}s`);
        } finally {
            setLoading(false);
        }
    };

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

    const handleTableChange = (newPagination: any) => {
        fetchData(newPagination.current, newPagination.pageSize, searchText, dateRange);
    };

    const handleSearch = () => {
        setPagination((prev) => ({ ...prev, current: 1 }));
        fetchData(1, pagination.pageSize, searchText, dateRange);
    };

    const handleResetSearch = () => {
        setSearchText('');
        setDateRange(null);
        setPagination((prev) => ({ ...prev, current: 1 }));
        fetchData(1, pagination.pageSize, '', null);
    };

    const buildExportParams = () => {
        const params = new URLSearchParams();
        if (searchText) params.set('search', searchText);
        if (dateRange) {
            params.set('startDate', dateRange[0].format('YYYY-MM-DD'));
            params.set('endDate', dateRange[1].format('YYYY-MM-DD'));
        }
        return params;
    };

    const handleExportExcel = async () => {
        if (!data || data.length === 0) {
            message.warning('No data available to export');
            return;
        }
        setExportExcelLoading(true);
        try {
            const response = await jwtAxios.get(
                `${ENTITY_EXPORT_EXCEL}?${buildExportParams().toString()}`,
                { responseType: 'blob' }
            );
            const disposition = response.headers['content-disposition'];
            let fileName = `supplier-returns-${dayjs().format('YYYY-MM-DD_HHmmss')}.xlsx`;
            if (disposition) {
                const match = disposition.match(/filename\*?=(?:UTF-8'')?"?([^"\n;]+)"?/i);
                if (match?.[1]) fileName = decodeURIComponent(match[1]);
            }
            const blob = new Blob([response.data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
            const objectUrl = window.URL.createObjectURL(blob);
            const link = document.createElement('a');
            link.href = objectUrl;
            link.download = fileName;
            document.body.appendChild(link);
            link.click();
            document.body.removeChild(link);
            window.URL.revokeObjectURL(objectUrl);
            message.success('Supplier returns exported successfully');
        } catch (err: any) {
            message.error(err.response?.data?.message || 'Failed to export Excel');
        } finally {
            setExportExcelLoading(false);
        }
    };

    const handleExportPdf = async () => {
        if (!data || data.length === 0) {
            message.warning('No data available to export');
            return;
        }
        setExportPdfLoading(true);
        try {
            const response = await jwtAxios.get(
                `${ENTITY_EXPORT_PDF}?${buildExportParams().toString()}`,
                { responseType: 'blob' }
            );
            const disposition = response.headers['content-disposition'];
            let fileName = `supplier-returns-${dayjs().format('YYYY-MM-DD')}.pdf`;
            if (disposition) {
                const match = disposition.match(/filename\*?=(?:UTF-8'')?"?([^"\n;]+)"?/i);
                if (match?.[1]) fileName = decodeURIComponent(match[1]);
            }
            const blob = new Blob([response.data], { type: 'application/pdf' });
            const objectUrl = window.URL.createObjectURL(blob);
            const link = document.createElement('a');
            link.href = objectUrl;
            link.download = fileName;
            document.body.appendChild(link);
            link.click();
            document.body.removeChild(link);
            window.URL.revokeObjectURL(objectUrl);
            message.success('Supplier returns exported as PDF successfully');
        } catch (err: any) {
            message.error(err.response?.data?.message || 'Failed to export PDF');
        } finally {
            setExportPdfLoading(false);
        }
    };

    const handleAdd = () => {
        form.resetFields();
        setSelectedSupplier(null);
        setPurchases([]);
        setSelectedPurchase(null);
        setOpen(true);
    };

    const handleOk = async () => {
        try {
            const values = await form.validateFields();
            setLoading(true);

            const payload = {
                ...values,
                returnDate: values.returnDate.format('YYYY-MM-DD'),
            };

            await jwtAxios.post(ENTITY_ENDPOINT, payload);
            message.success(`${ENTITY_LABEL} created successfully`);
            setOpen(false);
            fetchData();
        } catch (err: any) {
            if (err.name === 'ValidationError') return;
            message.error(err.response?.data?.message || `Failed to save ${ENTITY_LABEL.toLowerCase()}`);
        } finally {
            setLoading(false);
        }
    };

    const handleCancel = () => {
        setOpen(false);
    };

    const handleView = async (id: string) => {
        setViewLoading(true);
        setViewOpen(true);
        try {
            const res = await jwtAxios.get(`${ENTITY_ENDPOINT}/${id}`);
            const record = res.data?.result ?? res.data?.data ?? res.data;
            setViewRecord(record);
        } catch (err: any) {
            message.error(err.response?.data?.message || 'Failed to load return details');
            setViewOpen(false);
        } finally {
            setViewLoading(false);
        }
    };

    const onSupplierChange = (val: string) => {
        setSelectedSupplier(val);
        form.setFieldsValue({ purchaseId: undefined, returnAmount: undefined });
        setPurchases([]);
        setSelectedPurchase(null);
        if (val) {
            fetchPurchases(val);
        }
    };

    const onPurchaseChange = (val: string) => {
        const purchase = purchases.find((p) => p.id.toString() === val.toString());
        setSelectedPurchase(purchase || null);
        form.setFieldsValue({
            quantity: undefined,
            bags: undefined,
            returnAmount: undefined,
        });
    };

    const onQuantityChange = (qty: number | null) => {
        if (qty && selectedPurchase) {
            const costPerUnit = Number(selectedPurchase.costPerUnit || selectedPurchase.ratePerUnit || 0);
            const updates: any = { returnAmount: (qty * costPerUnit).toFixed(2) };

            if (selectedPurchase.unit !== 'KG' && selectedPurchase.weightPerBag) {
                updates.bags = Number((qty / Number(selectedPurchase.weightPerBag)).toFixed(3));
            }

            form.setFieldsValue(updates);
        }
    };

    const onBagsChange = (bgs: number | null) => {
        if (bgs && selectedPurchase && selectedPurchase.unit !== 'KG') {
            const isBagOnly = Number(selectedPurchase.quantity || 0) === 0;
            const costPerUnit = Number(selectedPurchase.costPerUnit || selectedPurchase.ratePerUnit || 0);

            if (isBagOnly) {
                form.setFieldsValue({
                    quantity: 0,
                    returnAmount: (bgs * costPerUnit).toFixed(2)
                });
            } else if (selectedPurchase.weightPerBag) {
                const qty = Number((bgs * Number(selectedPurchase.weightPerBag)).toFixed(3));
                form.setFieldsValue({
                    quantity: qty,
                    returnAmount: (qty * costPerUnit).toFixed(2)
                });
            }
        }
    };

    const columns = [
        {
            title: 'Return Date',
            dataIndex: 'returnDate',
            key: 'returnDate',
            width: 150,
            ellipsis: true,
            render: (text: string) => dayjs(text).format('DD/MM/YYYY'),
        },
        {
            title: 'Lot No',
            dataIndex: ['purchase', 'lotNo'],
            width: 150,
            ellipsis: true,
            key: 'lotNo',
        },
        {
            title: 'Supplier',
            dataIndex: ['purchase', 'supplier', 'name'],
            width: 150,
            ellipsis: true,
            key: 'supplier',
        },
        {
            title: 'Item',
            dataIndex: ['purchase', 'vegetable', 'name'],
            width: 150,
            ellipsis: true,
            key: 'vegetable',
        },
        {
            title: 'Qty Returned/KG',
            dataIndex: 'quantity',
            width: 150,
            ellipsis: true,
            key: 'quantity', // Represents the weight in TAG 
            render: (text: any) => (
                <span >
                    <Tag color="red">{text}</Tag>
                </span>
            ),
        },
        {
            title: 'Bags/Box Returned',
            dataIndex: 'bags',
            width: 150,
            ellipsis: true,
            key: 'bags',
            // render: (text: any, record: any) => text ? `${text} ${record.purchase?.unit === 'BOX' ? 'BOX' : 'BAG'}` : '-', //use TAg
            render: (text: any, record: any) =>
                text ? (
                    <Tag color={record.purchase?.unit === 'BOX' ? 'green' : 'blue'}>
                        {text} {record.purchase?.unit === 'BOX' ? 'BOX' : 'BAG'}
                    </Tag>
                ) : (
                    <Tag color='gray'>{'-'}</Tag>
                ),
        },
        {
            title: 'Return Amount',
            dataIndex: 'returnAmount',
            width: 150,
            ellipsis: true,
            key: 'returnAmount',
        },
        {
            title: 'Reason',
            dataIndex: 'reason',
            width: 150,
            ellipsis: true,
            key: 'reason',
            render: (text: any) => (
                text ? (
                    <Popover content={text} title="Reason">
                        <span>{text}</span>
                    </Popover>
                ) : '-'
            ),
        },
        {
            title: 'Remarks',
            dataIndex: 'remarks',
            width: 150,
            ellipsis: true,
            key: 'remarks',
            render: (text: any) => (
                text ? (
                    <Popover
                        title="Remarks"
                        content={
                            <div style={{ maxWidth: 300, whiteSpace: 'pre-wrap' }}>
                                {text}
                            </div>
                        }
                    >
                        <span>{text}</span>
                    </Popover>
                ) : '-'
            ),
        },
        {
            title: 'Actions',
            width: 150,
            render: (_: any, record: any) => (
                <Space>
                    <Button type="link" icon={<EyeOutlined />} onClick={() => handleView(record.id)} />
                </Space>
            ),
        }
    ];

    return (
        <AppContainer
            title={`${ENTITY_LABEL}s`}
            headerAction={
                <Space>
                    <RangePicker
                        value={dateRange}
                        onChange={(dates) => setDateRange(dates as [Dayjs, Dayjs] | null)}
                        format="DD/MM/YYYY"
                    />
                    <Input
                        placeholder="Search..."
                        value={searchText}
                        onChange={(e) => setSearchText(e.target.value)}
                        onPressEnter={handleSearch}
                        allowClear
                        style={{ width: 200 }}
                    />
                    <Button type="primary" icon={<SearchOutlined />} onClick={handleSearch}>
                        Search
                    </Button>
                    <Button onClick={handleResetSearch}>Reset</Button>
                    <Button type="primary" icon={<PlusOutlined />} onClick={handleAdd}>
                        Add {ENTITY_LABEL}
                    </Button>
                </Space>
            }
        >
            <div className="flex justify-end mb-4">
            <Space>
                <Button
                        icon={<DownloadOutlined />}
                        style={{ color: '#52c41a', borderColor: '#52c41a' }}
                        onClick={handleExportExcel}
                        loading={exportExcelLoading}
                    >
                        Export Excel
                    </Button>
                    <Button
                        icon={<DownloadOutlined />}
                        style={{ color: '#f5222d', borderColor: '#f5222d' }}
                        onClick={handleExportPdf}
                        loading={exportPdfLoading}
                    >
                        Export PDF
                    </Button>
            </Space>
            </div>
            <Table
                columns={columns}
                dataSource={data}
                rowKey="key"
                pagination={pagination}
                loading={loading}
                onChange={handleTableChange}
                scroll={{ x: 800 }}
            />

            <Modal
                title={`Add ${ENTITY_LABEL}`}
                open={open}
                onOk={handleOk}
                onCancel={handleCancel}
                confirmLoading={loading}
                width={700}
                destroyOnHidden
            >
                <Form form={form} layout="vertical">
                    <Row gutter={16}>
                        <Col span={12}>
                            <Form.Item
                                name="returnDate"
                                label="Return Date"
                                rules={[{ required: true, message: 'Please select a date' }]}
                                initialValue={dayjs()}
                            >
                                <DatePicker format="DD/MM/YYYY" style={{ width: '100%' }} />
                            </Form.Item>
                        </Col>
                        <Col span={12}>
                            <Form.Item
                                name="supplierId"
                                label="Supplier"
                                rules={[{ required: true, message: 'Please select a supplier' }]}
                            >
                                <Select
                                    placeholder="Select Supplier"
                                    onChange={onSupplierChange}
                                    showSearch
                                    optionFilterProp="children"
                                    filterOption={(input, option) =>
                                        (option?.label ?? '').toString().toLowerCase().includes(input.toLowerCase())
                                    }
                                    options={suppliers.map((s) => ({ label: s.name, value: s.id }))}
                                />
                            </Form.Item>
                        </Col>
                        <Col span={12}>
                            <Form.Item
                                name="purchaseId"
                                label="Purchase Lot"
                                rules={[{ required: true, message: 'Please select a purchase lot' }]}
                            >
                                <Select
                                    placeholder="Select Purchase Lot"
                                    onChange={onPurchaseChange}
                                    showSearch
                                    optionFilterProp="label"
                                    filterOption={(input, option) =>
                                        (option?.label ?? '').toString().toLowerCase().includes(input.toLowerCase())
                                    }
                                    options={purchases.map((p) => {
                                        const billPart = p.billNo ? `${p.billNo} ` : '';
                                        const bagPart = p.unit !== 'KG' && p.remainingBags != null ? ` / ${p.remainingBags} ${p.unit}` : '';
                                        return {
                                            label: `${billPart}${p.lotNo} ${p.vegetable?.name || 'Item'} - ${p.remainingQuantity} / ${p.quantity} KG${bagPart}`,
                                            value: p.id,
                                        };
                                    })}
                                    disabled={!selectedSupplier}
                                />
                            </Form.Item>
                        </Col>
                    </Row>

                    <Row gutter={16}>
                        <Col span={12}>
                            <Form.Item
                                name="quantity"
                                label="Return Quantity (KG)"
                                rules={[
                                    { required: true, message: 'Please enter return quantity' },
                                    {
                                        validator: async (_, value) => {
                                            if (value && selectedPurchase && value > Number(selectedPurchase.remainingQuantity)) {
                                                return Promise.reject(new Error(`Max allowable is ${selectedPurchase.remainingQuantity}`));
                                            }
                                            return Promise.resolve();
                                        },
                                    }
                                ]}
                            >
                                <InputNumber min={0} step={1} style={{ width: '100%' }} onChange={onQuantityChange} disabled={!selectedPurchase || (selectedPurchase.unit !== 'KG' && Number(selectedPurchase.quantity || 0) === 0)} />
                            </Form.Item>
                        </Col>
                        <Col span={12}>
                            <Form.Item
                                name="bags"
                                label={`Return ${selectedPurchase?.unit === 'BOX' ? 'Box' : 'Bags'}`}
                                rules={[
                                    {
                                        validator: async (_, value) => {
                                            if (value && selectedPurchase && value > Number(selectedPurchase.remainingBags)) {
                                                return Promise.reject(new Error(`Max allowable is ${selectedPurchase.remainingBags}`));
                                            }
                                            return Promise.resolve();
                                        },
                                    }
                                ]}
                            >
                                <InputNumber min={0} step={0.01} style={{ width: '100%' }} onChange={onBagsChange} disabled={selectedPurchase?.unit === 'KG' || !selectedPurchase} />
                            </Form.Item>
                        </Col>
                    </Row>

                    <Row gutter={16}>
                        <Col span={12}>
                            <Form.Item
                                name="returnAmount"
                                label="Return Amount"
                                rules={[{ required: true, message: 'Please enter return amount' }]}
                            >
                                <InputNumber min={0} step={0.01} style={{ width: '100%' }} />
                            </Form.Item>
                        </Col>
                        <Col span={12}>
                            <Form.Item
                                name="reason"
                                label="Reason"
                            >
                                <Input placeholder="Enter reason" />
                            </Form.Item>
                        </Col>
                        <Col span={24}>
                            <Form.Item
                                name="remarks"
                                label="Remarks"
                            >
                                <Input.TextArea rows={2} placeholder="Enter remarks" />
                            </Form.Item>
                        </Col>
                    </Row>
                </Form>
            </Modal>

            {/* View Return Details Modal */}
            <Modal
                title="Supplier Return Details"
                open={viewOpen}
                onCancel={() => { setViewOpen(false); setViewRecord(null); }}
                footer={<Button onClick={() => { setViewOpen(false); setViewRecord(null); }}>Close</Button>}
                width={750}
                destroyOnHidden
            >
                <Spin spinning={viewLoading}>
                    {viewRecord && (
                        <>
                            <Descriptions
                                title="Return Information"
                                bordered
                                column={2}
                                size="small"
                                style={{ marginBottom: 24 }}
                            >
                                <Descriptions.Item label="Return Date" span={1}>
                                    {dayjs(viewRecord.returnDate).format('DD/MM/YYYY')}
                                </Descriptions.Item>
                                <Descriptions.Item label="Return Amount" span={1}>
                                    <Tag color="red" style={{ fontSize: 14 }}>₹{Number(viewRecord.returnAmount).toLocaleString('en-IN', { minimumFractionDigits: 2 })}</Tag>
                                </Descriptions.Item>
                                <Descriptions.Item label="Returned Qty (KG)" span={1}>
                                    <Tag color="orange">{viewRecord.quantity} KG</Tag>
                                </Descriptions.Item>
                                <Descriptions.Item label={`Returned ${viewRecord.purchase?.unit === 'BOX' ? 'Box' : 'Bags'}`} span={1}>
                                    {viewRecord.bags ? (
                                        <Tag color={viewRecord.purchase?.unit === 'BOX' ? 'green' : 'blue'}>
                                            {viewRecord.bags} {viewRecord.purchase?.unit === 'BOX' ? 'BOX' : 'BAG'}
                                        </Tag>
                                    ) : '-'}
                                </Descriptions.Item>
                                <Descriptions.Item label="Reason" span={2}>
                                    {viewRecord.reason || '-'}
                                </Descriptions.Item>
                                <Descriptions.Item label="Remarks" span={2}>
                                    {viewRecord.remarks || '-'}
                                </Descriptions.Item>
                            </Descriptions>

                            <Descriptions
                                title="Purchase Lot Information"
                                bordered
                                column={2}
                                size="small"
                            >
                                <Descriptions.Item label="Supplier" span={1}>
                                    {viewRecord.purchase?.supplier?.name || '-'}
                                </Descriptions.Item>
                                <Descriptions.Item label="Vegetable / Item" span={1}>
                                    {viewRecord.purchase?.vegetable?.name || '-'}
                                </Descriptions.Item>
                                <Descriptions.Item label="Bill No" span={1}>
                                    {viewRecord.purchase?.billNo || '-'}
                                </Descriptions.Item>
                                <Descriptions.Item label="Lot No" span={1}>
                                    {viewRecord.purchase?.lotNo || '-'}
                                </Descriptions.Item>
                                <Descriptions.Item label="Purchase Date" span={1}>
                                    {viewRecord.purchase?.purchaseDate ? dayjs(viewRecord.purchase.purchaseDate).format('DD/MM/YYYY') : '-'}
                                </Descriptions.Item>
                                <Descriptions.Item label="Unit" span={1}>
                                    {viewRecord.purchase?.unit || '-'}
                                </Descriptions.Item>
                                <Descriptions.Item label="Total Qty" span={1}>
                                    {viewRecord.purchase?.quantity} KG
                                </Descriptions.Item>
                                <Descriptions.Item label="Remaining Qty (After Return)" span={1}>
                                    <Tag color="blue">{viewRecord.purchase?.remainingQuantity} KG</Tag>
                                </Descriptions.Item>
                                <Descriptions.Item label="Rate/Unit" span={1}>
                                    ₹{viewRecord.purchase?.ratePerUnit}
                                </Descriptions.Item>
                                <Descriptions.Item label="Cost/Unit" span={1}>
                                    ₹{viewRecord.purchase?.costPerUnit}
                                </Descriptions.Item>
                                <Descriptions.Item label="Grand Total" span={2}>
                                    ₹{Number(viewRecord.purchase?.grandTotal).toLocaleString('en-IN', { minimumFractionDigits: 2 })}
                                </Descriptions.Item>
                            </Descriptions>
                        </>
                    )}
                </Spin>
            </Modal>
        </AppContainer>
    );
};
