"use client";

import { useState, useTransition } from "react";
import { usePathname, useRouter, useSearchParams } from "next/navigation";
import { Button } from "@/components/ui/button";
import { Card } from "@/components/ui/card";
import { Select } from "@/components/ui/select";
import { AnimatedCounter } from "@/components/ui/animated-counter";
import { KpiCards, KpiHighlights } from "@/components/dashboard/kpi-cards";
import { RankedDocuments } from "@/components/dashboard/ranked-documents";
import { BrandBreakdown } from "@/components/dashboard/brand-breakdown";
import { DashboardCharts } from "@/components/dashboard/dashboard-charts";
import { DataConfidence } from "@/components/clm/data-confidence";
import { CLM_TREND_STYLES, type ClmTrend } from "@/lib/clm-trend";
import { getCountryName } from "@/lib/countries";
import { cn, formatInteger, formatPercent } from "@/lib/utils";
import { formatMonthLabel } from "@/lib/reports/month";
import { isTagged } from "@/lib/reports/insights";
import type { VaeInsight, ClmInsight, Takeaway } from "@/lib/reports/insights";
import type { fetchDashboardData } from "@/lib/queries/dashboard";
import type { ClmDashboardData } from "@/lib/clm-dashboard";

type VaeData = Awaited<ReturnType<typeof fetchDashboardData>>;

type Props = {
  month: string;
  availableMonths: string[];
  activeScope: string;
  vae: VaeData | null;
  clm: ClmDashboardData | null;
  takeaways: Takeaway[];
  vaeInsight: VaeInsight | null;
  clmInsight: ClmInsight | null;
  trendSeries: VaeData["monthlySeries"];
  presentationTrends: Record<string, ClmTrend>;
  // Otsuka's published scorecard figure for this month, if there is one.
  officialClmRate: number | undefined;
};

function TrendBadge({ trend }: { trend: ClmTrend | undefined }) {
  if (!trend || trend === "inactive") return null;
  const config = CLM_TREND_STYLES[trend];
  if (!config) return null;
  return (
    <span
      className={cn(
        "inline-flex shrink-0 items-center rounded-full border px-2 py-0.5 text-[10px] font-semibold uppercase tracking-wide",
        config.className,
      )}
    >
      {config.label}
    </span>
  );
}

function SectionHeading({ eyebrow, title }: { eyebrow: string; title: string }) {
  return (
    <div className="flex items-center gap-3">
      <span className="h-6 w-1.5 shrink-0 rounded-full bg-[#F7993A]" aria-hidden="true" />
      <div>
        <p className="caption text-[10px] uppercase tracking-[0.2em] text-slate-400">{eyebrow}</p>
        <h2 className="text-lg font-black tracking-tight text-slate-900">{title}</h2>
      </div>
    </div>
  );
}

// The report had three caveat lines in three different styles (italic, plain,
// varying margins). One style, one place in the visual hierarchy.
function FootNote({ children }: { children: React.ReactNode }) {
  return <p className="px-1 text-xs leading-relaxed text-slate-400">{children}</p>;
}

function TrendChip({ label, deltaPts }: { label: string; deltaPts: number }) {
  const isFlat = Math.abs(deltaPts) < 0.5;
  const isUp = deltaPts > 0;
  const tone = isFlat
    ? "bg-slate-100 text-slate-600"
    : isUp
      ? "bg-emerald-50 text-emerald-700"
      : "bg-rose-50 text-rose-700";
  const arrow = isFlat ? "→" : isUp ? "▲" : "▼";

  return (
    <span className={`inline-flex items-center gap-1 rounded-full px-2.5 py-1 text-xs font-semibold ${tone}`}>
      <span aria-hidden="true">{arrow}</span>
      {label} {isFlat ? "flat" : `${Math.abs(deltaPts).toFixed(1)}pts`} vs last month
    </span>
  );
}

// One takeaway = a labelled subject, its figures, and the suggested action.
// Same three tones the rest of the report uses: neutral blue, good green,
// needs-attention orange.
const TAKEAWAY_TONES = {
  neutral: { keyline: "#2663AC", label: "text-[#2663AC]" },
  good: { keyline: "#12805c", label: "text-emerald-700" },
  warn: { keyline: "#F7993A", label: "text-[#c9741e]" },
} as const;

function TakeawayCard({ item }: { item: Takeaway }) {
  const tone = TAKEAWAY_TONES[item.tone];
  return (
    <Card className="flex h-full flex-col p-4 print:break-inside-avoid">
      <div className="absolute left-0 top-0 h-1 w-full" style={{ backgroundColor: tone.keyline }} />
      <p className={cn("caption text-[10px] uppercase tracking-[0.16em]", tone.label)}>{item.label}</p>
      <p title={item.subject} className="mt-1.5 line-clamp-2 text-sm font-semibold leading-snug text-slate-900">
        {item.subject}
      </p>
      <dl className="mt-3 flex flex-wrap gap-x-5 gap-y-2">
        {item.metrics.map((metric) => (
          <div key={metric.label} className="min-w-0">
            <dd className="text-xl font-black leading-none tracking-tight tabular-nums text-slate-900">
              {metric.value}
            </dd>
            <dt className="mt-1 text-[11px] leading-tight text-slate-500">{metric.label}</dt>
          </div>
        ))}
      </dl>
      {item.action ? (
        <p className="mt-auto pt-3 text-xs leading-snug text-slate-600">{item.action}</p>
      ) : null}
      {item.explain ? (
        <p className={cn("pt-2 text-[11px] italic leading-snug text-slate-400", item.action ? "" : "mt-auto")}>
          {item.explain}
        </p>
      ) : null}
    </Card>
  );
}

function ClmStatCard({
  label,
  value,
  accent,
  format,
  suffix,
  sub,
}: {
  label: string;
  value: number;
  accent: string;
  format?: "decimal";
  suffix?: string;
  sub?: string;
}) {
  return (
    <Card className="relative min-h-[102px] overflow-hidden border-[#d8e4f3] bg-[linear-gradient(145deg,#ffffff_0%,#f6fbff_82%)] p-3">
      <div
        className="pointer-events-none absolute -right-10 -top-10 h-20 w-20 rounded-full opacity-20 blur-2xl"
        style={{ backgroundColor: accent }}
      />
      <div className="absolute left-0 top-0 h-1 w-full" style={{ backgroundColor: accent }} />
      <p className="caption text-[10px] uppercase tracking-[0.18em] text-slate-500">{label}</p>
      <p className="mt-1 text-[42px] font-black leading-[0.86] tracking-tight text-slate-900">
        <AnimatedCounter value={value} format={format} decimals={format === "decimal" ? 1 : 0} suffix={suffix} />
      </p>
      {sub ? <p className="mt-1.5 text-[11px] leading-tight text-slate-500">{sub}</p> : null}
    </Card>
  );
}

function MiniRankList({
  title,
  rows,
  pillTone,
}: {
  title: string;
  rows: Array<{ key: string; label: string; sub: string; value: string; trend?: ClmTrend }>;
  pillTone: "blue" | "orange";
}) {
  const pillClass = pillTone === "blue" ? "bg-[#eef5ff] text-[#2663AC]" : "bg-[#fff4e8] text-[#d9852c]";
  return (
    <Card className="overflow-hidden p-0 print:break-inside-avoid">
      <div className="border-b border-[#dbe7f5] px-4 py-3">
        <h3 className="text-sm font-semibold text-slate-900">{title}</h3>
      </div>
      <div className="divide-y divide-[#e2ebf7]">
        {rows.length > 0 ? (
          rows.map((row) => (
            <div key={row.key} className="flex items-center justify-between gap-3 px-4 py-2.5 text-sm">
              <div className="min-w-0">
                <p title={row.label} className="truncate font-medium text-slate-800">{row.label}</p>
                <div className="flex flex-wrap items-center gap-1.5">
                  {row.sub ? <p className="truncate text-xs text-slate-500">{row.sub}</p> : null}
                  <TrendBadge trend={row.trend} />
                </div>
              </div>
              <span className={`shrink-0 rounded-full px-2.5 py-0.5 text-xs font-semibold ${pillClass}`}>
                {row.value}
              </span>
            </div>
          ))
        ) : (
          <div className="px-4 py-5 text-sm text-slate-500">No data for this period.</div>
        )}
      </div>
    </Card>
  );
}

function SpotlightPair({
  title,
  best,
  worst,
  bestValueLabel,
  worstValueLabel,
  bestNote,
  worstNote,
}: {
  title: string;
  best: { country_code: string } | null;
  worst: { country_code: string } | null;
  bestValueLabel: string;
  worstValueLabel: string;
  bestNote: string;
  worstNote: string;
}) {
  if (!best) return null;
  return (
    <div className="grid gap-3 sm:grid-cols-2 print:break-inside-avoid">
      <Card className="border-emerald-200 bg-[linear-gradient(160deg,#ffffff_0%,#f2fbf6_100%)] p-4">
        <p className="caption text-[10px] uppercase tracking-[0.16em] text-emerald-700">{title} — Leading</p>
        <p className="mt-1 text-lg font-black text-slate-900">{getCountryName(best.country_code)}</p>
        <p className="mt-0.5 text-sm font-semibold text-emerald-700">{bestValueLabel}</p>
        <p className="mt-1 text-xs text-slate-500">{bestNote}</p>
      </Card>
      {worst ? (
        <Card className="border-rose-200 bg-[linear-gradient(160deg,#ffffff_0%,#fdf3f4_100%)] p-4">
          <p className="caption text-[10px] uppercase tracking-[0.16em] text-rose-700">{title} — Needs Support</p>
          <p className="mt-1 text-lg font-black text-slate-900">{getCountryName(worst.country_code)}</p>
          <p className="mt-0.5 text-sm font-semibold text-rose-700">{worstValueLabel}</p>
          <p className="mt-1 text-xs text-slate-500">{worstNote}</p>
        </Card>
      ) : null}
    </div>
  );
}

export function MonthlyReportView({
  month,
  availableMonths,
  activeScope,
  vae,
  clm,
  takeaways,
  vaeInsight,
  clmInsight,
  trendSeries,
  presentationTrends,
  officialClmRate,
}: Props) {
  const router = useRouter();
  const pathname = usePathname();
  const searchParams = useSearchParams();
  const [isPending, startTransition] = useTransition();
  const [isExporting, setIsExporting] = useState(false);

  async function handlePptxExport() {
    setIsExporting(true);
    try {
      const { exportMonthlyReportPptx } = await import("@/lib/reports/pptx-export");
      await exportMonthlyReportPptx({
        month,
        activeScope,
        vae,
        clm,
        takeaways: takeaways.map((item) => item.text),
        vaeInsight,
        clmInsight,
        trendSeries,
        officialClmRate,
      });
    } finally {
      setIsExporting(false);
    }
  }

  // Untagged sends are dropped from the brand mix, so the chart can cover a
  // fraction of the month's volume. Report that fraction rather than let the
  // chart imply the region barely sent anything.
  const untaggedSends = (vae?.brandBreakdown ?? [])
    .filter((row) => !isTagged(row))
    .reduce((sum, row) => sum + Number(row.sent ?? 0), 0);

  function handleMonthChange(nextMonth: string) {
    const params = new URLSearchParams(searchParams.toString());
    params.set("month", nextMonth);
    startTransition(() => {
      router.replace(`${pathname}?${params.toString()}`, { scroll: false });
    });
  }

  const generatedAt = new Intl.DateTimeFormat("en-GB", {
    day: "2-digit",
    month: "short",
    year: "numeric",
    hour: "2-digit",
    minute: "2-digit",
  }).format(new Date());

  return (
    <div className="space-y-4 pb-8">
      <div className="print:hidden flex flex-wrap items-end justify-between gap-3 rounded-2xl border border-[#dbe7f5] bg-white px-4 py-3">
        <div>
          <h2 className="text-xl font-black tracking-tight text-slate-900">Monthly Report</h2>
          <p className="mt-1 text-sm text-slate-600">
            VAE + CLM performance for one month, in a single printable pack.
          </p>
        </div>
        <div className="flex flex-wrap items-end gap-2">
          <div>
            <label className="mb-1 block text-[10px] uppercase tracking-[0.14em] text-slate-500">Month</label>
            <Select
              aria-label="Report month"
              value={month}
              onChange={(event) => handleMonthChange(event.target.value)}
              className="h-11 rounded-xl border-[#ceddee] bg-white text-sm font-medium"
            >
              {availableMonths.map((m) => (
                <option key={m} value={m}>
                  {formatMonthLabel(m)}
                </option>
              ))}
            </Select>
          </div>
          <Button onClick={handlePptxExport} disabled={(!vae && !clm) || isExporting}>
            {isExporting ? "Exporting..." : "Export PowerPoint"}
          </Button>
          <Button onClick={() => window.print()} disabled={!vae && !clm}>
            Print / Save as PDF
          </Button>
        </div>
      </div>

      {isPending ? (
        <div className="print:hidden flex items-center gap-3 rounded-2xl border border-[#dbe7f5] bg-white px-5 py-4">
          <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">Rebuilding report...</p>
        </div>
      ) : null}

      {!vae && !clm ? (
        <div className="rounded-2xl border border-slate-200 bg-white px-6 py-12 text-center text-sm text-slate-500">
          No dated data available yet to build a report.
        </div>
      ) : (
        <div
          aria-busy={isPending}
          className={cn("space-y-5 transition-opacity", isPending && "pointer-events-none opacity-40")}
        >
          <div className="rounded-3xl bg-[linear-gradient(135deg,#2C6BB6_0%,#255ea3_55%,#1d4f8c_100%)] px-5 py-6 text-white shadow-[0_22px_40px_-28px_rgba(38,99,172,0.6)] sm:px-8 print:rounded-none print:shadow-none">
            <p className="text-xs font-semibold uppercase tracking-[0.24em] text-[#F7993A]">
              Otsuka{activeScope ? ` — ${activeScope}` : ""}
            </p>
            <h1 className="mt-1 text-2xl font-black tracking-tight sm:text-3xl">Monthly Performance Report</h1>
            <p className="mt-1.5 text-sm text-blue-100">
              {formatMonthLabel(month)} &middot; generated {generatedAt}
            </p>
          </div>

          {takeaways.length > 0 ? (
            <div className="space-y-3 print:break-inside-avoid">
              <SectionHeading eyebrow="Summary" title="Key Takeaways" />
              <div className="grid gap-2.5 md:grid-cols-2 xl:grid-cols-3">
                {takeaways.map((item) => (
                  <TakeawayCard key={item.id} item={item} />
                ))}
              </div>
            </div>
          ) : null}

          {vae && vaeInsight ? (
            <div className="space-y-3 print:break-inside-avoid">
              <div className="flex flex-wrap items-center justify-between gap-2">
                <SectionHeading eyebrow="Veeva Approved Email" title="VAE Performance" />
                <div className="flex flex-wrap gap-2 print:hidden">
                  <TrendChip label="Open Rate" deltaPts={vaeInsight.openRateDeltaPts} />
                  <TrendChip label="CTR" deltaPts={vaeInsight.ctrDeltaPts} />
                </div>
              </div>
              <KpiHighlights kpis={vae.kpis} />
              <KpiCards kpis={vae.kpis} />
              {trendSeries.length > 1 ? (
                <div className="print:break-inside-avoid">
                  <DashboardCharts
                    rows={trendSeries}
                    selectedFilters={{ from: "", to: "", country: "", brand: "", scope: activeScope }}
                    selectedMonth={month}
                  />
                  <div className="mt-1.5">
                    <FootNote>
                      Trailing {trendSeries.length} months, ending {formatMonthLabel(month)}. The highlighted bar is
                      the reported month.
                    </FootNote>
                  </div>
                </div>
              ) : null}
              <SpotlightPair
                title="Market"
                best={vaeInsight.bestCountry}
                worst={vaeInsight.worstCountry}
                bestValueLabel={vaeInsight.bestCountry ? formatPercent(vaeInsight.bestCountry.open_rate) + " open rate" : ""}
                worstValueLabel={vaeInsight.worstCountry ? formatPercent(vaeInsight.worstCountry.open_rate) + " open rate" : ""}
                bestNote="Worth sharing what's working here with other markets."
                worstNote="Consider a content or targeting review for this market."
              />
              <div className="space-y-3">
                <FootNote>Tagged content only. Excludes sends still awaiting brand metadata.</FootNote>
                <RankedDocuments
                  title="Top performing emails"
                  rows={vae.topDocuments.filter(isTagged).slice(0, 4)}
                  emptyMessage="Not enough volume to rank top performers."
                  tone="top"
                />
                <RankedDocuments
                  title="Lowest performing emails"
                  rows={vae.worstDocuments.filter(isTagged).slice(0, 4)}
                  emptyMessage="Not enough volume to rank low performers."
                  tone="low"
                />
              </div>
              <div className="space-y-1.5 print:break-inside-avoid">
                <BrandBreakdown rows={vae.brandBreakdown.filter(isTagged)} />
                {untaggedSends > 0 ? (
                  <FootNote>
                    Mix covers {formatInteger(vae.kpis.total_emails_sent - untaggedSends)} of{" "}
                    {formatInteger(vae.kpis.total_emails_sent)} sends. {formatInteger(untaggedSends)} are not yet
                    brand-tagged in the data library and are excluded.
                  </FootNote>
                ) : null}
              </div>
            </div>
          ) : null}

          {clm && clmInsight ? (
            <div className="space-y-3 print:break-before-page">
              <div className="flex flex-wrap items-center justify-between gap-2">
                <SectionHeading eyebrow="Call Logging" title="CLM Performance" />
                <div className="flex flex-wrap gap-2 print:hidden">
                  <TrendChip label="CLM Adoption" deltaPts={clmInsight.clmRateDeltaPts} />
                </div>
              </div>
              <div className="grid grid-cols-2 gap-2.5 sm:grid-cols-3 xl:grid-cols-5">
                {/* Otsuka's published figure leads — same orange hero as the CLM
                    dashboard, so the number the client already circulates is the
                    number they see first. Ours sits next to it, labelled. */}
                <Card className="relative min-h-[102px] overflow-hidden border-[#db822c] !bg-[linear-gradient(155deg,#f7a043_0%,#f28f32_56%,#e58124_100%)] p-3 text-white">
                  <p className="caption text-[10px] uppercase tracking-[0.18em] text-white">CLM Usage Rate</p>
                  <p className="mt-1 text-[42px] font-black leading-[0.86] tracking-tight text-white">
                    {officialClmRate !== undefined ? (
                      <AnimatedCounter value={officialClmRate} format="decimal" decimals={1} suffix="%" />
                    ) : (
                      <span className="opacity-60">&mdash;</span>
                    )}
                  </p>
                  <p className="mt-1.5 text-[11px] leading-tight text-white/75">
                    {officialClmRate !== undefined ? "Otsuka scorecard" : "Not published for this month"}
                  </p>
                </Card>
                <ClmStatCard
                  label="CLM-linked Calls"
                  value={clmInsight.clmRate * 100}
                  accent="#2663AC"
                  format="decimal"
                  suffix="%"
                  sub="Measured from clickstream"
                />
                <ClmStatCard label="Clickstream Events" value={clm.summary.clickstreamEvents} accent="#2663AC" />
                <ClmStatCard label="Unique Calls" value={clm.summary.uniqueCalls} accent="#F7993A" />
                <ClmStatCard label="Presentations Used" value={clm.summary.uniquePresentations} accent="#2663AC" />
              </div>
              {officialClmRate !== undefined ? (
                <FootNote>
                  Otsuka&apos;s scorecard figure comes from their CRM and covers all calls; ours counts calls with
                  tracked CLM clickstream in this report&apos;s scope. A gap between the two is expected.
                </FootNote>
              ) : null}
              {clm.dateReadiness ? (
                <DataConfidence
                  coverage={clm.dateReadiness.clickstreamDateCoverage}
                  eventsWithDates={clm.dateReadiness.clickstreamEventsWithDates}
                  eventsInScope={clm.dateReadiness.clickstreamEventsInScope}
                  clmCallDatesAvailable={clm.dateReadiness.clmCallDatesAvailable}
                />
              ) : null}
              <SpotlightPair
                title="CLM Adoption"
                best={clmInsight.bestCountry}
                worst={clmInsight.worstCountry}
                bestValueLabel={clmInsight.bestCountry ? formatPercent(clmInsight.bestCountry.clm_rate) + " of calls" : ""}
                worstValueLabel={clmInsight.worstCountry ? formatPercent(clmInsight.worstCountry.clm_rate) + " of calls" : ""}
                bestNote="A strong reference team for CLM adoption coaching."
                worstNote="A coaching opportunity — consider a refresher on pulling up approved content."
              />
              <div className="grid gap-3 lg:grid-cols-2 xl:grid-cols-3">
                <MiniRankList
                  title="Most-Used Presentations"
                  pillTone="blue"
                  rows={clm.topPresentations.map((row) => ({
                    key: row.label,
                    label: row.label,
                    sub: "",
                    value: `${formatInteger(row.count)} views`,
                    trend: presentationTrends[row.label],
                  }))}
                />
                <MiniRankList
                  title="Top Products Discussed"
                  pillTone="orange"
                  rows={clm.topProducts.map((row) => ({
                    key: row.label,
                    label: row.label,
                    sub: "",
                    value: formatInteger(row.count),
                  }))}
                />
                <MiniRankList
                  title="By Country"
                  pillTone="blue"
                  rows={clm.countryBreakdown.map((row) => ({
                    key: row.country_code,
                    label: getCountryName(row.country_code),
                    sub: `${formatInteger(row.total_clickstream_events)} events`,
                    value: formatPercent(row.clm_rate),
                  }))}
                />
              </div>
            </div>
          ) : null}
        </div>
      )}
    </div>
  );
}
