import toast from "react-hot-toast";
import type { TableProps } from "antd";
import { useNavigate } from "react-router-dom";
import { useDebounce } from "@/hooks/useDebounce";
import { API_Instance } from "@/api/axios.instance";
import API_Constants from "@/constants/api.constants";
import ROUTE_CONSTANTS from "@/constants/route.constants";
import { getAxiosErrorMessage } from "@/utils/index.utils";
import React, { useState, useEffect, useCallback, useMemo } from "react";
import { Card, Skeleton, Empty, Select, Table, Tag, Pagination, Input, Button } from "antd";
import { Users, ArrowUpDown, Search, ChartNoAxesColumnDecreasing, ChartNoAxesColumnIncreasing } from "lucide-react";

interface IStudentRow {
    studentId: string;
    studentName: string;
    email?: string;
    assignedExam?: string;
    weeks: Record<string, number | null>;
    overallAverage: number;
    hasAttended: boolean;
}

interface PracticeTestSubjectWiseStudentsProps {
    selectedExamId: string;
    selectedSubjectId: string;
    selectedExamName: string;
    selectedSubjectName: string;
}

const formatWeekLabel = (label: string): string => {
    if (!label) return "";
    const formattedLabel = label.replace(/From\s+/i, "");
    const parts = formattedLabel.split(/\s+to\s+/i);
    if (parts.length !== 2) return label;

    const formatDate = (dateStr: string, includeMonth: boolean) => {
        const date = new Date(dateStr);
        if (isNaN(date.getTime())) return dateStr;
        return date.toLocaleDateString("en-US", {
            month: includeMonth ? "short" : undefined,
            day: "numeric",
        });
    };

    const firstDate = new Date(parts[0]);
    const secondDate = new Date(parts[1]);
    if (isNaN(firstDate.getTime()) || isNaN(secondDate.getTime())) return label;

    const sameMonthAndYear =
        firstDate.getFullYear() === secondDate.getFullYear() &&
        firstDate.getMonth() === secondDate.getMonth();

    const firstFormatted = formatDate(parts[0], true);
    const secondFormatted = sameMonthAndYear ? formatDate(parts[1], false) : formatDate(parts[1], true);

    return `${firstFormatted} - ${secondFormatted}`;
};

const PercentageCell = ({ value }: { value: number | null }) => {
    if (value === null || value === undefined) {
        return <span className="text-slate-300 text-xs font-medium">—</span>;
    }
    const color =
        value >= 75 ? "success" :
            value >= 50 ? "processing" :
                value >= 25 ? "warning" : "error";

    return (
        <Tag
            color={color}
            className="rounded-full text-xs font-semibold min-w-[48px] text-center"
        >
            {value}%
        </Tag>
    );
};

const PracticeTestSubjectWiseStudents: React.FC<PracticeTestSubjectWiseStudentsProps> = ({
    selectedExamId,
    selectedSubjectId,
    selectedExamName,
    selectedSubjectName
}) => {
    const navigate = useNavigate();
    const [tableData, setTableData] = useState<IStudentRow[]>([]);
    const [tableColumns, setTableColumns] = useState<string[]>([]);
    const [tableLoading, setTableLoading] = useState(false);
    const [sortBy, setSortBy] = useState<"studentName" | "overallAverage">("studentName");
    const [sortOrder, setSortOrder] = useState<"asc" | "desc">("asc");
    const [tablePage, setTablePage] = useState(1);
    const [tableLimit, setTableLimit] = useState(10);
    const [tableTotal, setTableTotal] = useState(0);

    const [statusFilter, setStatusFilter] = useState<"all" | "attended" | "notattended">("all");
    const [studentSearch, setStudentSearch] = useState("");
    const debouncedStudentSearch = useDebounce(studentSearch, 500);

    const fetchTableData = useCallback(async (page = tablePage, limit = tableLimit, filter = statusFilter) => {
        if (!selectedExamId || !selectedSubjectId) {
            setTableData([]);
            setTableTotal(0);
            return;
        }

        setTableLoading(true);
        try {
            const res = await API_Instance.get(`${API_Constants.reports}/overall/particular-subject-student-table`, {
                params: {
                    examId: selectedExamId,
                    subjectId: selectedSubjectId,
                    sortBy,
                    sortOrder,
                    statusFilter: filter,
                    search: debouncedStudentSearch || undefined,
                    page,
                    limit
                }
            });
            setTableData(res.data?.data || []);
            setTableTotal(res.data?.pagination?.total || 0);
            const rawCols: string[] = res.data?.columns || [];
            setTableColumns(rawCols.filter((c: string) => c !== "Student Name" && c !== "Overall Average"));
        } catch (e) {
            toast.error(getAxiosErrorMessage(e));
        } finally {
            setTableLoading(false);
        }
    }, [selectedExamId, selectedSubjectId, sortBy, sortOrder, statusFilter, tablePage, tableLimit, debouncedStudentSearch]);

    useEffect(() => {
        setTablePage(1);
        fetchTableData(1, tableLimit, statusFilter);
    }, [selectedExamId, selectedSubjectId, sortBy, sortOrder, statusFilter, debouncedStudentSearch]);

    const antdColumns = useMemo((): TableProps<IStudentRow>["columns"] => {
        const staticFirst = {
            title: (
                <button
                    className="flex items-center gap-1 font-semibold text-slate-700 text-sm cursor-pointer group select-none"
                    onClick={() => {
                        setSortBy("studentName");
                        setSortOrder((prev) => (sortBy === "studentName" && prev === "asc" ? "desc" : "asc"));
                    }}
                >
                    Student Details
                    <ArrowUpDown
                        size={13}
                        className={`transition-colors ${sortBy === "studentName" ? "text-blue-500" : "text-slate-400 group-hover:text-blue-400"}`}
                    />
                </button>
            ),
            dataIndex: "studentName",
            key: "studentName",
            fixed: "left" as const,
            width: 210,
            render: (name: string, record: IStudentRow) => (
                <div className="flex flex-col gap-0.5">
                    <span
                        className="font-semibold text-blue-600 hover:text-blue-800 hover:underline text-sm cursor-pointer"
                        onClick={() => navigate(ROUTE_CONSTANTS.StudentPerformance.replace(":studentId", record.studentId))}
                    >
                        {name}
                    </span>
                    {record.email && (
                        <span className="text-xs text-slate-400 font-normal">{record.email}</span>
                    )}
                </div>
            )
        };

        const weekCols = tableColumns.map((weekLabel) => ({
            title: (
                <span className="text-xs text-slate-500 font-medium whitespace-nowrap">
                    {formatWeekLabel(weekLabel)}
                </span>
            ),
            key: weekLabel,
            width: 110,
            align: "center" as const,
            render: (_: any, record: IStudentRow) => (
                <PercentageCell value={record.weeks[weekLabel] ?? null} />
            )
        }));

        const staticLast = {
            title: (
                <button
                    className="flex items-center gap-1 font-semibold text-slate-700 text-sm cursor-pointer group select-none"
                    onClick={() => {
                        setSortBy("overallAverage");
                        setSortOrder((prev) => (sortBy === "overallAverage" && prev === "desc" ? "asc" : "desc"));
                    }}
                >
                    Overall Avg
                    <ArrowUpDown
                        size={13}
                        className={`transition-colors ${sortBy === "overallAverage" ? "text-blue-500" : "text-slate-400 group-hover:text-blue-400"}`}
                    />
                </button>
            ),
            dataIndex: "overallAverage",
            key: "overallAverage",
            fixed: "left" as const,
            width: 130,
            align: "center" as const,
            render: (val: number, record: IStudentRow) => (
                <Tag
                    color={!record.hasAttended ? "default" : (val >= 75 ? "success" : val >= 50 ? "processing" : val >= 25 ? "warning" : "error")}
                    className="rounded-full text-xs font-bold min-w-[52px] text-center"
                >
                    {record.hasAttended ? `${val}%` : "—"}
                </Tag>
            )
        };

        return [staticFirst, staticLast, ...weekCols];
    }, [tableColumns, sortBy, sortOrder]);

    return (
        <Card className="shadow-sm border border-slate-200/80 rounded-2xl w-full">
            <div className="flex flex-col md:flex-row justify-between items-start md:items-center mb-6 gap-4">
                <div>
                    <h3 className="text-lg font-bold text-slate-800 flex items-center gap-2">
                        <Users size={18} className="text-[#1677ff]" />
                        Student-Wise Weekly Performance (Practice Test)
                    </h3>
                    <p className="text-xs font-medium text-slate-400 mt-0.5">
                        Practice Test Performance Matrix by Student and Week • Last 90 Days
                    </p>
                    {selectedExamName && (
                        <div className="flex flex-wrap gap-2 mt-2">
                            <span className="text-xs font-semibold text-indigo-600 uppercase tracking-wide bg-indigo-50 px-2.5 py-1 rounded-md w-fit">
                                Exam: {selectedExamName}
                            </span>
                            {selectedSubjectName && (
                                <span className="text-xs font-semibold text-purple-600 uppercase tracking-wide bg-purple-50 px-2.5 py-1 rounded-md w-fit">
                                    Subject: {selectedSubjectName}
                                </span>
                            )}
                        </div>
                    )}
                </div>

                {selectedExamId && selectedSubjectId && (
                    <div className="flex flex-col sm:flex-row items-stretch sm:items-center gap-3 w-full md:w-auto justify-end">
                        <div className="w-full sm:w-60">
                            <Input
                                placeholder="Search student name..."
                                allowClear
                                prefix={<Search size={14} className="text-slate-400 mr-1" />}
                                value={studentSearch}
                                onChange={(e) => setStudentSearch(e.target.value)}
                                className="h-9 rounded-lg"
                            />
                        </div>

                        <div className="w-full sm:w-48">
                            <Select
                                className="w-full h-9"
                                placeholder="Filter Status"
                                value={statusFilter}
                                onChange={(value: "all" | "attended" | "notattended") => {
                                    setStatusFilter(value);
                                    setTablePage(1);
                                }}
                                options={[
                                    { label: "All Students", value: "all" },
                                    { label: "Attended", value: "attended" },
                                    { label: "Not Attended", value: "notattended" }
                                ]}
                            />
                        </div>
                    </div>
                )}
            </div>

            {!selectedExamId || !selectedSubjectId ? (
                <div className="h-64 flex flex-col items-center justify-center text-slate-400 gap-2">
                    <Users size={48} className="text-slate-200" />
                    <p>Please select an exam and a subject to view student matrix.</p>
                </div>
            ) : tableLoading ? (
                <div className="p-4">
                    <Skeleton active paragraph={{ rows: 6 }} />
                </div>
            ) : tableData.length === 0 ? (
                <div className="h-64 flex items-center justify-center">
                    <Empty description="No students records matching selection criteria" />
                </div>
            ) : (
                <div className="flex flex-col gap-4">
                    <div className="overflow-x-auto border border-slate-100 rounded-xl">
                        <Table
                            columns={antdColumns}
                            dataSource={tableData}
                            rowKey="studentId"
                            pagination={false}
                            loading={tableLoading}
                            className="custom-table"
                            scroll={{ x: "max-content" }}
                        />
                    </div>
                    <div className="flex items-center justify-end">
                        <Pagination
                            current={tablePage}
                            total={tableTotal}
                            pageSize={tableLimit}
                            onChange={(p) => {
                                setTablePage(p);
                                fetchTableData(p, tableLimit, statusFilter);
                            }}
                            onShowSizeChange={(current, size) => {
                                setTableLimit(size);
                                setTablePage(1);
                                fetchTableData(1, size, statusFilter);
                            }}
                            showSizeChanger
                            pageSizeOptions={[5, 10, 20, 50]}
                            disabled={tableLoading}
                            showQuickJumper={false}
                        />
                    </div>
                </div>
            )}
        </Card>
    );
};

export default PracticeTestSubjectWiseStudents;
