import { useEffect, useState } from 'react';
import {
    Button,
    DatePicker,
    Input,
    Select,
    Space,
    Table,
    Tag,
    message,
    Spin,
    Row,
    Col,
} from 'antd';
import {
    DownloadOutlined,
    FilePdfOutlined,
    RedoOutlined,
} from '@ant-design/icons';
import dayjs, { Dayjs } from 'dayjs';
import { AppContainer } from '../../../components/AppContainer';
import jwtAxios from '../../../api/axiosInstance';
import { ENDPOINTS } from '../../../api/endpoints';
import SummaryCard from '../../../components/SummaryCard';

const ENTITY_LABEL = 'Whole Sale - Customer Sales Report';
const ENTITY_ENDPOINT = ENDPOINTS.SALES_REPORT;
const WALKIN_FILTER_VALUE = 'walkin';

interface NamedOption {
    id: string;
    name: string;
    outstandingBalance?: string;
}

interface SaleMeta {
    customers: NamedOption[];
    vegetables: NamedOption[];
}

const { RangePicker } = DatePicker;

export const CustomerSalesReport = () => {
    const [searchText, setSearchText] = useState('');
    const [dateRange, setDateRange] = useState<[Dayjs, Dayjs] | null>(null);
    const [selectedCustomer, setSelectedCustomer] = useState<string | undefined>(undefined);
    const [data, setData] = useState<any[]>([]);
    const [loading, setLoading] = useState<boolean>(false);
    const [exportLoading, setExportLoading] = useState<boolean>(false);
    const [exportPdfLoading, setExportPdfLoading] = useState<boolean>(false);
    const [meta, setMeta] = useState<SaleMeta>({ customers: [], vegetables: [] });
    const [sum, setSum] = useState({ grand_total: 0, balance_amount: 0, outstanding_balance: 0 });

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

    const fetchMeta = async () => {
        try {
            const res = await jwtAxios.get(ENDPOINTS.SALES_META);
            setMeta(res.data?.result || { customers: [], vegetables: [] });
        } catch (err: any) {
            message.error(err.response?.data?.message || 'Failed to fetch meta');
        }
    };

    const handleReset = () => {
        setSearchText('');
        setDateRange(null);
        setSelectedCustomer(undefined);
        fetchData(1, pagination.pageSize, '', null, null);
    };

    const fetchData = async (
        page: number = pagination.current,
        limit: number = pagination.pageSize,
        search: string = searchText,
        range: [Dayjs, Dayjs] | null = dateRange,
        customerId: string | null | undefined = selectedCustomer
    ) => {
        setLoading(true);
        try {
            let url = `${ENTITY_ENDPOINT}?page=${page}&limit=${limit}&search=${search}`;
            if (range) {
                url += `&dateFrom=${range[0].format('YYYY-MM-DD')}&dateTo=${range[1].format('YYYY-MM-DD')}`;
            }
            if (customerId) {
                if (customerId === WALKIN_FILTER_VALUE) {
                    url += `&isWalkIn=true`;
                } else {
                    url += `&customerId=${customerId}`;
                }
            }
            const res = await jwtAxios.get(url);
            const records = res.data?.result?.data || [];
            const metaInfo = res.data?.result?.meta || {};
            const sumInfo = res.data?.result?.sum || {};
            setData(records.map((item: any) => ({ key: item.id, ...item })));
            setPagination((prev) => ({
                ...prev,
                current: metaInfo.page ?? page,
                pageSize: metaInfo.limit ?? limit,
                total: metaInfo.total ?? prev.total,
                totalPages: metaInfo.totalPages ?? prev.totalPages,
            }));
            setSum({
                grand_total: Number(sumInfo.grand_total ?? 0),
                balance_amount: Number(sumInfo.balance_amount ?? 0),
                outstanding_balance: Number(sumInfo.outstanding_balance ?? 0),
            });
        } catch (err: any) {
            message.error(err.response?.data?.message || 'Failed to fetch data');
        } finally {
            setLoading(false);
        }
    };

    useEffect(() => {
        fetchMeta();
        fetchData(1, pagination.pageSize, '');
    }, []);

    const handleSearch = (value: string) => {
        fetchData(1, pagination.pageSize, value, dateRange, selectedCustomer);
    };

    const handleDateRangeChange = (values: any) => {
        const range = values ? (values as [Dayjs, Dayjs]) : null;
        setDateRange(range);
        fetchData(1, pagination.pageSize, searchText, range, selectedCustomer);
    };

    const handleCustomerChange = (value: string | undefined) => {
        setSelectedCustomer(value);
        fetchData(1, pagination.pageSize, searchText, dateRange, value ?? null);
    };

    const handleExport = async () => {
        if (!data || data.length === 0) {
            message.warning('No data available to export');
            return;
        }
        setExportLoading(true);
        try {
            // Build query string with all currently-active filters (no page/limit)
            const params = new URLSearchParams();
            if (searchText) params.set('search', searchText);
            if (dateRange) {
                params.set('dateFrom', dateRange[0].format('YYYY-MM-DD'));
                params.set('dateTo', dateRange[1].format('YYYY-MM-DD'));
            }
            if (selectedCustomer) {
                if (selectedCustomer === WALKIN_FILTER_VALUE) {
                    params.set('isWalkIn', 'true');
                } else {
                    params.set('customerId', selectedCustomer);
                }
            }

            const url = `${ENDPOINTS.SALES_EXPORT}${params.toString() ? '?' + params.toString() : ''}`;

            const response = await jwtAxios.get(url, { responseType: 'blob' });

            const disposition = response.headers['content-disposition'];
            let fileName = 'sales-report.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('Sales report exported successfully');
        } catch {
            message.error('Failed to export sales report. Please try again.');
        } finally {
            setExportLoading(false);
        }
    };

    const handleExportPdf = async () => {
        if (!data || data.length === 0) {
            message.warning('No data available to export');
            return;
        }
        setExportPdfLoading(true);
        try {
            const params = new URLSearchParams();
            if (searchText) params.set('search', searchText);
            if (dateRange) {
                params.set('dateFrom', dateRange[0].format('YYYY-MM-DD'));
                params.set('dateTo', dateRange[1].format('YYYY-MM-DD'));
            }
            if (selectedCustomer) {
                if (selectedCustomer === WALKIN_FILTER_VALUE) {
                    params.set('isWalkIn', 'true');
                } else {
                    params.set('customerId', selectedCustomer);
                }
            }

            const url = `${ENDPOINTS.SALES_EXPORT_PDF}${params.toString() ? '?' + params.toString() : ''}`;

            const response = await jwtAxios.get(url, { responseType: 'blob' });

            const disposition = response.headers['content-disposition'];
            let fileName = `sales-report-${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('Sales report PDF exported successfully');
        } catch {
            message.error('Failed to export sales report PDF. Please try again.');
        } finally {
            setExportPdfLoading(false);
        }
    };

    const columns = [
        {
            title: 'S.No',
            dataIndex: 'sNo',
            render: (_: number, __: any, index: number) => index + 1,
        },
        { title: 'Invoice No', dataIndex: 'invoiceNo' },
        {
            title: 'Date',
            dataIndex: 'invoiceDate',
            render: (date: string) => dayjs(date).format('DD/MM/YYYY'),
        },
        {
            title: 'Customer',
            dataIndex: 'customer',
            render: (customer: any, record: any) => customer?.name || (record.walkInName ? `${record.walkInName} (Walk-in)` : '-'),
        },
        {
            title: 'Grand Total',
            dataIndex: 'grandTotal',
            render: (val: string) => Number(val).toFixed(2),
        },
        {
            title: 'Balance Amount',
            dataIndex: 'balanceAmount',
            render: (val: string) => Number(val).toFixed(2),
        }
    ];

    return (
        <div>
            <Spin spinning={loading}>
                <AppContainer
                    title={`${ENTITY_LABEL}`}
                    headerAction={
                        <Space wrap>
                            <Button
                                icon={<DownloadOutlined />}
                                style={{ color: '#52c41a', borderColor: '#52c41a' }}
                                loading={exportLoading}
                                onClick={handleExport}
                            >
                                Export Excel
                            </Button>
                            <Button
                                icon={<FilePdfOutlined />}
                                danger
                                loading={exportPdfLoading}
                                onClick={handleExportPdf}
                            >
                                Export PDF
                            </Button>
                        </Space>
                    }
                >
                    {/* Summary Cards */}
                    <Row gutter={[16, 16]} style={{ marginBottom: 20 }}>
                        <Col xs={24} sm={12} md={8}>
                            <SummaryCard
                                label="Grand Total"
                                value={sum.grand_total}
                                color="#1677ff"
                                icon={<span style={{ fontSize: 20 }}>📈</span>}
                            />
                        </Col>
                        <Col xs={24} sm={12} md={8}>
                            <SummaryCard
                                label="Balance Amount"
                                value={sum.balance_amount}
                                color="#f522ab"
                                icon={<span style={{ fontSize: 20 }}>💰</span>}
                            />
                        </Col>
                        <Col xs={24} sm={12} md={8}>
                            <SummaryCard
                                label="Outstanding Balance"
                                value={sum.outstanding_balance}
                                color="#f5222d"
                                icon={<span style={{ fontSize: 20 }}>💰</span>}
                            />
                        </Col>
                    </Row>
                    <div className="flex justify-between items-center mb-4 pb-4 border-b border-gray-200">
                        <Space>
                            <RangePicker value={dateRange as any} onChange={handleDateRangeChange} />
                            <Select
                                placeholder="Select Customer"
                                allowClear
                                showSearch
                                value={selectedCustomer}
                                onChange={handleCustomerChange}
                                style={{ width: 220 }}
                                optionFilterProp="label"
                                filterOption={(input, option) =>
                                    (option?.label as string)
                                        ?.toLowerCase()
                                        .includes(input.toLowerCase())
                                }
                                options={[
                                    { label: 'Walk-in / Counter Sales', value: WALKIN_FILTER_VALUE },
                                    ...meta.customers.map((c) => ({
                                        label: c.name,
                                        value: c.id,
                                    })),
                                ]}
                            />
                            <Input.Search
                                placeholder="Search..."
                                value={searchText}
                                onChange={(e) => setSearchText(e.target.value)}
                                onSearch={handleSearch}
                                allowClear
                                style={{ width: 200 }}
                            />
                            <Button type="default" icon={<RedoOutlined />} onClick={handleReset}>
                                Reset
                            </Button>
                        </Space>
                    </div>
                    <Table
                        columns={columns}
                        dataSource={data}
                        loading={loading}
                        rowKey="id"
                        pagination={{
                            ...pagination,
                            onChange: (page, pageSize) => fetchData(page, pageSize),
                        }}
                    />
                    <div className="text-center mt-2">
                        <Tag color="cyan">
                            Page {pagination.current} of {pagination.totalPages}
                        </Tag>
                    </div>
                </AppContainer>
            </Spin>
        </div>
    );
};