import { CartesianGrid, Legend, Line, LineChart, XAxis, YAxis } from "recharts";
import { ChartContainer, ChartTooltip, ChartTooltipContent } from "../ui/chart";
import { getSubjectEmoji, getSubjectColor } from "~/lib/utils";
import type { PeriodResult, User } from "~/lib/api";
import { useEffect, useState } from "react";
import { HARDCODED_HIDDEN_SUBJECTS } from "./grades-chart"

export default function AverageChart({
  averages,
  subjects,
  user,
}: {
  averages: PeriodResult[];
  subjects: string[];
  user: User;
}) {
  const [hiddenSubjects, setHiddenSubjects] = useState<string[]>([]);
  const toggleSubjectVisibility = (subject: string) => {
    setHiddenSubjects((prev) =>
      prev.includes(subject)
        ? prev.filter((s) => s !== subject)
        : [...prev, subject]
    );
  };

  const [min, setMin] = useState(0);
  const [max, setMax] = useState(20);
  useEffect(() => {
    if (averages.length > 0) {
      const filteredGrades = averages.map((o) =>
        Object.entries(o)
          .filter(([key, value]) => {
            return !hiddenSubjects.includes(key) && !isNaN(parseFloat(value));
          })
          .map(([_, v]) => parseFloat(v))
          .filter(Boolean)
      );
      setMin(getMin(filteredGrades));
      setMax(getMax(filteredGrades));
    }
  }, [averages, hiddenSubjects]);

  return (
    <ChartContainer config={{}} className="h-full w-full -ml-6 max-w-2xl">
      <LineChart data={averages}>
        <CartesianGrid strokeDasharray="3 3" />
        <XAxis dataKey="period" />
        <YAxis domain={[min, max]} />
        <ChartTooltip content={<ChartTooltipContent />} />
        <Legend
          onClick={(e) => {
            if (e.dataKey) {
              toggleSubjectVisibility(e.dataKey as string);
            }
          }}
        />
        {subjects.filter((s) => !HARDCODED_HIDDEN_SUBJECTS.includes(s)).map((subject, index) => (
          <Line
            key={index}
            type="monotone"
            dataKey={subject}
            name={subject + " " + getSubjectEmoji(subject, user.preferences)}
            hide={hiddenSubjects.includes(subject)}
            stroke={`var(--color-${getSubjectColor(
              subject,
              user.preferences
            )}-800`}
            dot={{
              fill: `var(--color-${getSubjectColor(
                subject,
                user.preferences
              )}-800`,
              stroke: `var(--color-${getSubjectColor(
                subject,
                user.preferences
              )}-800)`,
            }}
          />
        ))}
        <Line
          type="monotone"
          dataKey="average"
          name="Moyenne"
          stroke="var(--primary)"
          strokeWidth={2}
          dot={false}
          strokeDasharray="5 5"
          hide={hiddenSubjects.includes("average")}
        />
      </LineChart>
    </ChartContainer>
  );
}

function getMin(grades: number[][]) {
  return Math.max(
    Math.round(
      Math.min(...grades.map((g) => Math.min(...g)).filter(Boolean)) - 1
    ),
    0
  );
}

function getMax(grades: number[][]) {
  return Math.min(
    Math.round(
      Math.max(...grades.map((g) => Math.max(...g)).filter(Boolean)) + 1
    ),
    20
  );
}
