import { useEffect, useState } from 'react';
import {
    Button,
    DatePicker,
    Select,
    Space,
    Table,
    Tag,
    message,
    Spin,
    Row,
    Col,
    Typography,
} from 'antd';
import {
    DownloadOutlined,
    RedoOutlined,
    WalletOutlined,
    RiseOutlined,
    FallOutlined,
    FilePdfOutlined,
} 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 { RangePicker } = DatePicker;
const { Text } = Typography;

interface Customer {
    id: string;
    name: string;
}

interface LedgerRow {
    key: string;
    date: string | null;
    voucherNo: string;
    customerName: string;
    transactionType: string;
    description: string;
    debit: number;
    credit: number;
    runningBalance: number;
}

interface LedgerSummary {
    openingBalance: number;
    totalDebit: number;
    totalCredit: number;
    closingBalance: number;
}

const TYPE_COLORS: Record<string, string> = {
    'Opening Balance': 'purple',
    'Sale': 'blue',
    'Receipt': 'green',
    'Sales Return': 'orange',
};

const CustomerLedger = () => {
    const [dateRange, setDateRange] = useState<[Dayjs, Dayjs] | null>(null);
    const [selectedCustomer, setSelectedCustomer] = useState<string | undefined>(undefined);
    const [customers, setCustomers] = useState<Customer[]>([]);
    const [data, setData] = useState<LedgerRow[]>([]);
    const [loading, setLoading] = useState(false);
    const [summary, setSummary] = useState<LedgerSummary>({
        openingBalance: 0,
        totalDebit: 0,
        totalCredit: 0,
        closingBalance: 0,
    });

    const fetchMeta = async () => {
        try {
            const res = await jwtAxios.get(ENDPOINTS.CUSTOMER_LEDGER_META);
            setCustomers(res.data?.result?.customers || []);
        } catch (err: any) {
            message.error(err.response?.data?.message || 'Failed to load customers');
        }
    };

    const fetchData = async (
        range: [Dayjs, Dayjs] | null = dateRange,
        customerId: string | undefined = selectedCustomer
    ) => {
        setLoading(true);
        try {
            const params = new URLSearchParams();
            if (range) {
                params.set('dateFrom', range[0].format('YYYY-MM-DD'));
                params.set('dateTo', range[1].format('YYYY-MM-DD'));
            }
            if (customerId) params.set('customerId', customerId);

            const res = await jwtAxios.get(`${ENDPOINTS.CUSTOMER_LEDGER}?${params.toString()}`);
            const rows: LedgerRow[] = (res.data?.result?.data || []).map((r: any, i: number) => ({
                key: `${i}`,
                date: r.date,
                voucherNo: r.voucherNo,
                customerName: r.customerName,
                transactionType: r.transactionType,
                description: r.description,
                debit: Number(r.debit ?? 0),
                credit: Number(r.credit ?? 0),
                runningBalance: Number(r.runningBalance ?? 0),
            }));
            setData(rows);

            const s = res.data?.result?.summary || {};
            setSummary({
                openingBalance: Number(s.openingBalance ?? 0),
                totalDebit: Number(s.totalDebit ?? 0),
                totalCredit: Number(s.totalCredit ?? 0),
                closingBalance: Number(s.closingBalance ?? 0),
            });
        } catch (err: any) {
            message.error(err.response?.data?.message || 'Failed to fetch ledger data');
        } finally {
            setLoading(false);
        }
    };

    useEffect(() => {
        fetchMeta();
        // Default to current month
        const from = dayjs().startOf('month');
        const to = dayjs().endOf('month');
        const range: [Dayjs, Dayjs] = [from, to];
        setDateRange(range);
        fetchData(range, undefined);
    }, []);

    const handleReset = () => {
        const from = dayjs().startOf('month');
        const to = dayjs().endOf('month');
        const range: [Dayjs, Dayjs] = [from, to];
        setDateRange(range);
        setSelectedCustomer(undefined);
        fetchData(range, undefined);
    };

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

    const handleCustomerChange = (value: string | undefined) => {
        setSelectedCustomer(value);
        fetchData(dateRange, value ?? undefined);
    };

    const handleExport = async () => {
        await handleExportFile('excel');
    };

    const handleExportPdf = async () => {
        await handleExportFile('pdf');
    };

    const handleExportFile = async (format: 'excel' | 'pdf') => {
        if (!data || data.length === 0) {
            message.warning('No data available to export');
            return;
        }
        setLoading(true);
        try {
            const params = new URLSearchParams();
            if (dateRange) {
                params.set('dateFrom', dateRange[0].format('YYYY-MM-DD'));
                params.set('dateTo', dateRange[1].format('YYYY-MM-DD'));
            }
            if (selectedCustomer) params.set('customerId', selectedCustomer);

            const endpoint = format === 'pdf'
                ? ENDPOINTS.CUSTOMER_LEDGER_EXPORT_PDF
                : ENDPOINTS.CUSTOMER_LEDGER_EXPORT;
            const url = `${endpoint}?${params.toString()}`;
            const response = await jwtAxios.get(url, { responseType: 'blob' });

            const disposition = response.headers['content-disposition'];
            let fileName = format === 'pdf' ? 'customer-ledger.pdf' : 'customer-ledger.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: format === 'pdf'
                    ? 'application/pdf'
                    : '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(`Customer ledger ${format.toUpperCase()} exported successfully`);
        } catch {
            message.error(`Failed to export ledger ${format.toUpperCase()}. Please try again.`);
        } finally {
            setLoading(false);
        }
    };

    const columns = [
        {
            title: 'Date',
            dataIndex: 'date',
            width: 110,
            render: (val: string | null) => val ? dayjs(val).format('DD/MM/YYYY') : <Text type="secondary">—</Text>,
        },
        {
            title: 'Voucher No',
            dataIndex: 'voucherNo',
            width: 140,
            render: (val: string) => <Text strong>{val}</Text>,
        },
        {
            title: 'Customer Name',
            dataIndex: 'customerName',
            width: 180,
            render: (val: string) => val || <Text type="secondary">—</Text>,
        },
        {
            title: 'Type',
            dataIndex: 'transactionType',
            width: 130,
            render: (type: string) => (
                <Tag color={TYPE_COLORS[type] ?? 'default'}>{type}</Tag>
            ),
        },
        {
            title: 'Description',
            dataIndex: 'description',
            ellipsis: true,
        },
        {
            title: 'Debit (₹)',
            dataIndex: 'debit',
            width: 120,
            align: 'right' as const,
            render: (val: number) => val > 0
                ? <Text style={{ color: '#d46b08', fontWeight: 600 }}>{val.toLocaleString('en-IN', { minimumFractionDigits: 2 })}</Text>
                : <Text type="secondary">—</Text>,
        },
        {
            title: 'Credit (₹)',
            dataIndex: 'credit',
            width: 120,
            align: 'right' as const,
            render: (val: number) => val > 0
                ? <Text style={{ color: '#389e0d', fontWeight: 600 }}>{val.toLocaleString('en-IN', { minimumFractionDigits: 2 })}</Text>
                : <Text type="secondary">—</Text>,
        },
        {
            title: 'Balance (₹)',
            dataIndex: 'runningBalance',
            width: 140,
            align: 'right' as const,
            render: (val: number) => (
                <Text strong style={{ color: val >= 0 ? '#1677ff' : '#cf1322' }}>
                    {Math.abs(val).toLocaleString('en-IN', { minimumFractionDigits: 2 })}
                    {' '}<Text type="secondary" style={{ fontSize: 11 }}>{val >= 0 ? 'Dr' : 'Cr'}</Text>
                </Text>
            ),
        },
    ];

    return (
        <div>
            <Spin spinning={loading}>
                <AppContainer
                    title="Customer Ledger"
                    headerAction={
                        <Space>
                            <Button
                                icon={<DownloadOutlined />}
                                style={{ color: '#52c41a', borderColor: '#52c41a' }}
                                loading={loading}
                                onClick={handleExport}
                            >
                                Export Excel
                            </Button>
                            <Button
                                icon={<FilePdfOutlined />}
                                style={{ color: '#cf1322', borderColor: '#cf1322' }}
                                loading={loading}
                                onClick={handleExportPdf}
                            >
                                Export PDF
                            </Button>
                        </Space>
                    }
                >
                    {/* Summary Cards */}
                    <Row gutter={[16, 16]} style={{ marginBottom: 20 }}>
                        <Col xs={24} sm={12} lg={6}>
                            <SummaryCard
                                label="Opening Balance"
                                value={summary.openingBalance}
                                color="#7c3aed"
                                icon={<WalletOutlined style={{ fontSize: 20 }} />}
                            />
                        </Col>
                        <Col xs={24} sm={12} lg={6}>
                            <SummaryCard
                                label="Total Debit"
                                value={summary.totalDebit}
                                color="#d46b08"
                                icon={<RiseOutlined style={{ fontSize: 20 }} />}
                            />
                        </Col>
                        <Col xs={24} sm={12} lg={6}>
                            <SummaryCard
                                label="Total Credit"
                                value={summary.totalCredit}
                                color="#389e0d"
                                icon={<FallOutlined style={{ fontSize: 20 }} />}
                            />
                        </Col>
                        <Col xs={24} sm={12} lg={6}>
                            <SummaryCard
                                label="Closing Balance"
                                value={summary.closingBalance}
                                color={summary.closingBalance >= 0 ? '#1677ff' : '#cf1322'}
                                icon={<FallOutlined style={{ fontSize: 20 }} />}
                            />
                        </Col>
                    </Row>

                    {/* Filters */}
                    <div style={{ marginBottom: 16 }}>
                        <Space wrap>
                            <RangePicker value={dateRange as any} onChange={handleDateRangeChange} />
                            <Select
                                placeholder="All Customers"
                                allowClear
                                showSearch
                                value={selectedCustomer}
                                onChange={handleCustomerChange}
                                style={{ width: 220 }}
                                optionFilterProp="label"
                                filterOption={(input, option) =>
                                    (option?.label as string)?.toLowerCase().includes(input.toLowerCase())
                                }
                                options={customers.map((c) => ({ label: c.name, value: String(c.id) }))}
                            />
                            <Button type="default" icon={<RedoOutlined />} onClick={handleReset}>
                                Reset
                            </Button>
                        </Space>
                    </div>

                    {/* Ledger Table */}
                    <Table
                        columns={columns}
                        dataSource={data}
                        loading={loading}
                        rowKey="key"
                        // pagination={ showTotal: (t) => `${t} transactions` }}
                        pagination={false}
                        rowClassName={(row: LedgerRow) => {
                            if (row.transactionType === 'Opening Balance') return 'ledger-row-opening';
                            if (row.debit > 0) return 'ledger-row-debit';
                            if (row.credit > 0) return 'ledger-row-credit';
                            return '';
                        }}
                        scroll={{ x: 900 }}
                        size="small"
                        summary={() => (
                            <Table.Summary fixed>
                                <Table.Summary.Row>
                                    <Table.Summary.Cell index={0} colSpan={5}>
                                        <Text strong>Closing Balance</Text>
                                    </Table.Summary.Cell>
                                    <Table.Summary.Cell index={5} align="right">
                                        <Text strong style={{ color: '#d46b08' }}>
                                            {summary.totalDebit.toLocaleString('en-IN', { minimumFractionDigits: 2 })}
                                        </Text>
                                    </Table.Summary.Cell>
                                    <Table.Summary.Cell index={6} align="right">
                                        <Text strong style={{ color: '#389e0d' }}>
                                            {summary.totalCredit.toLocaleString('en-IN', { minimumFractionDigits: 2 })}
                                        </Text>
                                    </Table.Summary.Cell>
                                    <Table.Summary.Cell index={7} align="right">
                                        <Text strong style={{ color: summary.closingBalance >= 0 ? '#1677ff' : '#cf1322' }}>
                                            {Math.abs(summary.closingBalance).toLocaleString('en-IN', { minimumFractionDigits: 2 })}
                                            {' '}<Text type="secondary" style={{ fontSize: 11 }}>{summary.closingBalance >= 0 ? 'Dr' : 'Cr'}</Text>
                                        </Text>
                                    </Table.Summary.Cell>
                                </Table.Summary.Row>
                            </Table.Summary>
                        )}
                    />
                </AppContainer>
            </Spin>

            <style>{`
                .ledger-row-debit td { background-color: #fff9f0 !important; }
                .ledger-row-credit td { background-color: #f6ffed !important; }
                .ledger-row-opening td { background-color: #f5f3ff !important; }
            `}</style>
        </div>
    );
};

export default CustomerLedger;
