"use client";

import type { Chart as ChartType } from "chart.js";
import dynamic from "next/dynamic";
import { useEffect, useRef } from "react";
import { getLocalizedLanguageName } from "../lib/localization";

interface SessionsData {
  [date: string]: number;
}

interface CategoriesData {
  [category: string]: number;
}

interface LanguageData {
  [language: string]: number;
}

interface SessionsLineChartProps {
  sessionsPerDay: SessionsData;
}

interface CategoriesBarChartProps {
  categories: CategoriesData;
}

interface LanguagePieChartProps {
  languages: LanguageData;
}

interface SentimentChartProps {
  sentimentData: {
    positive: number;
    neutral: number;
    negative: number;
  };
}

interface TokenUsageChartProps {
  tokenData: {
    labels: string[];
    values: number[];
    costs: number[];
  };
}

// Loading skeleton for charts
function ChartSkeleton({ height = 180 }: { height?: number }) {
  return (
    <div
      className="animate-pulse bg-gray-200 dark:bg-gray-700 rounded"
      style={{ height }}
    />
  );
}

function DonutChartSkeleton() {
  return (
    <div className="flex items-center justify-center h-[180px]">
      <div className="animate-pulse flex items-center gap-6">
        <div className="w-28 h-28 rounded-full bg-gray-200 dark:bg-gray-700" />
        <div className="space-y-2">
          {[...Array(3)].map((_, i) => (
            <div key={i} className="flex items-center gap-2">
              <div className="w-3 h-3 rounded-full bg-gray-200 dark:bg-gray-700" />
              <div className="w-16 h-3 rounded bg-gray-200 dark:bg-gray-700" />
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

// Inner components that do the actual rendering
function SessionsLineChartInner({ sessionsPerDay }: SessionsLineChartProps) {
  const ref = useRef<HTMLCanvasElement | null>(null);
  const chartRef = useRef<ChartType | null>(null);

  useEffect(() => {
    let isMounted = true;

    async function initChart() {
      if (!ref.current || !sessionsPerDay) return;
      const ctx = ref.current.getContext("2d");
      if (!ctx) return;

      const { default: Chart } = await import("chart.js/auto");
      if (!isMounted) return;

      if (chartRef.current) chartRef.current.destroy();

      chartRef.current = new Chart(ctx, {
        type: "line",
        data: {
          labels: Object.keys(sessionsPerDay),
          datasets: [
            {
              label: "Sessions",
              data: Object.values(sessionsPerDay),
              borderColor: "rgb(59, 130, 246)",
              backgroundColor: "rgba(59, 130, 246, 0.1)",
              borderWidth: 2,
              tension: 0.3,
              fill: true,
            },
          ],
        },
        options: {
          responsive: true,
          plugins: { legend: { display: false } },
          scales: { y: { beginAtZero: true } },
        },
      });
    }

    initChart();

    return () => {
      isMounted = false;
      if (chartRef.current) {
        chartRef.current.destroy();
        chartRef.current = null;
      }
    };
  }, [sessionsPerDay]);

  return <canvas ref={ref} height={180} />;
}

function CategoriesBarChartInner({ categories }: CategoriesBarChartProps) {
  const ref = useRef<HTMLCanvasElement | null>(null);
  const chartRef = useRef<ChartType | null>(null);

  useEffect(() => {
    let isMounted = true;

    async function initChart() {
      if (!ref.current || !categories) return;
      const ctx = ref.current.getContext("2d");
      if (!ctx) return;

      const { default: Chart } = await import("chart.js/auto");
      if (!isMounted) return;

      if (chartRef.current) chartRef.current.destroy();

      chartRef.current = new Chart(ctx, {
        type: "bar",
        data: {
          labels: Object.keys(categories),
          datasets: [
            {
              label: "Categories",
              data: Object.values(categories),
              backgroundColor: "rgba(59, 130, 246, 0.7)",
              borderWidth: 1,
            },
          ],
        },
        options: {
          responsive: true,
          plugins: { legend: { display: false } },
          scales: { y: { beginAtZero: true } },
        },
      });
    }

    initChart();

    return () => {
      isMounted = false;
      if (chartRef.current) {
        chartRef.current.destroy();
        chartRef.current = null;
      }
    };
  }, [categories]);

  return <canvas ref={ref} height={180} />;
}

function SentimentChartInner({ sentimentData }: SentimentChartProps) {
  const ref = useRef<HTMLCanvasElement | null>(null);
  const chartRef = useRef<ChartType | null>(null);

  useEffect(() => {
    let isMounted = true;

    async function initChart() {
      if (!ref.current || !sentimentData) return;
      const ctx = ref.current.getContext("2d");
      if (!ctx) return;

      const { default: Chart } = await import("chart.js/auto");
      if (!isMounted) return;

      if (chartRef.current) chartRef.current.destroy();

      chartRef.current = new Chart(ctx, {
        type: "doughnut",
        data: {
          labels: ["Positive", "Neutral", "Negative"],
          datasets: [
            {
              data: [
                sentimentData.positive,
                sentimentData.neutral,
                sentimentData.negative,
              ],
              backgroundColor: [
                "rgba(34, 197, 94, 0.8)",
                "rgba(249, 115, 22, 0.8)",
                "rgba(239, 68, 68, 0.8)",
              ],
              borderWidth: 1,
            },
          ],
        },
        options: {
          responsive: true,
          plugins: {
            legend: {
              position: "right",
              labels: {
                usePointStyle: true,
                padding: 20,
              },
            },
          },
          cutout: "65%",
        },
      });
    }

    initChart();

    return () => {
      isMounted = false;
      if (chartRef.current) {
        chartRef.current.destroy();
        chartRef.current = null;
      }
    };
  }, [sentimentData]);

  return <canvas ref={ref} height={180} />;
}

function LanguagePieChartInner({ languages }: LanguagePieChartProps) {
  const ref = useRef<HTMLCanvasElement | null>(null);
  const chartRef = useRef<ChartType | null>(null);

  useEffect(() => {
    let isMounted = true;

    async function initChart() {
      if (!ref.current || !languages) return;
      const ctx = ref.current.getContext("2d");
      if (!ctx) return;

      const { default: Chart } = await import("chart.js/auto");
      if (!isMounted) return;

      // Get top 5 languages, combine others
      const entries = Object.entries(languages);
      const topLanguages = entries.sort((a, b) => b[1] - a[1]).slice(0, 5);

      const otherCount = entries
        .slice(5)
        .reduce((sum, [, count]) => sum + count, 0);
      if (otherCount > 0) {
        topLanguages.push(["Other", otherCount]);
      }

      const isoCodes = topLanguages.map(([lang]) => lang);

      const labels = topLanguages.map(([lang]) => {
        if (lang === "Other") return "Other";
        return getLocalizedLanguageName(lang, "en");
      });

      const data = topLanguages.map(([, count]) => count);

      if (chartRef.current) chartRef.current.destroy();

      chartRef.current = new Chart(ctx, {
        type: "pie",
        data: {
          labels,
          datasets: [
            {
              data,
              backgroundColor: [
                "rgba(59, 130, 246, 0.8)",
                "rgba(16, 185, 129, 0.8)",
                "rgba(249, 115, 22, 0.8)",
                "rgba(236, 72, 153, 0.8)",
                "rgba(139, 92, 246, 0.8)",
                "rgba(107, 114, 128, 0.8)",
              ],
              borderWidth: 1,
            },
          ],
        },
        options: {
          responsive: true,
          plugins: {
            legend: {
              position: "right",
              labels: {
                usePointStyle: true,
                padding: 20,
              },
            },
            tooltip: {
              callbacks: {
                label: (context) => {
                  const label = context.label || "";
                  const value = context.formattedValue || "";
                  const index = context.dataIndex;
                  const originalIsoCode = isoCodes[index];

                  if (
                    originalIsoCode &&
                    originalIsoCode !== "Other" &&
                    /^[a-z]{2}$/.test(originalIsoCode.toLowerCase())
                  ) {
                    return `${label} (${originalIsoCode.toUpperCase()}): ${value}`;
                  }

                  return `${label}: ${value}`;
                },
              },
            },
          },
        },
      });
    }

    initChart();

    return () => {
      isMounted = false;
      if (chartRef.current) {
        chartRef.current.destroy();
        chartRef.current = null;
      }
    };
  }, [languages]);

  return <canvas ref={ref} height={180} />;
}

function TokenUsageChartInner({ tokenData }: TokenUsageChartProps) {
  const ref = useRef<HTMLCanvasElement | null>(null);
  const chartRef = useRef<ChartType | null>(null);

  useEffect(() => {
    let isMounted = true;

    async function initChart() {
      if (!ref.current || !tokenData) return;
      const ctx = ref.current.getContext("2d");
      if (!ctx) return;

      const { default: Chart } = await import("chart.js/auto");
      if (!isMounted) return;

      if (chartRef.current) chartRef.current.destroy();

      chartRef.current = new Chart(ctx, {
        type: "bar",
        data: {
          labels: tokenData.labels,
          datasets: [
            {
              label: "Tokens",
              data: tokenData.values,
              backgroundColor: "rgba(59, 130, 246, 0.7)",
              borderWidth: 1,
              yAxisID: "y",
            },
            {
              label: "Cost (EUR)",
              data: tokenData.costs,
              backgroundColor: "rgba(16, 185, 129, 0.7)",
              borderWidth: 1,
              type: "line",
              yAxisID: "y1",
            },
          ],
        },
        options: {
          responsive: true,
          plugins: { legend: { display: true } },
          scales: {
            y: {
              beginAtZero: true,
              position: "left",
              title: {
                display: true,
                text: "Token Count",
              },
            },
            y1: {
              beginAtZero: true,
              position: "right",
              grid: {
                drawOnChartArea: false,
              },
              title: {
                display: true,
                text: "Cost (EUR)",
              },
            },
          },
        },
      });
    }

    initChart();

    return () => {
      isMounted = false;
      if (chartRef.current) {
        chartRef.current.destroy();
        chartRef.current = null;
      }
    };
  }, [tokenData]);

  return <canvas ref={ref} height={180} />;
}

// Dynamic exports with SSR disabled
export const SessionsLineChart = dynamic(
  () => Promise.resolve(SessionsLineChartInner),
  {
    ssr: false,
    loading: () => <ChartSkeleton height={180} />,
  }
);

export const CategoriesBarChart = dynamic(
  () => Promise.resolve(CategoriesBarChartInner),
  {
    ssr: false,
    loading: () => <ChartSkeleton height={180} />,
  }
);

export const SentimentChart = dynamic(
  () => Promise.resolve(SentimentChartInner),
  {
    ssr: false,
    loading: () => <DonutChartSkeleton />,
  }
);

export const LanguagePieChart = dynamic(
  () => Promise.resolve(LanguagePieChartInner),
  {
    ssr: false,
    loading: () => <DonutChartSkeleton />,
  }
);

export const TokenUsageChart = dynamic(
  () => Promise.resolve(TokenUsageChartInner),
  {
    ssr: false,
    loading: () => <ChartSkeleton height={180} />,
  }
);
