"use client";

import Link from "next/link";
import { useEffect, useState } from "react";
import { useSearchParams } from "next/navigation";
import { KpiRow } from "@/components/dashboard/kpi-cards";
import { DashboardCharts } from "@/components/dashboard/dashboard-charts";
import { RankedDocuments } from "@/components/dashboard/ranked-documents";
import { DocumentTable } from "@/components/dashboard/document-table";
import { DashboardFilters } from "@/components/dashboard/dashboard-filters";
import { MonthlyBreakdowns } from "@/components/dashboard/monthly-breakdowns";
import { KpiInlineChart } from "@/components/dashboard/kpi-inline-chart";
import { Card } from "@/components/ui/card";

type DashboardApiPayload = {
  activeScope: string;
  data: any;
};

const dashboardResponseCache = new Map<string, DashboardApiPayload>();

function monthBounds(monthKey: string) {
  const [yearRaw, monthRaw] = monthKey.split("-");
  const year = Number(yearRaw);
  const month = Number(monthRaw);
  if (!Number.isInteger(year) || !Number.isInteger(month) || month < 1 || month > 12) return null;
  const endDate = new Date(Date.UTC(year, month, 0));
  return {
    from: `${year}-${String(month).padStart(2, "0")}-01`,
    to: `${endDate.getUTCFullYear()}-${String(endDate.getUTCMonth() + 1).padStart(2, "0")}-${String(
      endDate.getUTCDate(),
    ).padStart(2, "0")}`,
  };
}

function asMonthKey(from: string, to: string) {
  if (!from || !to) return null;
  const fromParts = from.split("-");
  const toParts = to.split("-");
  if (fromParts.length !== 3 || toParts.length !== 3) return null;
  const [fromYear, fromMonth, fromDay] = fromParts.map(Number);
  const [toYear, toMonth, toDay] = toParts.map(Number);
  if (fromYear !== toYear || fromMonth !== toMonth || fromDay !== 1) return null;
  const endDate = new Date(Date.UTC(fromYear, fromMonth, 0));
  if (toDay !== endDate.getUTCDate()) return null;
  return `${String(fromYear).padStart(4, "0")}-${String(fromMonth).padStart(2, "0")}`;
}

function monthLabel(monthKey: string) {
  const bounds = monthBounds(monthKey);
  if (!bounds) return monthKey;
  return new Intl.DateTimeFormat("en-GB", { month: "long", year: "numeric" }).format(
    new Date(`${bounds.from}T00:00:00Z`),
  );
}

function PageLoading() {
  return (
    <div className="space-y-4">
      <Card>
        <div className="flex items-center gap-3">
          <span
            className="h-4 w-4 animate-spin rounded-full border-2 border-[#2663AC]/30 border-t-[#2663AC]"
            aria-hidden="true"
          />
          <p className="text-sm font-semibold text-slate-700">Loading dashboard...</p>
        </div>
      </Card>
      <Card>
        <div className="space-y-2">
          <div className="h-6 w-64 animate-pulse rounded bg-slate-200" />
          <div className="h-4 w-full animate-pulse rounded bg-slate-100" />
          <div className="h-4 w-5/6 animate-pulse rounded bg-slate-100" />
        </div>
      </Card>
    </div>
  );
}

export function DashboardPageClient({
  initialQuery = "",
  initialPayload = null,
}: {
  initialQuery?: string;
  initialPayload?: DashboardApiPayload | null;
}) {
  const searchParams = useSearchParams();
  const query = searchParams.toString();
  const seededPayload =
    dashboardResponseCache.get(query) ?? (query === initialQuery ? initialPayload ?? null : null);
  const [payload, setPayload] = useState<DashboardApiPayload | null>(seededPayload);
  const [error, setError] = useState<string | null>(null);
  const [loading, setLoading] = useState(!seededPayload);
  const [activeMetric, setActiveMetric] = useState<
    "emails_sent" | "opened" | "total_opens" | "clicked" | "total_clicks" | "ctor" | null
  >(null);

  useEffect(() => {
    if (query !== initialQuery || !initialPayload) return;
    dashboardResponseCache.set(query, initialPayload);
    setPayload(initialPayload);
    setError(null);
    setLoading(false);
  }, [initialPayload, initialQuery, query]);

  useEffect(() => {
    let active = true;
    const cached = dashboardResponseCache.get(query);
    if (cached) {
      setPayload(cached);
      setError(null);
      setLoading(false);
      return;
    }

    setLoading(true);
    setError(null);

    fetch(`/api/dashboard-data${query ? `?${query}` : ""}`, {
      credentials: "same-origin",
      cache: "no-store",
    })
      .then(async (response) => {
        if (!response.ok) {
          throw new Error(`Dashboard request failed (${response.status})`);
        }
        return (await response.json()) as DashboardApiPayload;
      })
      .then((nextPayload) => {
        if (!active) return;
        dashboardResponseCache.set(query, nextPayload);
        setPayload(nextPayload);
        setLoading(false);
      })
      .catch((nextError: Error) => {
        if (!active) return;
        setError(nextError.message);
        setLoading(false);
      });

    return () => {
      active = false;
    };
  }, [query]);

  if (!payload && loading) {
    return <PageLoading />;
  }

  if (!payload) {
    return (
      <Card>
        <p className="text-sm text-rose-600">{error ?? "Could not load dashboard data."}</p>
      </Card>
    );
  }

  const { activeScope, data } = payload;
  const monthKeys = data.monthlySeries
    .map((row: { month_start: string }) => row.month_start.slice(0, 7))
    .filter((value: string, index: number, array: string[]) => array.indexOf(value) === index);

  const requestedMonth = (searchParams.get("month") ?? "").trim();
  const derivedMonth = asMonthKey(data.selectedFilters.from, data.selectedFilters.to);
  const activeMonth = monthKeys.includes(requestedMonth)
    ? requestedMonth
    : derivedMonth && monthKeys.includes(derivedMonth)
      ? derivedMonth
      : null;

  function monthHref(monthKey: string) {
    const bounds = monthBounds(monthKey);
    if (!bounds) return "/dashboard";
    const next = new URLSearchParams();
    next.set("from", bounds.from);
    next.set("to", bounds.to);
    next.set("month", monthKey);
    if (data.selectedFilters.country) next.set("country", data.selectedFilters.country);
    if (data.selectedFilters.brand) next.set("brand", data.selectedFilters.brand);
    if (activeScope) next.set("scope", activeScope);
    return `/dashboard?${next.toString()}`;
  }

  function clearMonthHref() {
    const next = new URLSearchParams();
    if (data.selectedFilters.country) next.set("country", data.selectedFilters.country);
    if (data.selectedFilters.brand) next.set("brand", data.selectedFilters.brand);
    if (activeScope) next.set("scope", activeScope);
    const serialized = next.toString();
    return serialized ? `/dashboard?${serialized}` : "/dashboard";
  }

  function focusMetric(metric: Exclude<typeof activeMetric, null>) {
    setActiveMetric((prev) => (prev === metric ? null : metric));
  }

  return (
    <>
      <DashboardFilters
        selected={{ ...data.selectedFilters, scope: activeScope }}
        minDate={data.minAvailableDate}
        maxDate={data.maxAvailableDate}
        availableCountries={data.availableCountries}
        availableBrands={data.availableBrands}
      />

      <KpiRow kpis={data.kpis} activeMetric={activeMetric ?? undefined} onMetricSelect={focusMetric} />

      {activeMetric ? (
        <KpiInlineChart
          metric={activeMetric}
          rows={data.monthlySeries}
          onClose={() => setActiveMetric(null)}
        />
      ) : null}

      {data.setupRequired ? (
        <div className="enter-fade flex flex-wrap gap-2" style={{ ["--enter-delay" as string]: "100ms" }}>
          <p className="rounded-full border border-amber-400/50 bg-amber-50/95 px-3 py-1 text-xs text-amber-700">
            Supabase env not configured in <code>.env.local</code>
          </p>
        </div>
      ) : null}

      {activeMonth ? (
        <section className="enter-fade-up rounded-2xl border border-[#f1cfaa] bg-[linear-gradient(165deg,#fff8f0_0%,#fff1e2_100%)] px-4 py-3 shadow-[0_16px_24px_-20px_rgba(199,110,33,0.62)]">
          <div className="flex flex-wrap items-center justify-between gap-3">
            <div>
              <p className="caption text-[10px] uppercase tracking-[0.16em] text-[#b46820]">Month Focus</p>
              <p className="text-base font-semibold text-slate-900">Showing {monthLabel(activeMonth)}</p>
            </div>
            <div className="flex items-center gap-2">
              {(() => {
                const activeIndex = monthKeys.indexOf(activeMonth);
                const previousMonth = activeIndex > 0 ? monthKeys[activeIndex - 1] : null;
                const nextMonth =
                  activeIndex >= 0 && activeIndex < monthKeys.length - 1 ? monthKeys[activeIndex + 1] : null;
                return (
                  <>
                    {previousMonth ? (
                      <Link
                        href={monthHref(previousMonth)}
                        className="inline-flex items-center gap-1 rounded-lg border border-[#e6bc8d] bg-white px-3 py-1.5 text-xs font-semibold text-[#a35e1c] transition hover:bg-[#fff7ee]"
                      >
                        <span aria-hidden="true">←</span>
                        Prev
                      </Link>
                    ) : null}
                    {nextMonth ? (
                      <Link
                        href={monthHref(nextMonth)}
                        className="inline-flex items-center gap-1 rounded-lg border border-[#e6bc8d] bg-white px-3 py-1.5 text-xs font-semibold text-[#a35e1c] transition hover:bg-[#fff7ee]"
                      >
                        Next
                        <span aria-hidden="true">→</span>
                      </Link>
                    ) : null}
                    <Link
                      href={clearMonthHref()}
                      className="rounded-lg border border-[#d7e3f2] bg-white px-3 py-1.5 text-xs font-semibold text-[#2663AC] transition hover:bg-[#f5faff]"
                    >
                      All Months
                    </Link>
                  </>
                );
              })()}
            </div>
          </div>
        </section>
      ) : null}

      <details
        id="monthly-trends"
        open
        className="enter-fade-up group rounded-3xl border border-[#d8e4f3] bg-white/92 p-4 shadow-[0_22px_40px_-30px_rgba(38,99,172,0.56)]"
        style={{ ["--enter-delay" as string]: "180ms" }}
      >
        <summary className="flex cursor-pointer list-none items-center justify-between rounded-2xl border border-[#dce8f6] bg-[linear-gradient(120deg,#f2f8ff_0%,#eaf2fd_100%)] px-4 py-3.5 text-sm font-semibold text-slate-900 shadow-[inset_0_1px_0_rgba(255,255,255,0.8)] transition hover:border-[#c5d9ef] hover:bg-[linear-gradient(120deg,#edf6ff_0%,#e3eefb_100%)]">
          Monthly Trend View
          <span className="flex h-7 w-7 items-center justify-center rounded-full bg-[#edf4ff] text-[#2663AC] transition-transform duration-200 group-open:rotate-180">
            <svg viewBox="0 0 20 20" className="h-4 w-4 fill-current" aria-hidden="true">
              <path d="M5.23 7.21a.75.75 0 0 1 1.06.02L10 11.12l3.71-3.9a.75.75 0 1 1 1.08 1.04l-4.25 4.47a.75.75 0 0 1-1.08 0L5.21 8.27a.75.75 0 0 1 .02-1.06Z" />
            </svg>
          </span>
        </summary>
        <div className="mt-4 overflow-hidden transition duration-300 group-open:opacity-100">
          <div className="mb-4 rounded-2xl border border-[#dbe7f5] bg-[linear-gradient(145deg,#fbfdff_0%,#f4f9ff_100%)] px-4 py-3 text-sm text-slate-600">
            {activeMetric === "emails_sent"
              ? "Showing send volume across the period. Use this to spot delivery patterns and month-on-month growth."
              : activeMetric === "opened" || activeMetric === "total_opens"
                ? activeMetric === "opened"
                  ? "Showing unique opened emails across the period. This helps you see how many sends were opened at least once each month."
                  : "Showing total open actions across the period, including repeat opens from the same email."
                : activeMetric === "clicked"
                  ? "Showing unique clicked emails across the period. This helps you see how many sends drove at least one click each month."
                  : activeMetric === "total_clicks"
                    ? "Showing total click actions across the period, including repeat clicks from the same email."
                    : "Showing click-to-open rate across the period. This is clicks divided by opens, so it shows how well opened emails convert into clicks."}
          </div>
          <DashboardCharts
            rows={data.monthlySeries}
            selectedFilters={{ ...data.selectedFilters, scope: activeScope }}
            selectedMonth={activeMonth ?? undefined}
            activeMetric={activeMetric ?? undefined}
          />
        </div>
      </details>

      <details
        open
        className="enter-fade-up group rounded-3xl border border-[#d8e4f3] bg-white/92 p-4 shadow-[0_22px_40px_-30px_rgba(38,99,172,0.56)]"
        style={{ ["--enter-delay" as string]: "220ms" }}
      >
        <summary className="flex cursor-pointer list-none items-center justify-between rounded-2xl border border-[#dce8f6] bg-[linear-gradient(120deg,#f2f8ff_0%,#eaf2fd_100%)] px-4 py-3.5 text-sm font-semibold text-slate-900 shadow-[inset_0_1px_0_rgba(255,255,255,0.8)] transition hover:border-[#c5d9ef] hover:bg-[linear-gradient(120deg,#edf6ff_0%,#e3eefb_100%)]">
          Country + Brand + Time Breakdowns
          <span className="flex h-7 w-7 items-center justify-center rounded-full bg-[#edf4ff] text-[#2663AC] transition-transform duration-200 group-open:rotate-180">
            <svg viewBox="0 0 20 20" className="h-4 w-4 fill-current" aria-hidden="true">
              <path d="M5.23 7.21a.75.75 0 0 1 1.06.02L10 11.12l3.71-3.9a.75.75 0 1 1 1.08 1.04l-4.25 4.47a.75.75 0 0 1-1.08 0L5.21 8.27a.75.75 0 0 1 .02-1.06Z" />
            </svg>
          </span>
        </summary>
        <div className="mt-4">
          <MonthlyBreakdowns countryRows={data.countryMonthBreakdown} brandRows={data.brandMonthBreakdown} />
        </div>
      </details>

      <section className="enter-fade-up space-y-4" style={{ ["--enter-delay" as string]: "260ms" }}>
        <RankedDocuments
          title={`Highest performing emails (min sent ${data.rankingMinSent})`}
          rows={data.topDocuments}
          emptyMessage="Not enough volume to rank top performers."
          tone="top"
        />
        <RankedDocuments
          title={`Lowest performing emails (min sent ${data.rankingMinSent})`}
          rows={data.worstDocuments}
          emptyMessage="Not enough volume to rank low performers."
          tone="low"
        />
      </section>

      <details
        open
        className="enter-fade-up group rounded-3xl border border-[#d8e4f3] bg-white/92 p-0 shadow-[0_22px_40px_-30px_rgba(38,99,172,0.56)]"
        style={{ ["--enter-delay" as string]: "300ms" }}
      >
        <summary className="flex cursor-pointer list-none items-center justify-between border-b border-slate-200 px-4 py-4 text-sm font-semibold text-slate-900">
          VEEVA Email Library
          <span className="flex h-7 w-7 items-center justify-center rounded-full bg-[#edf4ff] text-[#2663AC] transition-transform duration-200 group-open:rotate-180">
            <svg viewBox="0 0 20 20" className="h-4 w-4 fill-current" aria-hidden="true">
              <path d="M5.23 7.21a.75.75 0 0 1 1.06.02L10 11.12l3.71-3.9a.75.75 0 1 1 1.08 1.04l-4.25 4.47a.75.75 0 0 1-1.08 0L5.21 8.27a.75.75 0 0 1 .02-1.06Z" />
            </svg>
          </span>
        </summary>
        <div className="px-4 pb-4">
          <DocumentTable rows={data.documentTable} />
        </div>
      </details>
    </>
  );
}
