"use client";

import Link from "next/link";
import { useEffect, useState } from "react";
import { Download, Search } from "lucide-react";
import { Badge, EmptyState, Input, PageHeader, Panel, Skeleton } from "@/components/ui/kit";
import { FilterTabs, Pager, StatTile } from "@/components/admin/common";
import { LineChart } from "@/components/charts/line-chart";
import { useSession } from "@/components/session";
import { qs } from "@/lib/api";
import { formatDateTime, formatPaise } from "@/lib/format";
import { useApi } from "@/lib/use-api";
import { useToday } from "@/lib/use-today";

type Tab = "messaging" | "campaigns" | "automation" | "usage";
type Meta = { from: string; to: string; timezone: string };

const pct = (v: number | null) => (v === null ? "—" : `${(v * 100).toFixed(v > 0 && v < 0.1 ? 1 : 0)}%`);

const daysBefore = (day: string, n: number) => new Date(Date.parse(`${day}T00:00:00Z`) - n * 86400_000).toISOString().slice(0, 10);

function Range({ from, to, today, onChange }: { from: string; to: string; today: string; onChange: (from: string, to: string) => void }) {
  const preset = (days: number) => onChange(daysBefore(today, days - 1), today);
  return (
    <div className="flex flex-wrap items-end gap-2">
      <div className="flex rounded-lg border border-line bg-white p-0.5 text-sm" role="group" aria-label="Quick ranges">
        {[7, 30, 90].map((n) => (
          <button key={n} type="button" onClick={() => preset(n)} className="rounded-md px-3 py-1.5 hover:bg-paper">
            {n} days
          </button>
        ))}
      </div>
      <label className="text-[13px] text-muted">
        From
        <Input type="date" className="mt-0.5 block w-40" value={from} max={to} onChange={(e) => e.target.value && onChange(e.target.value, to)} />
      </label>
      <label className="text-[13px] text-muted">
        To
        <Input type="date" className="mt-0.5 block w-40" value={to} min={from} max={today} onChange={(e) => e.target.value && onChange(from, e.target.value)} />
      </label>
    </div>
  );
}

function ExportLink({ report, from, to }: { report: string; from: string; to: string }) {
  return (
    <a href={`/api/analytics/export${qs({ report, from, to })}`} className="inline-flex items-center gap-1.5 rounded-lg border border-line bg-white px-3 py-1.5 text-sm font-medium hover:bg-paper">
      <Download className="size-4" /> Export CSV
    </a>
  );
}

interface Messaging {
  days: Record<string, string | number>[];
  totals: Record<string, number>;
  rates: { delivered: number | null; read: number | null; failed: number | null };
  failures: { error_code: number | null; message: string | null; count: number }[];
  sources: Record<string, number>;
  types: Record<string, number>;
}
const SOURCE_LABEL: Record<string, string> = { team: "Your team (inbox)", flow: "Bot flows", bot_reply: "Bot replies", campaign_or_api: "Campaigns and API" };

function MessagingView({ from, to }: { from: string; to: string }) {
  const { data, error } = useApi<{ data: Messaging; meta: Meta }>(`/analytics/messaging${qs({ from, to })}`);
  if (error) return <p className="rounded-md bg-brick-soft px-4 py-3 text-sm text-brick">{error}</p>;
  if (!data) return <Skeleton className="h-96" />;
  const m = data.data;
  const days = m.days.map((d) => ({ day: d.day, sent: Number(d.sent) + Number(d.delivered) + Number(d.read) + Number(d.failed), delivered: Number(d.delivered) + Number(d.read), received: d.received }));
  return (
    <>
      <div className="mb-6 grid grid-cols-2 gap-3 lg:grid-cols-5">
        <StatTile label="Sent" value={m.totals.outbound.toLocaleString("en-IN")} />
        <StatTile label="Delivered" value={pct(m.rates.delivered)} sub={`${(m.totals.delivered + m.totals.read).toLocaleString("en-IN")} messages`} />
        <StatTile label="Read" value={pct(m.rates.read)} sub={`${m.totals.read.toLocaleString("en-IN")} messages`} />
        <StatTile label="Failed" value={pct(m.rates.failed)} sub={`${m.totals.failed.toLocaleString("en-IN")} messages`} tone={m.totals.failed ? "brick" : undefined} />
        <StatTile label="Received" value={m.totals.received.toLocaleString("en-IN")} sub="from customers" />
      </div>
      <Panel className="mb-6 p-5">
        <div className="mb-3 flex flex-wrap items-center justify-between gap-2">
          <h2 className="font-semibold">Messages per day</h2>
          <ExportLink report="messaging" from={from} to={to} />
        </div>
        <LineChart
          label="Messages sent, delivered and received per day"
          days={days}
          series={[
            { key: "sent", label: "Sent" },
            { key: "delivered", label: "Delivered" },
            { key: "received", label: "Received" },
          ]}
        />
        <p className="mt-2 text-xs text-muted">Days in {data.meta.timezone}. Delivered includes messages that were read.</p>
      </Panel>
      <div className="grid gap-6 lg:grid-cols-2">
        <Panel>
          <h2 className="border-b border-line px-5 py-3 font-semibold">Who sent your messages</h2>
          <ul className="divide-y divide-line">
            {Object.entries(SOURCE_LABEL).map(([k, label]) => (
              <li key={k} className="flex justify-between px-5 py-2.5 text-sm">
                <span>{label}</span>
                <span className="tabular">{(m.sources[k] ?? 0).toLocaleString("en-IN")}</span>
              </li>
            ))}
          </ul>
        </Panel>
        <Panel>
          <h2 className="border-b border-line px-5 py-3 font-semibold">Why messages failed</h2>
          {m.failures.length === 0 ? (
            <p className="px-5 py-8 text-center text-sm text-muted">No failed messages in this period.</p>
          ) : (
            <ul className="divide-y divide-line">
              {m.failures.map((f) => (
                <li key={String(f.error_code)} className="flex items-start gap-3 px-5 py-2.5 text-sm">
                  <span className="min-w-0 flex-1">
                    <span className="font-medium">{f.error_code ? `Error ${f.error_code}` : "Unknown error"}</span>
                    <span className="block truncate text-[13px] text-muted">{f.message ?? "No details from WhatsApp"}</span>
                  </span>
                  <span className="tabular">{f.count.toLocaleString("en-IN")}</span>
                </li>
              ))}
            </ul>
          )}
        </Panel>
      </div>
    </>
  );
}

interface CampaignRow {
  id: number;
  title: string;
  status: string;
  template: string;
  started_at: string | null;
  stats: Record<string, number>;
  delivery_rate: number | null;
  read_rate: number | null;
}

function CampaignsView({ from, to }: { from: string; to: string }) {
  const [term, setTerm] = useState("");
  const [q, setQ] = useState("");
  const [page, setPage] = useState(1);
  useEffect(() => {
    const t = setTimeout(() => setQ(term.trim()), 300);
    return () => clearTimeout(t);
  }, [term]);
  const { data } = useApi<{ data: CampaignRow[]; meta: { total: number; last_page: number } }>(`/analytics/campaigns${qs({ from, to, q, page })}`);
  return (
    <Panel>
      <div className="flex flex-wrap items-center gap-3 border-b border-line px-5 py-3">
        <div className="relative min-w-0 flex-1 sm:max-w-xs">
          <Search className="pointer-events-none absolute left-3 top-1/2 size-4 -translate-y-1/2 text-muted" />
          <Input aria-label="Search campaigns" placeholder="Search campaigns" className="w-full pl-9" value={term} onChange={(e) => (setTerm(e.target.value), setPage(1))} />
        </div>
        <span className="ml-auto">
          <ExportLink report="campaigns" from={from} to={to} />
        </span>
      </div>
      {!data ? (
        <Skeleton className="m-5 h-40" />
      ) : data.data.length === 0 ? (
        <p className="px-5 py-10 text-center text-sm text-muted">No campaigns in this period{q ? " match that search" : ""}.</p>
      ) : (
        <>
          <div className="relative overflow-x-auto">
            <table className="w-full min-w-[760px] text-sm">
              <thead className="text-left text-[13px] text-muted">
                <tr>
                  <th className="px-5 py-2.5 font-medium">Campaign</th>
                  <th className="px-3 py-2.5 font-medium">Started</th>
                  <th className="px-3 py-2.5 text-right font-medium">Recipients</th>
                  <th className="px-3 py-2.5 text-right font-medium">Delivered</th>
                  <th className="px-3 py-2.5 text-right font-medium">Read</th>
                  <th className="px-5 py-2.5 text-right font-medium">Failed</th>
                </tr>
              </thead>
              <tbody className="divide-y divide-line border-t border-line">
                {data.data.map((c) => (
                  <tr key={c.id}>
                    <td className="px-5 py-2.5">
                      <Link href={`/campaigns/${c.id}`} className="font-medium hover:text-teal">
                        {c.title}
                      </Link>
                      <span className="block text-[13px] text-muted">{c.template}</span>
                    </td>
                    <td className="px-3 py-2.5 text-muted">{c.started_at ? formatDateTime(c.started_at) : <Badge>{c.status}</Badge>}</td>
                    <td className="tabular px-3 py-2.5 text-right">{(c.stats.total ?? 0).toLocaleString("en-IN")}</td>
                    <td className="tabular px-3 py-2.5 text-right">{pct(c.delivery_rate)}</td>
                    <td className="tabular px-3 py-2.5 text-right">{pct(c.read_rate)}</td>
                    <td className="tabular px-5 py-2.5 text-right">{(c.stats.failed ?? 0).toLocaleString("en-IN")}</td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
          <Pager page={page} last={data.meta.last_page} total={data.meta.total} onPage={setPage} />
        </>
      )}
    </Panel>
  );
}

interface Automation {
  flows: { id: number; title: string; total: number; by_status: Record<string, number>; completion_rate: number | null }[];
  replies: { id: number; name: string; trigger_type: string; sent: number }[];
  runs_per_day: Record<string, string | number>[];
}

function AutomationView({ from, to }: { from: string; to: string }) {
  const { data } = useApi<{ data: Automation }>(`/analytics/automation${qs({ from, to })}`);
  if (!data) return <Skeleton className="h-96" />;
  const a = data.data;
  return (
    <>
      <Panel className="mb-6">
        <div className="flex flex-wrap items-center justify-between gap-2 border-b border-line px-5 py-3">
          <h2 className="font-semibold">Bot flow runs</h2>
          <ExportLink report="automation" from={from} to={to} />
        </div>
        {a.flows.length === 0 ? (
          <p className="px-5 py-10 text-center text-sm text-muted">No flow runs in this period.</p>
        ) : (
          <div className="relative overflow-x-auto">
            <table className="w-full min-w-[720px] text-sm">
              <thead className="text-left text-[13px] text-muted">
                <tr>
                  <th className="px-5 py-2.5 font-medium">Flow</th>
                  <th className="px-3 py-2.5 text-right font-medium">Runs</th>
                  <th className="px-3 py-2.5 text-right font-medium">Completed</th>
                  <th className="px-3 py-2.5 text-right font-medium">Handed to team</th>
                  <th className="px-3 py-2.5 text-right font-medium">Failed</th>
                  <th className="px-5 py-2.5 text-right font-medium">Finished</th>
                </tr>
              </thead>
              <tbody className="divide-y divide-line border-t border-line">
                {a.flows.map((f) => (
                  <tr key={f.id}>
                    <td className="px-5 py-2.5">
                      <Link href={`/bot-flows/${f.id}`} className="font-medium hover:text-teal">
                        {f.title}
                      </Link>
                    </td>
                    <td className="tabular px-3 py-2.5 text-right">{f.total}</td>
                    <td className="tabular px-3 py-2.5 text-right">{f.by_status.completed ?? 0}</td>
                    <td className="tabular px-3 py-2.5 text-right">{f.by_status.handed_off ?? 0}</td>
                    <td className="tabular px-3 py-2.5 text-right">{f.by_status.failed ?? 0}</td>
                    <td className="tabular px-5 py-2.5 text-right">{pct(f.completion_rate)}</td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        )}
      </Panel>
      <Panel>
        <h2 className="border-b border-line px-5 py-3 font-semibold">Bot replies sent</h2>
        {a.replies.length === 0 ? (
          <p className="px-5 py-8 text-center text-sm text-muted">No bot replies sent in this period.</p>
        ) : (
          <ul className="divide-y divide-line">
            {a.replies.map((r) => (
              <li key={r.id} className="flex justify-between px-5 py-2.5 text-sm">
                <Link href="/bot-replies" className="hover:text-teal">
                  {r.name}
                </Link>
                <span className="tabular">{r.sent.toLocaleString("en-IN")}</span>
              </li>
            ))}
          </ul>
        )}
      </Panel>
    </>
  );
}

interface Usage {
  days: { day: string; messages: number; charged_paise: number; pending_paise: number; free: number }[];
  by_category: { category: string; messages: number; charged_paise: number }[];
  ledger: { type: string; entries: number; amount_paise: number }[];
}
const LEDGER_LABEL: Record<string, string> = { recharge: "Recharges", usage: "Message charges", subscription: "Plan payments", refund: "Refunds", refund_reversal: "Refund reversals", adjustment: "Adjustments" };

function UsageView({ from, to }: { from: string; to: string }) {
  const { data, error } = useApi<{ data: Usage }>(`/analytics/usage${qs({ from, to })}`);
  if (error) return <p className="rounded-md bg-brick-soft px-4 py-3 text-sm text-brick">{error}</p>;
  if (!data) return <Skeleton className="h-96" />;
  const u = data.data;
  const charged = u.days.reduce((a, d) => a + d.charged_paise, 0);
  const pending = u.days.reduce((a, d) => a + d.pending_paise, 0);
  return (
    <>
      <div className="mb-6 grid grid-cols-2 gap-3 lg:grid-cols-4">
        <StatTile label="Template messages" value={u.days.reduce((a, d) => a + d.messages, 0).toLocaleString("en-IN")} />
        <StatTile label="Charged" value={formatPaise(charged)} />
        <StatTile label="Awaiting confirmation" value={formatPaise(pending)} />
        <StatTile label="Free" value={u.days.reduce((a, d) => a + d.free, 0).toLocaleString("en-IN")} sub="service window and free entry points" />
      </div>
      <div className="grid gap-6 lg:grid-cols-2">
        <Panel>
          <div className="flex items-center justify-between border-b border-line px-5 py-3">
            <h2 className="font-semibold">Charges by category</h2>
            <ExportLink report="usage" from={from} to={to} />
          </div>
          {u.by_category.length === 0 ? (
            <p className="px-5 py-8 text-center text-sm text-muted">No charged messages in this period.</p>
          ) : (
            <ul className="divide-y divide-line">
              {u.by_category.map((c) => (
                <li key={c.category} className="flex justify-between px-5 py-2.5 text-sm capitalize">
                  <span>
                    {c.category} <span className="text-muted normal-case">({c.messages.toLocaleString("en-IN")})</span>
                  </span>
                  <span className="tabular">{formatPaise(c.charged_paise)}</span>
                </li>
              ))}
            </ul>
          )}
        </Panel>
        <Panel>
          <div className="flex items-center justify-between border-b border-line px-5 py-3">
            <h2 className="font-semibold">Wallet transactions</h2>
            <ExportLink report="ledger" from={from} to={to} />
          </div>
          {u.ledger.length === 0 ? (
            <p className="px-5 py-8 text-center text-sm text-muted">No wallet transactions in this period.</p>
          ) : (
            <ul className="divide-y divide-line">
              {u.ledger.map((l) => (
                <li key={l.type} className="flex justify-between px-5 py-2.5 text-sm">
                  <span>
                    {LEDGER_LABEL[l.type] ?? l.type} <span className="text-muted">({l.entries})</span>
                  </span>
                  <span className="tabular">{formatPaise(l.amount_paise)}</span>
                </li>
              ))}
            </ul>
          )}
        </Panel>
      </div>
    </>
  );
}

export default function AnalyticsPage() {
  const today = useToday();
  if (!today) return <Skeleton className="h-96" />;
  return <Analytics today={today} />;
}

function Analytics({ today }: { today: string }) {
  const { can } = useSession();
  const [tab, setTab] = useState<Tab>("messaging");
  const [range, setRange] = useState(() => ({ from: daysBefore(today, 29), to: today }));
  const tabs: [Tab, string][] = [
    ["messaging", "Messaging"],
    ...(can("campaigns.view") ? ([["campaigns", "Campaigns"]] as [Tab, string][]) : []),
    ...(can("bots.view") ? ([["automation", "Bots"]] as [Tab, string][]) : []),
    ...(can("billing.view") ? ([["usage", "Usage and wallet"]] as [Tab, string][]) : []),
  ];
  if (!can("analytics.view")) return <EmptyState icon={<Search />} title="No access" body="You don't have permission to see analytics." />;
  return (
    <>
      <PageHeader title="Analytics" description="How your messages, campaigns and bots performed. Export any report as CSV." />
      <div className="mb-5 flex flex-col gap-3 lg:flex-row lg:items-end lg:justify-between">
        <FilterTabs label="Reports" value={tab} onChange={setTab} options={tabs} />
        <Range from={range.from} to={range.to} today={today} onChange={(from, to) => setRange({ from, to })} />
      </div>
      {tab === "messaging" && <MessagingView {...range} />}
      {tab === "campaigns" && <CampaignsView {...range} />}
      {tab === "automation" && <AutomationView {...range} />}
      {tab === "usage" && <UsageView {...range} />}
    </>
  );
}
