"use client";

import { useEffect, useMemo, useState } from "react";
import type { ComponentType, ReactNode } from "react";
import { ChevronDown, Eye, Globe2, MonitorSmartphone, Network, TrendingUp } from "lucide-react";
import { AdminGuard } from "@/components/admin/AdminGuard";
import { AdminShell } from "@/components/admin/AdminShell";
import { adminRequest } from "@/lib/admin-api";

type AnalyticsData = {
  totalViews: number;
  viewsToday: number;
  views7Days: number;
  serviceViews: number;
  uniqueIps: number;
  dailyViews: Array<{ day: string; views: number; uniqueIps: number }>;
  topPages: Array<{ pagePath: string; views: number; uniqueIps: number; lastViewedAt: string }>;
  topServicePages: Array<{
    serviceSlug: string;
    serviceLabel: string;
    pagePath: string;
    views: number;
    uniqueIps: number;
    lastViewedAt: string;
  }>;
  topIps: Array<{
    ipAddress: string;
    views: number;
    uniquePages: number;
    lastViewedAt: string;
  }>;
  recentViews: Array<{
    id: string;
    pagePath: string;
    serviceLabel: string | null;
    referrer: string | null;
    userAgent: string | null;
    ipAddress: string | null;
    viewedAt: string;
  }>;
};

type AnalyticsSection = "dailyViews" | "topIps" | "topPages" | "topServicePages" | "recentViews";

const previewLimits: Record<AnalyticsSection, number> = {
  dailyViews: 7,
  topIps: 5,
  topPages: 5,
  topServicePages: 5,
  recentViews: 8,
};

function formatCount(value: number | null) {
  return value === null ? "..." : value.toLocaleString("en-IN");
}

function formatDate(value: string | null) {
  if (!value) {
    return "-";
  }

  return new Intl.DateTimeFormat("en-IN", {
    day: "numeric",
    month: "short",
    hour: "numeric",
    minute: "2-digit",
  }).format(new Date(value));
}

function formatDay(value: string) {
  return new Intl.DateTimeFormat("en-IN", {
    day: "numeric",
    month: "short",
  }).format(new Date(value));
}

function getBrowserLabel(userAgent: string | null) {
  if (!userAgent) {
    return "Unknown";
  }

  if (userAgent.includes("Edg/")) return "Edge";
  if (userAgent.includes("Chrome/")) return "Chrome";
  if (userAgent.includes("Safari/")) return "Safari";
  if (userAgent.includes("Firefox/")) return "Firefox";

  return "Browser";
}

function StatCard({
  label,
  value,
  icon: Icon,
}: {
  label: string;
  value: number | null;
  icon: ComponentType<{ className?: string }>;
}) {
  return (
    <article className="rounded-lg border border-border bg-white p-6 shadow-sm">
      <div className="flex items-center justify-between gap-4">
        <div>
          <p className="text-xs font-black uppercase tracking-[0.16em] text-muted-foreground">
            {label}
          </p>
          <p className="mt-3 text-4xl font-black text-foreground">{formatCount(value)}</p>
        </div>
        <div className="grid h-12 w-12 place-items-center rounded-md bg-primary/10 text-primary">
          <Icon className="h-6 w-6" />
        </div>
      </div>
    </article>
  );
}

export default function AdminAnalyticsPage() {
  const [analytics, setAnalytics] = useState<AnalyticsData | null>(null);
  const [error, setError] = useState<string | null>(null);
  const [expandedSections, setExpandedSections] = useState<Record<AnalyticsSection, boolean>>({
    dailyViews: false,
    topIps: false,
    topPages: false,
    topServicePages: false,
    recentViews: false,
  });

  useEffect(() => {
    adminRequest<AnalyticsData>("/api/admin/analytics")
      .then((data) => {
        setAnalytics(data);
        setError(null);
      })
      .catch((loadError) => {
        setError(loadError instanceof Error ? loadError.message : "Could not load analytics");
      });
  }, []);

  const maxDailyViews = useMemo(
    () => Math.max(1, ...(analytics?.dailyViews.map((item) => item.views) ?? [0])),
    [analytics],
  );
  const visibleDailyViews = getPreviewRows(
    analytics?.dailyViews ?? [],
    expandedSections.dailyViews,
    previewLimits.dailyViews,
    "end",
  );
  const visibleTopIps = getPreviewRows(
    analytics?.topIps ?? [],
    expandedSections.topIps,
    previewLimits.topIps,
  );
  const visibleRecentViews = getPreviewRows(
    analytics?.recentViews ?? [],
    expandedSections.recentViews,
    previewLimits.recentViews,
  );

  function toggleSection(section: AnalyticsSection) {
    setExpandedSections((current) => ({ ...current, [section]: !current[section] }));
  }

  return (
    <AdminGuard>
      <AdminShell
        title="Analytics"
        lead="Website traffic, service-page traffic, visitor IPs, and recent page opens."
      >
        {error ? (
          <div className="mb-5 rounded-lg border border-primary/20 bg-primary/5 p-4 text-sm font-bold text-primary">
            {error}
          </div>
        ) : null}

        <div className="grid gap-4 sm:grid-cols-2 xl:grid-cols-5">
          <StatCard label="Total website views" value={analytics?.totalViews ?? null} icon={Eye} />
          <StatCard label="Today" value={analytics?.viewsToday ?? null} icon={TrendingUp} />
          <StatCard label="Last 7 days" value={analytics?.views7Days ?? null} icon={Globe2} />
          <StatCard
            label="Service views"
            value={analytics?.serviceViews ?? null}
            icon={MonitorSmartphone}
          />
          <StatCard label="Unique IPs" value={analytics?.uniqueIps ?? null} icon={Network} />
        </div>

        <section className="mt-5 grid gap-4 xl:grid-cols-[1fr_1.25fr]">
          <PreviewCard
            title="14-day traffic"
            lead="Website page opens by day"
            shownCount={visibleDailyViews.length}
            totalCount={analytics?.dailyViews.length ?? 0}
            expanded={expandedSections.dailyViews}
            onToggle={() => toggleSection("dailyViews")}
          >
            <div className="flex h-52 items-end gap-2">
              {visibleDailyViews.length > 0 ? (
                visibleDailyViews.map((item) => (
                  <div key={item.day} className="flex min-w-0 flex-1 flex-col items-center gap-2">
                    <div className="flex h-36 w-full items-end rounded-md bg-slate-100 p-1">
                      <div
                        className="w-full rounded-sm bg-primary"
                        style={{ height: `${Math.max(7, (item.views / maxDailyViews) * 100)}%` }}
                      />
                    </div>
                    <p className="text-xs font-black text-foreground">{item.views}</p>
                    <p className="w-full truncate text-center text-[10px] font-bold uppercase tracking-[0.1em] text-muted-foreground">
                      {formatDay(item.day)}
                    </p>
                  </div>
                ))
              ) : (
                <div className="grid h-full w-full place-items-center rounded-md bg-slate-50 text-sm font-semibold text-muted-foreground">
                  No traffic has been tracked yet.
                </div>
              )}
            </div>
          </PreviewCard>

          <TableCard
            title="Top visitor IPs"
            lead="IPs ranked by most website views"
            shownCount={visibleTopIps.length}
            totalCount={analytics?.topIps.length ?? 0}
            expanded={expandedSections.topIps}
            onToggle={() => toggleSection("topIps")}
          >
            <table className="w-full min-w-[540px] text-left">
              <thead className="bg-slate-50 text-xs font-black uppercase tracking-[0.14em] text-muted-foreground">
                <tr>
                  <th className="px-5 py-3">IP address</th>
                  <th className="px-5 py-3 text-right">Views</th>
                  <th className="px-5 py-3 text-right">Pages</th>
                  <th className="px-5 py-3 text-right">Last visit</th>
                </tr>
              </thead>
              <tbody className="divide-y divide-border text-sm">
                {visibleTopIps.length > 0 ? (
                  visibleTopIps.map((item) => (
                    <tr key={item.ipAddress}>
                      <td className="px-5 py-4 font-black text-foreground">{item.ipAddress}</td>
                      <td className="px-5 py-4 text-right font-black text-foreground">
                        {item.views.toLocaleString("en-IN")}
                      </td>
                      <td className="px-5 py-4 text-right font-semibold text-muted-foreground">
                        {item.uniquePages}
                      </td>
                      <td className="px-5 py-4 text-right font-semibold text-muted-foreground">
                        {formatDate(item.lastViewedAt)}
                      </td>
                    </tr>
                  ))
                ) : (
                  <tr>
                    <td
                      colSpan={4}
                      className="px-5 py-8 text-center font-semibold text-muted-foreground"
                    >
                      No visitor IPs have been tracked yet.
                    </td>
                  </tr>
                )}
              </tbody>
            </table>
          </TableCard>
        </section>

        <section className="mt-5 grid gap-4 xl:grid-cols-2">
          <TrafficTable
            title="Top website pages"
            lead="All public pages ranked by visits"
            rows={analytics?.topPages ?? []}
            expanded={expandedSections.topPages}
            onToggle={() => toggleSection("topPages")}
            previewLimit={previewLimits.topPages}
          />
          <TrafficTable
            title="Top service pages"
            lead="Only service pages ranked by visits"
            rows={analytics?.topServicePages ?? []}
            expanded={expandedSections.topServicePages}
            onToggle={() => toggleSection("topServicePages")}
            previewLimit={previewLimits.topServicePages}
          />
        </section>

        <section className="mt-5">
          <TableCard
            title="Recent visits"
            lead="Latest tracked public page opens"
            shownCount={visibleRecentViews.length}
            totalCount={analytics?.recentViews.length ?? 0}
            expanded={expandedSections.recentViews}
            onToggle={() => toggleSection("recentViews")}
          >
            <table className="w-full min-w-[840px] text-left">
              <thead className="bg-slate-50 text-xs font-black uppercase tracking-[0.14em] text-muted-foreground">
                <tr>
                  <th className="px-5 py-3">Page</th>
                  <th className="px-5 py-3">IP</th>
                  <th className="px-5 py-3">Browser</th>
                  <th className="px-5 py-3">Referrer</th>
                  <th className="px-5 py-3 text-right">Time</th>
                </tr>
              </thead>
              <tbody className="divide-y divide-border text-sm">
                {visibleRecentViews.length > 0 ? (
                  visibleRecentViews.map((item) => (
                    <tr key={item.id}>
                      <td className="px-5 py-4">
                        <p className="font-black text-foreground">{item.pagePath}</p>
                        {item.serviceLabel ? (
                          <p className="mt-1 text-xs font-bold uppercase tracking-[0.14em] text-primary">
                            {item.serviceLabel}
                          </p>
                        ) : null}
                      </td>
                      <td className="px-5 py-4 font-semibold text-muted-foreground">
                        {item.ipAddress ?? "Unknown"}
                      </td>
                      <td className="px-5 py-4 font-semibold text-muted-foreground">
                        {getBrowserLabel(item.userAgent)}
                      </td>
                      <td className="max-w-[260px] truncate px-5 py-4 font-semibold text-muted-foreground">
                        {item.referrer || "-"}
                      </td>
                      <td className="px-5 py-4 text-right font-semibold text-muted-foreground">
                        {formatDate(item.viewedAt)}
                      </td>
                    </tr>
                  ))
                ) : (
                  <tr>
                    <td
                      colSpan={5}
                      className="px-5 py-8 text-center font-semibold text-muted-foreground"
                    >
                      No visits have been tracked yet.
                    </td>
                  </tr>
                )}
              </tbody>
            </table>
          </TableCard>
        </section>
      </AdminShell>
    </AdminGuard>
  );
}

function TableCard({
  title,
  lead,
  children,
  expanded,
  onToggle,
  shownCount,
  totalCount,
}: {
  title: string;
  lead: string;
  children: ReactNode;
  expanded: boolean;
  onToggle: () => void;
  shownCount: number;
  totalCount: number;
}) {
  return (
    <PreviewCard
      title={title}
      lead={lead}
      shownCount={shownCount}
      totalCount={totalCount}
      expanded={expanded}
      onToggle={onToggle}
    >
      <div className="overflow-x-auto">{children}</div>
    </PreviewCard>
  );
}

function PreviewCard({
  title,
  lead,
  children,
  expanded,
  onToggle,
  shownCount,
  totalCount,
}: {
  title: string;
  lead: string;
  children: ReactNode;
  expanded: boolean;
  onToggle: () => void;
  shownCount: number;
  totalCount: number;
}) {
  const canToggle = totalCount > shownCount || expanded;

  return (
    <article className="overflow-hidden rounded-lg border border-border bg-white shadow-sm">
      <div className="flex items-start justify-between gap-4 border-b border-border p-6">
        <span className="min-w-0">
          <h2 className="text-lg font-black tracking-tight text-foreground">{title}</h2>
          <p className="mt-1 text-sm font-semibold text-muted-foreground">{lead}</p>
        </span>
        <span className="shrink-0 rounded-md bg-slate-50 px-3 py-1 text-xs font-black text-muted-foreground">
          {shownCount} / {totalCount}
        </span>
      </div>
      <div className="p-6">{children}</div>
      {canToggle ? (
        <div className="border-t border-border bg-slate-50 px-6 py-4 text-center">
          <button
            type="button"
            onClick={onToggle}
            className="inline-flex h-10 items-center justify-center gap-2 rounded-md border border-border bg-white px-4 text-sm font-black text-muted-foreground transition hover:border-primary/30 hover:text-primary"
          >
            {expanded ? "Show less" : "Show more"}
            <ChevronDown className={`h-4 w-4 transition ${expanded ? "rotate-180" : ""}`} />
          </button>
        </div>
      ) : null}
    </article>
  );
}

function getPreviewRows<T>(
  rows: T[],
  expanded: boolean,
  previewLimit: number,
  direction: "start" | "end" = "start",
) {
  if (expanded || rows.length <= previewLimit) {
    return rows;
  }

  return direction === "end" ? rows.slice(-previewLimit) : rows.slice(0, previewLimit);
}

function TrafficTable({
  expanded,
  title,
  lead,
  onToggle,
  previewLimit,
  rows,
}: {
  title: string;
  lead: string;
  rows: Array<{
    pagePath: string;
    views: number;
    uniqueIps: number;
    lastViewedAt: string;
    serviceLabel?: string;
  }>;
  expanded: boolean;
  onToggle: () => void;
  previewLimit: number;
}) {
  const visibleRows = getPreviewRows(rows, expanded, previewLimit);

  return (
    <TableCard
      title={title}
      lead={lead}
      shownCount={visibleRows.length}
      totalCount={rows.length}
      expanded={expanded}
      onToggle={onToggle}
    >
      <table className="w-full min-w-[560px] text-left">
        <thead className="bg-slate-50 text-xs font-black uppercase tracking-[0.14em] text-muted-foreground">
          <tr>
            <th className="px-5 py-3">Page</th>
            <th className="px-5 py-3 text-right">Views</th>
            <th className="px-5 py-3 text-right">IPs</th>
            <th className="px-5 py-3 text-right">Last visit</th>
          </tr>
        </thead>
        <tbody className="divide-y divide-border text-sm">
          {visibleRows.length > 0 ? (
            visibleRows.map((item) => (
              <tr key={item.pagePath}>
                <td className="px-5 py-4">
                  <p className="font-black text-foreground">{item.serviceLabel ?? item.pagePath}</p>
                  {item.serviceLabel ? (
                    <p className="mt-1 font-semibold text-muted-foreground">{item.pagePath}</p>
                  ) : null}
                </td>
                <td className="px-5 py-4 text-right font-black text-foreground">
                  {item.views.toLocaleString("en-IN")}
                </td>
                <td className="px-5 py-4 text-right font-semibold text-muted-foreground">
                  {item.uniqueIps}
                </td>
                <td className="px-5 py-4 text-right font-semibold text-muted-foreground">
                  {formatDate(item.lastViewedAt)}
                </td>
              </tr>
            ))
          ) : (
            <tr>
              <td colSpan={4} className="px-5 py-8 text-center font-semibold text-muted-foreground">
                No traffic has been tracked yet.
              </td>
            </tr>
          )}
        </tbody>
      </table>
    </TableCard>
  );
}
