import toast from "react-hot-toast";
import { API_Instance } from "@/api/axios.instance";
import { Card, Skeleton, Empty } from "antd";
import API_Constants from "@/constants/api.constants";
import { getAxiosErrorMessage } from "@/utils/index.utils";
import { TrendingUp, Calendar } from "lucide-react";
import React, { useState, useEffect, useCallback, useMemo } from "react";
import { ResponsiveContainer, LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip } from "recharts";

interface IGraphPoint {
    week: string;
    percentage: number | null;
}

interface PracticeTestSubjectTrendProps {
    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 ChartTooltip = ({ active, payload, label }: any) => {
    if (!active || !payload?.[0]) return null;
    const data = payload[0].payload;
    const formattedLabel = formatWeekLabel(label);

    return (
        <div className="bg-white rounded-xl p-3 shadow-xl border border-slate-100 min-w-[160px]">
            <p className="font-bold text-slate-700 text-xs mb-1.5 flex items-center gap-1">
                <Calendar size={12} className="text-slate-400" />
                {formattedLabel}
            </p>
            {!data.hasSubmissions ? (
                <p className="text-slate-400 text-xs italic">No Submissions</p>
            ) : (
                <p className="text-[#1677ff] text-xs font-medium flex items-center gap-1.5">
                    <span className="w-2 h-2 rounded-full bg-[#1677ff] inline-block" />
                    Percentage: <span className="font-bold text-slate-800">{data.percentage}%</span>
                </p>
            )}
        </div>
    );
};

const PracticeTestSubjectTrend: React.FC<PracticeTestSubjectTrendProps> = ({
    selectedExamId,
    selectedSubjectId,
    selectedExamName,
    selectedSubjectName
}) => {
    const [graphData, setGraphData] = useState<IGraphPoint[]>([]);
    const [chartLoading, setChartLoading] = useState(false);

    const fetchGraphData = useCallback(async () => {
        if (!selectedExamId || !selectedSubjectId) {
            setGraphData([]);
            return;
        }

        setChartLoading(true);
        try {
            const res = await API_Instance.get(`${API_Constants.reports}/overall/practice-test-subject-trend`, {
                params: {
                    examId: selectedExamId,
                    subjectId: selectedSubjectId
                }
            });
            const trendRaw = res.data?.data || [];
            setGraphData(trendRaw);
        } catch (e) {
            toast.error(getAxiosErrorMessage(e));
        } finally {
            setChartLoading(false);
        }
    }, [selectedExamId, selectedSubjectId]);

    useEffect(() => {
        fetchGraphData();
    }, [fetchGraphData]);

    const processedGraphData = useMemo(() => {
        return graphData.map((item) => ({
            ...item,
            displayPercentage: item.percentage === null || item.percentage === undefined ? 0 : item.percentage,
            hasSubmissions: item.percentage !== null && item.percentage !== undefined,
        }));
    }, [graphData]);

    return (
        <Card className="shadow-sm border border-slate-200/80 rounded-2xl w-full">
            <div className="flex flex-col sm:flex-row justify-between items-start sm:items-center mb-6 gap-4">
                <div>
                    <h3 className="text-lg font-bold text-slate-800 flex items-center gap-2">
                        <TrendingUp size={18} className="text-[#1677ff]" />
                        Particular Subject Trend (All Students)
                    </h3>
                    <p className="text-xs font-medium text-slate-400 mt-0.5">
                        Performance Trend for Selected Subject • 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>
            </div>

            {(!selectedExamId || !selectedSubjectId) ? (
                <div className="h-64 flex flex-col items-center justify-center text-slate-400 gap-2">
                    <TrendingUp size={48} className="text-slate-200" />
                    <p>Please select an exam and a subject to view the trend.</p>
                </div>
            ) : chartLoading ? (
                <div className="p-4">
                    <Skeleton active paragraph={{ rows: 6 }} />
                </div>
            ) : processedGraphData.length === 0 ? (
                <div className="h-64 flex items-center justify-center">
                    <Empty description="No performance data available" />
                </div>
            ) : (
                <ResponsiveContainer width="100%" height={330}>
                    <LineChart data={processedGraphData} margin={{ top: 30, right: 20, left: 15, bottom: 40 }}>
                        <CartesianGrid strokeDasharray="3 3" vertical={false} stroke="#f1f5f9" />
                        <XAxis
                            dataKey="week"
                            tickFormatter={(val) => formatWeekLabel(val)}
                            tick={{ fill: "#94a3b8", fontSize: 11, fontWeight: 500 }}
                            axisLine={false}
                            tickLine={false}
                            dy={10}
                            label={{ value: "Weeks", position: "bottom", offset: 25, fill: "#64748b", fontSize: 12, fontWeight: 600 }}
                        />
                        <YAxis
                            tick={{ fill: "#94a3b8", fontSize: 11 }}
                            axisLine={false}
                            tickLine={false}
                            domain={[0, 100]}
                            ticks={[0, 25, 50, 75, 100]}
                            tickFormatter={(v) => `${v}%`}
                            label={{ value: "Percentage", angle: -90, position: "left", offset: 10, fill: "#64748b", fontSize: 12, fontWeight: 600 }}
                        />
                        <Tooltip content={<ChartTooltip />} cursor={{ stroke: '#f1f5f9', strokeWidth: 2 }} />
                        <Line
                            type="monotone"
                            dataKey="displayPercentage"
                            name="Percentage %"
                            stroke="#1677ff"
                            strokeWidth={3}
                            connectNulls={true}
                            isAnimationActive={false}
                            dot={(props: any) => {
                                const { cx, cy, payload } = props;
                                const hasSubmissions = payload?.hasSubmissions;
                                const value = payload?.displayPercentage;

                                if (!hasSubmissions || value === null || value === undefined) {
                                    return (
                                        <circle
                                            key={props.key}
                                            cx={cx}
                                            cy={cy}
                                            r={3}
                                            fill="#cbd5e1"
                                            stroke="none"
                                        />
                                    );
                                }

                                return (
                                    <g key={props.key}>
                                        <circle
                                            cx={cx}
                                            cy={cy}
                                            r={4}
                                            fill="#1677ff"
                                            stroke="#fff"
                                            strokeWidth={2}
                                        />
                                        <text
                                            x={cx}
                                            y={cy - 10}
                                            textAnchor="middle"
                                            fill="#1677ff"
                                            fontSize={11}
                                            fontWeight={700}
                                        >
                                            {`${value}%`}
                                        </text>
                                    </g>
                                );
                            }}
                            activeDot={{ r: 6, strokeWidth: 0 }}
                        />
                    </LineChart>
                </ResponsiveContainer>
            )}
        </Card>
    );
};

export default PracticeTestSubjectTrend;