"use client";

import { useEffect, useMemo, useState } from "react";

type ChartLib = {
  Doughnut: typeof import("react-chartjs-2").Doughnut;
  Bar: typeof import("react-chartjs-2").Bar;
} | null;

export interface OverviewItem {
  moduleSlug: string;
  data: Record<string, unknown>;
}

const MONEY_TYPES = new Set([
  "money",
  "cash",
  "bank",
  "upi",
  "card",
  "cheque",
]);

const CHART_PALETTE = [
  "#6366f1",
  "#10b981",
  "#f59e0b",
  "#ef4444",
  "#06b6d4",
  "#a855f7",
  "#ec4899",
  "#84cc16",
  "#f97316",
  "#0ea5e9",
  "#14b8a6",
  "#eab308",
];

export function buildOverview(items: OverviewItem[]) {
  const moduleSlugs = new Set<string>();
  let totalItems = 0;
  let totalMoney = 0;

  const giftsByTypeMap = new Map<string, number>();
  const moneyByTypeMap = new Map<string, number>();
  const tasks = { total: 0, done: 0, inProgress: 0, pending: 0 };
  const guestsByRsvpMap = new Map<string, number>();
  const budgetItems: { label: string; estimated: number; actual: number }[] = [];

  for (const i of items) {
    moduleSlugs.add(i.moduleSlug);
    totalItems += 1;
    const d = i.data;

    if (i.moduleSlug === "gift") {
      const rawType = String(d.giftType ?? "other");
      const label =
        rawType.charAt(0).toUpperCase() + rawType.slice(1).replace(/_/g, " ");
      giftsByTypeMap.set(label, (giftsByTypeMap.get(label) ?? 0) + 1);
      if (MONEY_TYPES.has(rawType.toLowerCase())) {
        const amt = Number(d.amount ?? 0);
        if (Number.isFinite(amt)) {
          totalMoney += amt;
          moneyByTypeMap.set(label, (moneyByTypeMap.get(label) ?? 0) + amt);
        }
      }
    }

    if (i.moduleSlug === "expense-tracker") {
      const type = String(d.paymentType ?? "").toLowerCase();
      if (MONEY_TYPES.has(type)) {
        const amt = Number(d.amount ?? 0);
        if (Number.isFinite(amt)) {
          totalMoney += amt;
          const label =
            type.charAt(0).toUpperCase() + type.slice(1).replace(/_/g, " ");
          moneyByTypeMap.set(label, (moneyByTypeMap.get(label) ?? 0) + amt);
        }
      }
    }

    if (i.moduleSlug === "todo") {
      tasks.total += 1;
      const s = String(d.status ?? "").toLowerCase();
      if (s === "done" || s === "completed") tasks.done += 1;
      else if (s === "in_progress") tasks.inProgress += 1;
      else tasks.pending += 1;
    }

    if (i.moduleSlug === "guest-list") {
      const r = String(d.rsvp ?? "pending").toLowerCase();
      const key =
        r === "accepted"
          ? "Accepted"
          : r === "declined"
            ? "Declined"
            : "Pending";
      guestsByRsvpMap.set(key, (guestsByRsvpMap.get(key) ?? 0) + 1);
    }

    if (i.moduleSlug === "budget") {
      const title = String(d.title ?? "Untitled");
      const est = Number(d.estimated ?? 0);
      const act = Number(d.actual ?? 0);
      if (Number.isFinite(est) || Number.isFinite(act)) {
        budgetItems.push({ label: title, estimated: est, actual: act });
      }
    }
  }

  const giftsByType = Array.from(giftsByTypeMap.entries())
    .map(([label, value]) => ({ label, value }))
    .sort((a, b) => b.value - a.value);

  const moneyByType = Array.from(moneyByTypeMap.entries())
    .map(([label, value]) => ({ label, value }))
    .sort((a, b) => b.value - a.value);

  const rsvpOrder = ["Accepted", "Pending", "Declined"];
  const rsvpColors: Record<string, string> = {
    Accepted: "#10b981",
    Pending: "#f59e0b",
    Declined: "#ef4444",
  };
  const guestsByRsvp = rsvpOrder
    .filter((k) => guestsByRsvpMap.has(k))
    .map((label) => ({
      label,
      value: guestsByRsvpMap.get(label) ?? 0,
      color: rsvpColors[label] ?? "#94a3b8",
    }));

  return {
    modulesActive: moduleSlugs.size,
    totalItems,
    totalMoney,
    tasks,
    giftsByType,
    moneyByType,
    guestsByRsvp,
    budget: budgetItems.slice(0, 8),
  };
}

export interface EventOverviewChartsProps {
  items: OverviewItem[];
  loading?: boolean;
  error?: string | null;
  emptyMessage?: string;
}

export function EventOverviewCharts({
  items,
  loading,
  error,
  emptyMessage = "Add items in any module to see charts here.",
}: EventOverviewChartsProps) {
  const ChartComponents = useChartComponents();
  const data = useMemo(() => buildOverview(items), [items]);

  if (error) {
    return (
      <section className="rounded-2xl border border-red-200 bg-red-50 p-4 shadow-sm">
        <p className="text-sm font-medium text-red-700">Overview unavailable</p>
        <p className="mt-1 text-xs text-red-700/80">{error}</p>
      </section>
    );
  }

  if (loading || !ChartComponents) {
    return (
      <section className="rounded-2xl border border-border bg-surface p-5 shadow-sm">
        <p className="text-sm text-muted">Loading overview…</p>
      </section>
    );
  }

  const { Doughnut, Bar } = ChartComponents;

  return (
    <section className="space-y-4">
      <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
        <StatTile label="Modules active" value={data.modulesActive} accent="indigo" />
        <StatTile label="Items tracked" value={data.totalItems} accent="blue" />
        <StatTile
          label="Money received"
          value={`$${data.totalMoney.toFixed(2)}`}
          accent="emerald"
        />
        <StatTile
          label="Tasks done"
          value={`${data.tasks.done} / ${data.tasks.total}`}
          accent="amber"
          subtitle={`${data.tasks.pending} pending · ${data.tasks.inProgress} in progress`}
        />
      </div>

      {data.totalItems === 0 ? (
        <div className="rounded-2xl border border-dashed border-border bg-surface p-8 text-center">
          <p className="text-sm font-medium">No data to visualise yet</p>
          <p className="mt-1 text-xs text-muted">{emptyMessage}</p>
        </div>
      ) : (
        <div className="grid gap-4 lg:grid-cols-2">
          {data.giftsByType.length > 0 ? (
            <ChartCard title="Gifts by type" subtitle="Count of gifts received">
              <Doughnut
                data={{
                  labels: data.giftsByType.map((d) => d.label),
                  datasets: [
                    {
                      data: data.giftsByType.map((d) => d.value),
                      backgroundColor: data.giftsByType.map(
                        (_, i) => CHART_PALETTE[i % CHART_PALETTE.length],
                      ),
                      borderColor: "transparent",
                    },
                  ],
                }}
                options={{
                  responsive: true,
                  maintainAspectRatio: false,
                  plugins: {
                    legend: { position: "right", labels: { boxWidth: 12 } },
                  },
                  cutout: "60%",
                }}
              />
            </ChartCard>
          ) : null}

          {data.moneyByType.length > 0 ? (
            <ChartCard title="Money received by method" subtitle="Sum in $">
              <Bar
                data={{
                  labels: data.moneyByType.map((d) => d.label),
                  datasets: [
                    {
                      label: "Amount ($)",
                      data: data.moneyByType.map((d) => d.value),
                      backgroundColor: data.moneyByType.map(
                        (_, i) => CHART_PALETTE[i % CHART_PALETTE.length],
                      ),
                      borderRadius: 6,
                    },
                  ],
                }}
                options={{
                  responsive: true,
                  maintainAspectRatio: false,
                  plugins: { legend: { display: false } },
                  scales: {
                    y: { beginAtZero: true, ticks: { precision: 0 } },
                  },
                }}
              />
            </ChartCard>
          ) : null}

          {data.tasks.total > 0 ? (
            <ChartCard title="To-do progress" subtitle="Status breakdown">
              <Doughnut
                data={{
                  labels: ["Done", "In progress", "Pending"],
                  datasets: [
                    {
                      data: [
                        data.tasks.done,
                        data.tasks.inProgress,
                        data.tasks.pending,
                      ],
                      backgroundColor: ["#10b981", "#3b82f6", "#f59e0b"],
                      borderColor: "transparent",
                    },
                  ],
                }}
                options={{
                  responsive: true,
                  maintainAspectRatio: false,
                  plugins: {
                    legend: { position: "right", labels: { boxWidth: 12 } },
                  },
                  cutout: "60%",
                }}
              />
            </ChartCard>
          ) : null}

          {data.guestsByRsvp.length > 0 ? (
            <ChartCard title="Guest RSVP" subtitle="Accepted vs pending vs declined">
              <Bar
                data={{
                  labels: data.guestsByRsvp.map((d) => d.label),
                  datasets: [
                    {
                      label: "Guests",
                      data: data.guestsByRsvp.map((d) => d.value),
                      backgroundColor: data.guestsByRsvp.map((d) => d.color),
                      borderRadius: 6,
                    },
                  ],
                }}
                options={{
                  responsive: true,
                  maintainAspectRatio: false,
                  plugins: { legend: { display: false } },
                  scales: { y: { beginAtZero: true, ticks: { precision: 0 } } },
                }}
              />
            </ChartCard>
          ) : null}

          {data.budget.length > 0 ? (
            <ChartCard
              title="Budget vs actual"
              subtitle="Estimated (blue) vs actual (green)"
            >
              <Bar
                data={{
                  labels: data.budget.map((d) => d.label),
                  datasets: [
                    {
                      label: "Estimated",
                      data: data.budget.map((d) => d.estimated),
                      backgroundColor: "#60a5fa",
                      borderRadius: 6,
                    },
                    {
                      label: "Actual",
                      data: data.budget.map((d) => d.actual),
                      backgroundColor: "#34d399",
                      borderRadius: 6,
                    },
                  ],
                }}
                options={{
                  responsive: true,
                  maintainAspectRatio: false,
                  plugins: {
                    legend: { position: "bottom", labels: { boxWidth: 12 } },
                  },
                  scales: { y: { beginAtZero: true } },
                }}
              />
            </ChartCard>
          ) : null}
        </div>
      )}
    </section>
  );
}

function ChartCard({
  title,
  subtitle,
  children,
}: {
  title: string;
  subtitle?: string;
  children: React.ReactNode;
}) {
  return (
    <div className="rounded-2xl border border-border bg-surface p-5 shadow-sm">
      <div className="mb-3">
        <h4 className="text-sm font-semibold text-foreground">{title}</h4>
        {subtitle ? <p className="mt-0.5 text-xs text-muted">{subtitle}</p> : null}
      </div>
      <div className="h-64">{children}</div>
    </div>
  );
}

function StatTile({
  label,
  value,
  subtitle,
  accent,
}: {
  label: string;
  value: string | number;
  subtitle?: string;
  accent: "indigo" | "blue" | "emerald" | "amber";
}) {
  const accentMap: Record<string, string> = {
    indigo: "bg-indigo-50 text-indigo-700",
    blue: "bg-blue-50 text-blue-700",
    emerald: "bg-emerald-50 text-emerald-700",
    amber: "bg-amber-50 text-amber-700",
  };
  return (
    <div className={`rounded-2xl border border-border p-4 shadow-sm ${accentMap[accent]}`}>
      <p className="text-[10px] font-medium uppercase tracking-wide opacity-70">
        {label}
      </p>
      <p className="mt-1 text-2xl font-semibold">{value}</p>
      {subtitle ? <p className="mt-1 text-xs opacity-80">{subtitle}</p> : null}
    </div>
  );
}

function useChartComponents(): ChartLib {
  const [comps, setComps] = useState<ChartLib>(null);
  useEffect(() => {
    let active = true;
    Promise.all([import("chart.js/auto"), import("react-chartjs-2")])
      .then(([, rc]) => {
        if (!active) return;
        setComps({ Doughnut: rc.Doughnut, Bar: rc.Bar });
      })
      .catch((err) => {
        if (!active) return;
        console.warn("Charts failed to load:", err);
        setComps(null);
      });
    return () => {
      active = false;
    };
  }, []);
  return comps;
}
