import React, { useEffect, useState } from "react";
import { Card, Input, Pagination, Table, Tag, Button, DatePicker, Select } from "antd";
import { useNavigate } from "react-router-dom";
import type { ColumnsType } from "antd/es/table";
import { API_Instance } from "@/api/axios.instance";
import API_Constants from "@/constants/api.constants";
import toast from "react-hot-toast";
import { getAxiosErrorMessage } from "@/utils/index.utils";
import dayjs from "dayjs";
import { useAuth } from "@/hooks/useAuth";
import { Role } from "@/constants/navLink.constants";
import {
    AlertCircle,
    Building2,
    Calendar,
    CheckCircle,
    Clock,
    CreditCard,
    IndianRupee,
    Mail,
    Search,
    User,
    Banknote,
    Percent,
    Download,
} from "lucide-react";
import { useDebounce } from "@/hooks/useDebounce";
import ROUTE_CONSTANTS from "@/constants/route.constants";

interface IUserBasic {
    name: string;
    email: string;
    phone: string;
}

interface IPayment {
    id: string;
    transactionId: string;
    receiptNo: string;
    user: IUserBasic;
    amount: number;
    taxableAmount: number;
    gstRate: number;
    gstAmount: number;
    cgstAmount: number;
    sgstAmount: number;
    igstAmount: number;
    gstType?: "CGST_SGST" | "IGST" | "EXEMPT" | "ZERO_RATED" | null;
    customerGstNumber?: string | null;
    method: string;
    offer: string;
    date: string;
    status: string;
    plan: string;
    institution: string;
    institutionEmail: string;
}

interface IPaymentSummary {
    totalTransactions: number;
    successfulPayments: number;
    pendingPayments: number;
    attentionPayments: number;
    institutionCount: number;
    totalCollected: number;
    totalTaxableCollected: number;
    totalGstCollected: number;
}

const paginationInitial = {
    page: 1,
    limit: 10,
    total: 0,
    totalPages: 0,
};

const paymentSummaryInitial: IPaymentSummary = {
    totalTransactions: 0,
    successfulPayments: 0,
    pendingPayments: 0,
    attentionPayments: 0,
    institutionCount: 0,
    totalCollected: 0,
    totalTaxableCollected: 0,
    totalGstCollected: 0,
};

const formatCurrency = (amount: number) =>
    new Intl.NumberFormat("en-IN", {
        style: "currency",
        currency: "INR",
        maximumFractionDigits: 2,
    }).format(amount || 0);

const renderTaxBreakup = (payment: IPayment) => {
    if (!payment.gstRate || !payment.gstAmount) {
        return <span className="text-xs text-slate-400">No GST</span>;
    }

    if (payment.gstType === "IGST") {
        return (
            <div className="flex flex-col text-xs leading-5">
                <span className="font-semibold text-slate-700">IGST {payment.gstRate}%</span>
                <span className="text-slate-500">{formatCurrency(payment.igstAmount || payment.gstAmount)}</span>
            </div>
        );
    }

    return (
        <div className="flex flex-col text-xs leading-5">
            <span className="font-semibold text-slate-700">CGST/SGST {payment.gstRate}%</span>
            <span className="text-slate-500">
                {formatCurrency(payment.cgstAmount)} + {formatCurrency(payment.sgstAmount)}
            </span>
        </div>
    );
};

const buildFallbackSummary = (
    records: IPayment[],
    totalTransactions: number,
): IPaymentSummary => {
    const institutionCount = new Set(
        records
            .map((payment) => payment.institution)
            .filter((institution) => institution && institution !== "N/A"),
    ).size;

    return {
        totalTransactions,
        successfulPayments: records.filter((payment) => payment.status === "SUCCESS").length,
        pendingPayments: records.filter((payment) => payment.status === "PENDING").length,
        attentionPayments: records.filter((payment) =>
            ["FAILED", "CANCELLED", "EXPIRED"].includes(payment.status),
        ).length,
        institutionCount,
        totalCollected: records
            .filter((payment) => payment.status === "SUCCESS")
            .reduce((sum, payment) => sum + Number(payment.amount || 0), 0),
        totalTaxableCollected: records
            .filter((payment) => payment.status === "SUCCESS")
            .reduce((sum, payment) => sum + Number(payment.taxableAmount || 0), 0),
        totalGstCollected: records
            .filter((payment) => payment.status === "SUCCESS")
            .reduce((sum, payment) => sum + Number(payment.gstAmount || 0), 0),
    };
};

const SummaryCard = ({
    title,
    value,
    subtitle,
    icon: Icon,
    color,
}: {
    title: string;
    value: string | number;
    subtitle: string;
    icon: React.ElementType;
    color: string;
}) => (
    <div className="bg-white border border-slate-200 rounded-xl p-4 shadow-sm">
        <div className="flex items-start justify-between gap-3">
            <div className="min-w-0">
                <p className="text-xs font-semibold uppercase tracking-wide text-slate-500">
                    {title}
                </p>
                <p className="mt-2 text-2xl font-bold text-slate-900 truncate">
                    {value}
                </p>
                <p className="mt-1 text-xs text-slate-500">{subtitle}</p>
            </div>
            <span className={`shrink-0 rounded-lg p-2.5 ${color}`}>
                <Icon size={20} />
            </span>
        </div>
    </div>
);

const PlatformPaymentReport: React.FC = () => {
    const navigate = useNavigate();
    const { user } = useAuth();
    const isAdmin = user?.role === Role.ADMIN;
    const [payments, setPayments] = useState<IPayment[]>([]);
    const [loading, setLoading] = useState(false);
    const [exportLoading, setExportLoading] = useState(false);
    const [pagination, setPagination] = useState(paginationInitial);
    const [summary, setSummary] = useState<IPaymentSummary>(paymentSummaryInitial);
    const [filters, setFilters] = useState({
        search: "",
        planType: undefined as string | undefined,
        status: undefined as string | undefined,
        gstType: undefined as string | undefined,
        institutionId: undefined as string | undefined,
        startDate: undefined as string | undefined,
        endDate: undefined as string | undefined,
    });
    const [subscriptions, setSubscriptions] = useState<any[]>([]);
    const [transactionStatuses, setTransactionStatuses] = useState<string[]>([]);
    const [institutes, setInstitutes] = useState<{ id: string; name: string }[]>([]);
    const [downloadingId, setDownloadingId] = useState<string | null>(null);

    const debouncedSearch = useDebounce(filters.search, 600);

    useEffect(() => {
        const fetchData = async () => {
            try {
                const [statusResult, instituteResult] = await Promise.allSettled([
                    API_Instance.get(`${API_Constants.payments}/statuses`),
                    API_Instance.get(API_Constants.institutionsList, {
                        params: { limit: 1000 },
                    }),
                ]);

                const statusRes = statusResult.status === "fulfilled" ? statusResult.value : null;
                const instituteRes = instituteResult.status === "fulfilled" ? instituteResult.value : null;

                const stats = statusRes?.data?.data ?? statusRes?.data;
                const insts = instituteRes?.data?.data ?? instituteRes?.data;

                setTransactionStatuses(Array.isArray(stats) ? stats : []);
                setInstitutes(Array.isArray(insts) ? insts : []);
            } catch (error) {
                console.error("Failed to load filter dropdown data:", error);
            }
        };
        fetchData();
    }, []);

    useEffect(() => {
        const fetchPlans = async () => {
            try {
                const params: any = { page: 1, limit: 1000, includeHidden: true };
                if (isAdmin && filters.institutionId) {
                    params.institutionId = filters.institutionId;
                }
                const res = await API_Instance.get(API_Constants.subscriptionPlans, { params });
                const subs = res.data?.data ?? res.data;
                setSubscriptions(Array.isArray(subs) ? subs : []);
            } catch (error) {
                console.error("Failed to load subscription plan options:", error);
            }
        };
        fetchPlans();
    }, [filters.institutionId, isAdmin]);

    const subscriptionOptions = React.useMemo(() => {
        return Array.from(
            new Map(
                subscriptions
                    .filter((p: any) => (p.isActive || p.planType.toLowerCase() === 'trial') && p.planName && p.planType)
                    .map((p: any) => [p.planType, p.planName])
            )
        ).map(([planType, planName]) => ({
            label: planName,
            value: planType,
        }));
    }, [subscriptions]);

    const statusOptions = React.useMemo(() => {
        return transactionStatuses
            .filter((stat: string) => !["REFUNDED", "PARTIAL_REFUND", "PROCESSING"].includes(stat))
            .map((stat: string) => ({
                label: stat.charAt(0).toUpperCase() + stat.slice(1).toLowerCase().replace('_', ' '),
                value: stat,
            }));
    }, [transactionStatuses]);

    const handleDownloadReceipt = async (id: string) => {
        try {

            setDownloadingId(id);

            const res = await API_Instance.get(
                `${API_Constants.payments}/${id}/download-receipt`,
                {
                    responseType: "blob",
                }
            );

            const blob = new Blob([res.data], {
                type: "application/pdf",
            });

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

            // OPEN PDF IN NEW TAB
            window.open(url, "_blank");

            // Optional cleanup
            setTimeout(() => {
                window.URL.revokeObjectURL(url);
            }, 1000);

        } catch (error) {

            toast.error("Failed to open receipt");

        } finally {

            setDownloadingId(null);
        }
    };

    const fetchPayments = async (page = 1, limit = 10, currentFilters = filters) => {
        setLoading(true);
        try {
            const params: any = {
                page,
                limit,
                search: currentFilters.search,
                institutionId: currentFilters.institutionId,
                planType: currentFilters.planType,
                status: currentFilters.status,
                gstType: currentFilters.gstType,
            };

            if (currentFilters.search) {
                const searchTrim = String(currentFilters.search).trim();
                if (searchTrim) {
                    const numericCandidate = searchTrim.replace(/[,₹\s]/g, "");
                    const numericMatch = /^(\d+(?:\.\d+)?)$/.test(numericCandidate);
                    if (numericMatch) {
                        const amountDecimal = Number(numericCandidate);
                        params.amount = amountDecimal;
                        params.amountInPaise = Math.round(amountDecimal * 100);
                    }
                }
            }

            if (currentFilters.startDate) {
                params.startDate = dayjs(currentFilters.startDate).startOf("day").toISOString();
            }
            if (currentFilters.endDate) {
                params.endDate = dayjs(currentFilters.endDate).endOf("day").toISOString();
            }

            const res = await API_Instance.get(API_Constants.payments, { params });
            setPayments(res.data.data);
            setPagination(res.data.meta);
            setSummary(
                res.data.meta?.summary ||
                buildFallbackSummary(res.data.data, res.data.meta?.total || 0),
            );
        } catch (error) {
            toast.error(getAxiosErrorMessage(error));
        } finally {
            setLoading(false);
        }
    };

    useEffect(() => {
        const updatedFilters = { ...filters, search: debouncedSearch };
        setPagination((prev) => ({ ...prev, page: 1 }));
        fetchPayments(1, pagination.limit, updatedFilters);
    }, [debouncedSearch, filters.planType, filters.status, filters.gstType, filters.institutionId, filters.startDate, filters.endDate]);


    const handleExportPDF = async () => {
        if (payments.length === 0) {
            toast.error("No data available to export.");
            return;
        }
        setExportLoading(true);
        const params: any = {
            search: filters.search || undefined,
            planType: filters.planType || undefined,
            status: filters.status || undefined,
            startDate: filters.startDate ? dayjs(filters.startDate).startOf("day").toISOString() : undefined,
            endDate: filters.endDate ? dayjs(filters.endDate).endOf("day").toISOString() : undefined,
        };

        if (filters.search) {
            const searchTrim = String(filters.search).trim();
            const numericCandidate = searchTrim.replace(/[,₹\s]/g, "");
            const numericMatch = /^(\d+(?:\.\d+)?)$/.test(numericCandidate);
            if (numericMatch) {
                const amountDecimal = Number(numericCandidate);
                params.amount = amountDecimal;
                params.amountInPaise = Math.round(amountDecimal * 100);
            }
        }

        const query = new URLSearchParams(Object.entries(params).filter(([_, v]) => v !== undefined) as any).toString();
        const url = `${API_Constants.payments}/payment-report-pdf?${query}`;
        try {
            const resp = await API_Instance.get(url, { responseType: 'blob' });
            const blobUrl = window.URL.createObjectURL(new Blob([resp.data], { type: 'application/pdf' }));
            const link = document.createElement('a');
            link.href = blobUrl;
            link.setAttribute('download', `Payments_Report_${dayjs().format('DD-MM-YYYY')}.pdf`);
            document.body.appendChild(link);
            link.click();
            link.remove();
            window.URL.revokeObjectURL(blobUrl);
        } catch (e) {
            toast.error('Failed to generate PDF');
        } finally {
            setExportLoading(false);
        }
    }


    return (
        <div className="flex flex-col gap-4 px-4 py-6">
            <div className="flex flex-col md:flex-row justify-between items-start md:items-center gap-4">
                <div>
                    <h2 className="text-2xl font-bold text-slate-800 flex items-center gap-2">
                        <CreditCard className="text-blue-600" /> Institution Payments Report
                    </h2>
                    <p className="text-slate-500 text-sm mt-1">
                        Admin view of institution billing, receipts, subscription plans, and payment status.
                    </p>
                </div>

                <Button
                    type="primary"
                    disabled={exportLoading}
                    onClick={handleExportPDF}
                    className="bg-blue-600 hover:bg-blue-700 hover:text-white flex items-center gap-2 rounded-lg font-medium"
                    icon={<Download size={16} />}
                    loading={exportLoading}
                >
                    {exportLoading ? "Generating PDF..." : "Export PDF"}
                </Button>
            </div>

            <div className="grid grid-cols-1 sm:grid-cols-2 xl:grid-cols-3 gap-4">
                <SummaryCard
                    title="Institutions"
                    value={summary.institutionCount.toLocaleString("en-IN")}
                    subtitle="Institutions with payments"
                    icon={Building2}
                    color="bg-indigo-50 text-indigo-600"
                />
                <SummaryCard
                    title="Total Payments"
                    value={summary.totalTransactions.toLocaleString("en-IN")}
                    subtitle="Transactions in current filters"
                    icon={CreditCard}
                    color="bg-blue-50 text-blue-600"
                />
                <SummaryCard
                    title="Status Overview"
                    value={`${summary.successfulPayments.toLocaleString("en-IN")} Success`}
                    subtitle={`Pending: ${summary.pendingPayments.toLocaleString("en-IN")} | Issues: ${summary.attentionPayments.toLocaleString("en-IN")}`}
                    icon={summary.attentionPayments > 0 ? AlertCircle : CheckCircle}
                    color={
                        summary.attentionPayments > 0
                            ? "bg-rose-50 text-rose-600"
                            : "bg-green-50 text-green-600"
                    }
                />
                <SummaryCard
                    title={filters.status ? `${filters.status.charAt(0).toUpperCase() + filters.status.slice(1).toLowerCase()} Amount` : "Collected"}
                    value={formatCurrency(summary.totalCollected)}
                    subtitle={filters.status ? `Total ${filters.status.toLowerCase()} payments (Incl. GST)` : "Total payments collected (Incl. GST)"}
                    icon={IndianRupee}
                    color="bg-emerald-50 text-emerald-600"
                />
                <SummaryCard
                    title="Taxable Amount"
                    value={formatCurrency(summary.totalTaxableCollected)}
                    subtitle={filters.status ? `Total ${filters.status.toLowerCase()} amount (Excl. GST)` : "Total amount collected (Excl. GST)"}
                    icon={Banknote}
                    color="bg-cyan-50 text-cyan-600"
                />
                <SummaryCard
                    title={filters.status ? "Total GST" : "Total GST Paid"}
                    value={formatCurrency(summary.totalGstCollected)}
                    subtitle={filters.status ? `GST amount from ${filters.status.toLowerCase()} payments` : "GST amount from collected payments"}
                    icon={Percent}
                    color="bg-violet-50 text-violet-600"
                />
            </div>

            <Card className="shadow-sm border border-slate-200 rounded-xl">
                <div className="flex flex-col lg:flex-row justify-between items-start gap-4 mb-4">
                    <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3 w-full">
                        <Input
                            placeholder="Search receipt, amount, mode..."
                            prefix={<Search size={16} className="text-slate-400" />}
                            allowClear
                            value={filters.search}
                            onChange={(e) => setFilters({ ...filters, search: e.target.value })}
                            className="w-full"
                        />
                        <Select
                            placeholder="Institution"
                            className="w-full"
                            allowClear
                            value={filters.institutionId}
                            onChange={(val) => setFilters({ ...filters, institutionId: val })}
                            options={institutes.map((inst) => ({ label: inst.name, value: inst.id }))}
                        />
                        <Select
                            placeholder="Subscription Plan"
                            className="w-full"
                            allowClear
                            value={filters.planType}
                            onChange={(val) => setFilters({ ...filters, planType: val })}
                            options={subscriptionOptions}
                        />
                        <Select
                            placeholder="Transaction Status"
                            className="w-full"
                            allowClear
                            value={filters.status}
                            onChange={(val) => setFilters({ ...filters, status: val })}
                            options={statusOptions}
                        />
                        <Select
                            placeholder="GST Type"
                            className="w-full"
                            allowClear
                            value={filters.gstType}
                            onChange={(val) => setFilters({ ...filters, gstType: val })}
                            options={[
                                { label: "IGST (Inter-State)", value: "IGST" },
                                { label: "CGST/SGST (Intra-State)", value: "CGST_SGST" },
                                { label: "No GST", value: "NO_GST" },
                            ]}
                        />
                        <div className="flex gap-2 w-full">
                            <DatePicker.RangePicker
                                value={filters.startDate && filters.endDate ? [dayjs(filters.startDate), dayjs(filters.endDate)] : null}
                                disabledDate={(current) => {
                                    return current && current > dayjs().endOf("day");
                                }}
                                onChange={(dates) => {
                                    setFilters({
                                        ...filters,
                                        startDate: dates && dates[0] ? dates[0].toISOString() : undefined,
                                        endDate: dates && dates[1] ? dates[1].toISOString() : undefined,
                                    });
                                }}
                                className="flex-1"
                            />
                            {(filters.search || filters.planType || filters.status || filters.gstType || filters.institutionId || filters.startDate) && (
                                <Button
                                    onClick={() => setFilters({
                                        search: "",
                                        planType: undefined,
                                        status: undefined,
                                        gstType: undefined,
                                        institutionId: undefined,
                                        startDate: undefined,
                                        endDate: undefined,
                                    })}
                                >
                                    Clear
                                </Button>
                            )}
                        </div>
                    </div>
                    <div className="text-slate-500 text-sm whitespace-nowrap mt-4 lg:mt-0">
                        Matching payments:{" "}
                        <span className="font-semibold text-slate-800">
                            {pagination.total}
                        </span>
                    </div>
                </div>

                <Table
                    columns={[
                        {
                            title: "Institution",
                            key: "institution",
                            width: 250,
                            render: (_, record) => (
                                <div className="flex flex-col gap-1">
                                    <div className="flex items-center gap-2">
                                        <User size={14} className="text-blue-500" />
                                        <span className="font-semibold text-slate-700">
                                            {record.institution}
                                        </span>
                                    </div>
                                    <div className="flex items-center gap-2 text-xs text-slate-500">
                                        <Mail size={12} /> {record.institutionEmail}
                                    </div>

                                </div>
                            ),
                        },
                        {
                            title: "Receipt Info",
                            key: "receiptNo",
                            render: (_, record) => (
                                <div className="flex flex-col">
                                    <span className="font-medium text-slate-700">
                                        Receipt: {record.receiptNo || "N/A"}
                                    </span>
                                    <span className="text-xs text-slate-500 uppercase">
                                        Payment Mode: {record.method || "N/A"}
                                    </span>
                                </div>
                            ),
                        },
                        {
                            title: "Payment Amount",
                            dataIndex: "amount",
                            key: "amount",
                            render: (amount) => (
                                <span className="font-semibold text-green-600">
                                    {formatCurrency(amount)}
                                </span>
                            ),
                        },
                        {
                            title: "Tax Details",
                            key: "tax",
                            width: 170,
                            render: (_, record) => (
                                <div className="flex flex-col gap-1">
                                    <span className="text-xs text-slate-500">
                                        Taxable: {formatCurrency(record.taxableAmount || record.amount)}
                                    </span>
                                    {renderTaxBreakup(record)}
                                </div>
                            ),
                        },
                        {
                            title: "Subscription Plan",
                            dataIndex: "plan",
                            key: "plan",
                            render: (plan) => (
                                <Tag color="blue" className="uppercase">
                                    {plan}
                                </Tag>
                            ),
                        },
                        {
                            title: "Date",
                            dataIndex: "date",
                            key: "date",
                            render: (date) => (
                                <div className="flex items-center gap-1 text-slate-500">
                                    <Calendar size={14} />
                                    <span>{dayjs(date).format("DD MMM YYYY, hh:mm A")}</span>
                                </div>
                            ),
                        },
                        {
                            title: "Status",
                            dataIndex: "status",
                            key: "status",
                            render: (status: string) => {
                                const statusConfig: Record<string, { color: string; label: string }> = {
                                    SUCCESS: { color: "success", label: "Success" },
                                    PENDING: { color: "processing", label: "Pending" },
                                    FAILED: { color: "error", label: "Failed" },
                                    CANCELLED: { color: "error", label: "Cancelled" },
                                    EXPIRED: { color: "warning", label: "Expired" },
                                    REFUNDED: { color: "magenta", label: "Refunded" },
                                    PARTIAL_REFUND: { color: "volcano", label: "Partial Refund" },
                                };
                                const config = statusConfig[status] || { color: "default", label: status };
                                return <Tag color={config.color}>{config.label}</Tag>;
                            },
                        },
                        {
                            title: "Actions",
                            key: "action",
                            width: 150,
                            render: (_, record) => (
                                <div className="flex gap-2">
                                    <Button
                                        type="link"
                                        size="small"
                                        className="text-blue-600 hover:text-blue-700 font-semibold p-0"
                                        onClick={() => navigate(ROUTE_CONSTANTS.PaymentDetail.replace(":transactionId", record.id))}
                                    >
                                        View
                                    </Button>
                                    {record.status === 'SUCCESS' && (
                                        <>
                                            <span className="text-slate-300">|</span>
                                            <Button
                                                type="link"
                                                size="small"
                                                className="text-emerald-600 hover:text-emerald-700 font-semibold p-0"
                                                onClick={() => handleDownloadReceipt(record.id)}
                                                loading={downloadingId === record.id}
                                            >
                                                Receipt
                                            </Button>
                                        </>
                                    )}
                                </div>
                            ),
                        },
                    ]}
                    dataSource={payments}
                    loading={loading}
                    rowKey="id"
                    pagination={false}
                    scroll={{ x: 1000 }}
                    className="border border-slate-100 rounded-lg overflow-hidden"
                    locale={{
                        emptyText: "No institution payments found",
                    }}
                />

                <div className="flex justify-end mt-4">
                    <Pagination
                        current={pagination.page}
                        total={pagination.total}
                        pageSize={pagination.limit}
                        onChange={(page, pageSize) => {
                            setPagination((prev) => ({ ...prev, page, limit: pageSize }));
                            fetchPayments(page, pageSize, { ...filters, search: debouncedSearch });
                        }}
                        showSizeChanger
                        showTotal={(total) => `Total ${total} payments`}
                    />
                </div>
            </Card>
        </div>
    );
};

export default PlatformPaymentReport;
