import toast from "react-hot-toast";
import { UploadCloud } from "lucide-react";
import Modal from "@/components/shared/Modal";
import React, { useState, useMemo } from "react";
import { API_Instance } from "@/api/axios.instance";
import API_Constants from "@/constants/api.constants";
import { getAxiosErrorMessage } from "@/utils/index.utils";
import type { UploadFile } from "antd/es/upload/interface";
import { Table, Upload, Button, Tag, Pagination } from "antd";
import { UploadOutlined, CheckCircleOutlined, ExclamationCircleOutlined } from "@ant-design/icons";

interface BulkUploadModalProps {
    isOpen: boolean;
    onClose: () => void;
    onUploadSuccess: () => Promise<void>;
}

interface RowValidationResult {
    key: string;
    index: number;
    firstName: string;
    lastName: string;
    email: string;
    phone: string;
    exam: string;
    examName?: string;
    examsId?: string;
    language: string;
    referralCode?: string;
    referralId?: string;
    isValid: boolean;
    errors: string[];
}

export const BulkUploadModal: React.FC<BulkUploadModalProps> = ({
    isOpen,
    onClose,
    onUploadSuccess,
}) => {
    const [fileList, setFileList] = useState<UploadFile[]>([]);
    const [previewData, setPreviewData] = useState<RowValidationResult[]>([]);
    const [bulkStep, setBulkStep] = useState(0);
    const [isLoading, setIsLoading] = useState<boolean>(false);

    const [page, setPage] = useState(1);
    const [pageSize, setPageSize] = useState(5);

    const paginatedData = useMemo(() => {
        const start = (page - 1) * pageSize;
        return previewData.slice(start, start + pageSize);
    }, [previewData, page, pageSize]);

    const handleBulkUploadPreview = async () => {
        if (fileList.length === 0) {
            toast.error("Please select a file to preview.");
            return;
        }

        setIsLoading(true);
        try {
            const formData = new FormData();
            const fileObj = (fileList[0] as UploadFile).originFileObj || fileList[0];
            formData.append("file", fileObj as Blob);

            const response = await API_Instance.post(
                `${API_Constants.students}/preview-bulk`,
                formData,
                { headers: { "Content-Type": "multipart/form-data" } },
            );

            const rows = response.data?.data as unknown;
            const parsedRows = Array.isArray(rows) ? rows : [];
            const mappedRows: RowValidationResult[] = parsedRows.map((row, index) => {
                const previewRow = row as Record<string, unknown>;
                return {
                    key: `row-${index}`,
                    index: index + 1,
                    firstName: String(previewRow.firstName ?? ""),
                    lastName: String(previewRow.lastName ?? ""),
                    email: String(previewRow.email ?? ""),
                    phone: String(previewRow.phone ?? ""),
                    exam: String(previewRow.examName ?? previewRow.exam ?? ""),
                    examName: String(previewRow.examName ?? previewRow.exam ?? ""),
                    examsId: typeof previewRow.examsId === "string" ? previewRow.examsId : undefined,
                    language: String(previewRow.language ?? ""),
                    referralCode: String(previewRow.referralCode ?? ""),
                    referralId: typeof previewRow.referralId === "string" ? previewRow.referralId : undefined,
                    isValid: Boolean(previewRow.isValid),
                    errors: Array.isArray(previewRow.errors)
                        ? (previewRow.errors as string[])
                        : [],
                };
            });

            setPreviewData(mappedRows);
            setPage(1);
            setPageSize(5);
            setBulkStep(1);
            toast.success("Please review the data before importing.");
        } catch (err) {
            toast.error(getAxiosErrorMessage(err));
        } finally {
            setIsLoading(false);
        }
    };

    const handleConfirmUpload = async () => {
        if (!canImportAll) {
            toast.error("All uploaded rows must be valid before import.");
            return;
        }

        const validRows = previewData.filter((r) => r.isValid);
        if (validRows.length === 0) {
            toast.error("No valid student rows found to import.");
            return;
        }

        setIsLoading(true);
        try {
            await API_Instance.post(
                `${API_Constants.students}/confirm-bulk`,
                { students: validRows },
            );
            toast.success(`Successfully imported ${validRows.length} students. Verification mail has been sent to their email.`);
            await onUploadSuccess();
            handleCloseAndCleanup();
        } catch (error) {
            toast.error(getAxiosErrorMessage(error));
        } finally {
            setIsLoading(false);
        }
    };

    const handleCloseAndCleanup = () => {
        setFileList([]);
        setPreviewData([]);
        setBulkStep(0);
        setPage(1);
        setPageSize(5);
        onClose();
    };

    const handleRemove = () => {
        setFileList([]);
        setPreviewData([]);
        setBulkStep(0);
        setPage(1);
        setPageSize(5);
    };

    const validCount = previewData.filter((row) => row.isValid).length;
    const invalidCount = previewData.filter((row) => !row.isValid).length;
    const totalCount = previewData.length;
    const canImportAll = totalCount > 0 && invalidCount === 0;

    return (
        <Modal
            isOpen={isOpen}
            onClose={handleCloseAndCleanup}
            title="Student Bulk Upload"
            className={
                bulkStep === 1
                    ? "w-full max-w-[1280px] xl:max-w-[1300px] max-w-none"
                    : "w-full max-w-[600px]"
            }
        >
            <div className="space-y-4">
                {bulkStep === 0 && (
                    <div className="py-6 flex flex-col items-center gap-4">
                        <div className="w-16 h-16 bg-blue-50 text-blue-600 rounded-full flex items-center justify-center">
                            <UploadCloud size={32} />
                        </div>
                        <div className="text-center">
                            <h3 className="font-bold text-lg">Upload Student Excel File</h3>
                            <p className="text-slate-500 text-sm">
                                Download the template, fill it with student details and upload it here.
                            </p>
                        </div>
                        <Upload
                            fileList={fileList}
                            beforeUpload={(file) => {
                                setFileList([file]);
                                return false;
                            }}
                            onRemove={handleRemove}
                            maxCount={1}
                            accept=".xlsx,.xls"
                        >
                            <Button icon={<UploadOutlined />} type="dashed" className="h-20 w-80">
                                Click to select file
                            </Button>
                        </Upload>
                        <Button
                            type="primary"
                            size="large"
                            className="w-full mt-4"
                            onClick={handleBulkUploadPreview}
                            loading={isLoading}
                            disabled={fileList.length === 0}
                        >
                            Continue to Preview
                        </Button>
                    </div>
                )}

                {bulkStep === 1 && (
                    <div className="space-y-4">
                        {/* Header row */}
                        <div className="flex justify-between items-center">
                            <h3 className="font-bold">Parsing Result</h3>
                            <div className="flex gap-2">
                                <Tag color="default">Total: {totalCount}</Tag>
                                <Tag color="success">Valid: {validCount}</Tag>
                                <Tag color="error">Errors: {invalidCount}</Tag>
                            </div>
                        </div>

                        {/* Info note */}
                        <div className="rounded-lg border border-slate-200 bg-slate-50 px-3 py-2 text-sm text-slate-600">
                            <div className="font-medium text-slate-700">Note</div>
                            <div className="mt-1">• Student's phone number is the password. They can change it in the mobile app.</div>
                            <div>• All data must be valid before importing.</div>
                        </div>

                        {/* Table */}
                        <div className="border rounded-xl overflow-hidden">
                            <Table
                                dataSource={paginatedData}
                                rowKey="key"
                                size="small"
                                pagination={false}
                                loading={isLoading}
                                className="min-w-[1000px]"
                                scroll={{ x: 1000, y: "50vh" }}
                                columns={[
                                    {
                                        title: "#",
                                        dataIndex: "index",
                                        align: "center",
                                        width: 50,
                                    },
                                    {
                                        title: "Name",
                                        align: "center",
                                        width: 140,
                                        render: (_, record) => (
                                            <span className="font-medium text-slate-700 block truncate" title={`${record.firstName || ""} ${record.lastName || ""}`}>
                                                {record.firstName || "—"} {record.lastName || ""}
                                            </span>
                                        ),
                                    },
                                    {
                                        title: "Email",
                                        dataIndex: "email",
                                        align: "center",
                                        width: 140,
                                        render: (email) => <span className="block truncate" title={email}>{email}</span>,
                                    },
                                    {
                                        title: "Phone",
                                        dataIndex: "phone",
                                        align: "center",
                                        width: 130,
                                        render: (phone) => <span className="block truncate" title={phone}>{phone}</span>,

                                    },
                                    {
                                        title: "Exam",
                                        dataIndex: "exam",
                                        align: "center",
                                        width: 130,
                                        render: (exam) => <span className="block truncate" title={exam}>{exam}</span>,
                                    },
                                    {
                                        title: "Language",
                                        dataIndex: "language",
                                        align: "center",
                                        width: 130,
                                        render: (language) => <span className="block truncate" title={language}>{language}</span>,
                                    },
                                    {
                                        title: "Referral Code",
                                        align: "center",
                                        width: 130,
                                        render: (_, record) => (
                                            <span className="font-medium text-slate-700 block truncate" title={record.referralCode}>
                                                {record.referralCode || "—"}
                                            </span>
                                        ),
                                    },
                                    {
                                        title: "Status",
                                        dataIndex: "isValid",
                                        align: "center",
                                        width: 100,
                                        render: (isValid) =>
                                            isValid ? (
                                                <Tag color="success" icon={<CheckCircleOutlined />} className="m-0">Valid</Tag>
                                            ) : (
                                                <Tag color="error" icon={<ExclamationCircleOutlined />} className="m-0">Invalid</Tag>
                                            ),
                                    },
                                    {
                                        title: "Errors",
                                        dataIndex: "errors",
                                        // align: "center",
                                        width: 280,
                                        render: (errors: string[]) => (
                                            <div className="flex flex-col gap-1 whitespace-normal break-words">
                                                {errors && errors.length > 0 ? (
                                                    errors.map((err, i) => (
                                                        <span key={i} className="text-xs text-red-500 leading-tight">
                                                            • {err}
                                                        </span>
                                                    ))
                                                ) : (
                                                    <span className="text-xs text-green-600 font-medium">No Error</span>
                                                )}
                                            </div>
                                        ),
                                    },
                                ]}
                            />
                        </div>

                        {/* Pagination */}
                        <div className="flex justify-end mt-2">
                            <Pagination
                                current={page}
                                total={totalCount}
                                pageSize={pageSize}
                                onChange={(p, ps) => {
                                    setPage(p);
                                    setPageSize(ps);
                                }}
                                showSizeChanger
                                pageSizeOptions={["5", "10", "20", "50", "100"]}
                                showTotal={(total) => `Total ${total} records`}
                            />
                        </div>

                        {/* Action buttons */}
                        <div className="flex justify-between pt-2">
                            <Button key="back" onClick={() => setBulkStep(0)} disabled={isLoading}>
                                Change File
                            </Button>
                            <div className="flex gap-3">
                                <Button key="cancel" onClick={handleCloseAndCleanup}>
                                    Cancel
                                </Button>
                                <Button
                                    key="submit"
                                    type="primary"
                                    loading={isLoading}
                                    disabled={!canImportAll}
                                    onClick={handleConfirmUpload}
                                >
                                    Confirm & Import Students
                                </Button>
                            </div>
                        </div>
                    </div>
                )}
            </div>
        </Modal>
    );
};