"use client";

import { useEffect, useMemo, useState } from "react";
import Link from "next/link";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Card, CardContent } from "@/components/ui/card";
import { EmptyState } from "@/components/ui/empty-state";
import { Kpi, KpiStrip } from "@/components/ui/kpi";
import { Skeleton } from "@/components/ui/skeleton";
import { Tooltip } from "@/components/ui/tooltip";
import {
  SegmentedControl,
  SegmentedControlItem,
} from "@/components/ui/segmented-control";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuLabel,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { useAlertConfirm } from "@/components/ui/alert-dialog";
import { useToast } from "@/components/ui/toast";
import {
  ACTIVITY_STORAGE_KEY,
  clearActivity,
  loadActivity,
  type ActivityEntry,
  type ActivitySource,
} from "@/lib/activity/log";
import { ALL_ORGANIZATIONS } from "@/lib/sag/entities";
import { formatCurrency } from "@/lib/utils";

type RangeFilter = "all" | "today" | "week" | "month" | "all-time";

const SOURCE_LABEL: Record<ActivitySource, string> = {
  bills: "Bills",
  plaid: "Plaid",
  subscriptions: "Subscriptions",
  "owner-draws": "Owner draws",
  "tax-pack": "Tax pack",
  ncdor: "NCDOR",
  hemp: "Hemp",
  abc: "ABC",
  ttb: "TTB",
  filings: "Filings",
  licenses: "Licenses",
  domains: "Domains",
  "annual-report": "Annual report",
  hr: "HR",
  pto: "PTO",
  payroll: "Payroll",
  hiring: "Hiring",
  "offer-letters": "Offer letters",
  onboarding: "Onboarding",
  docs: "Docs",
  social: "Social",
  music: "Music",
  mail: "Mail",
  research: "Research",
  agents: "Agents",
  council: "Council",
  system: "System",
};

const SOURCE_TONE: Record<
  ActivitySource,
  "default" | "secondary" | "outline" | "success" | "warning" | "info" | "destructive"
> = {
  bills: "info",
  plaid: "info",
  subscriptions: "info",
  "owner-draws": "success",
  "tax-pack": "info",
  ncdor: "warning",
  hemp: "warning",
  abc: "warning",
  ttb: "warning",
  filings: "warning",
  licenses: "warning",
  domains: "secondary",
  "annual-report": "warning",
  hr: "secondary",
  pto: "secondary",
  payroll: "secondary",
  hiring: "secondary",
  "offer-letters": "secondary",
  onboarding: "secondary",
  docs: "outline",
  social: "outline",
  music: "outline",
  mail: "outline",
  research: "outline",
  agents: "default",
  council: "default",
  system: "outline",
};

function startOfTodayMs(): number {
  const d = new Date();
  d.setHours(0, 0, 0, 0);
  return d.getTime();
}

function startOfWeekMs(): number {
  const d = new Date();
  d.setHours(0, 0, 0, 0);
  // Treat Monday as start of week.
  const day = d.getDay();
  const diff = (day + 6) % 7;
  d.setDate(d.getDate() - diff);
  return d.getTime();
}

function startOfMonthMs(): number {
  const d = new Date();
  d.setHours(0, 0, 0, 0);
  d.setDate(1);
  return d.getTime();
}

function rangeStartMs(range: RangeFilter): number | null {
  switch (range) {
    case "today":
      return startOfTodayMs();
    case "week":
      return startOfWeekMs();
    case "month":
      return startOfMonthMs();
    case "all":
    case "all-time":
      return null;
  }
}

function formatRelative(iso: string, nowMs: number): string {
  const t = new Date(iso).getTime();
  if (!Number.isFinite(t)) return "—";
  const diffSec = Math.round((nowMs - t) / 1000);
  if (diffSec < 60) return diffSec <= 1 ? "just now" : `${diffSec}s ago`;
  const diffMin = Math.round(diffSec / 60);
  if (diffMin < 60) return `${diffMin}m ago`;
  const diffHr = Math.round(diffMin / 60);
  if (diffHr < 24) return `${diffHr}h ago`;
  const diffDay = Math.round(diffHr / 24);
  if (diffDay < 30) return `${diffDay}d ago`;
  const diffMo = Math.round(diffDay / 30);
  if (diffMo < 12) return `${diffMo}mo ago`;
  const diffYr = Math.round(diffMo / 12);
  return `${diffYr}y ago`;
}

function formatAbsolute(iso: string): string {
  const d = new Date(iso);
  if (Number.isNaN(d.getTime())) return iso;
  return d.toLocaleString("en-US", {
    year: "numeric",
    month: "short",
    day: "numeric",
    hour: "numeric",
    minute: "2-digit",
  });
}

export function ActivityLog() {
  const [loaded, setLoaded] = useState(false);
  const [entries, setEntries] = useState<ActivityEntry[]>([]);
  const [range, setRange] = useState<RangeFilter>("all");
  const [sourceFilter, setSourceFilter] = useState<ActivitySource | "all">("all");
  const [entityFilter, setEntityFilter] = useState<string>("all");
  const [nowMs, setNowMs] = useState<number>(() => Date.now());
  const { toast } = useToast();
  const { confirm: confirmAlert, AlertConfirmPortal } = useAlertConfirm();

  // Initial load + cross-tab sync.
  useEffect(() => {
    // eslint-disable-next-line react-hooks/set-state-in-effect -- one-time hydration from localStorage
    setEntries(loadActivity());
    setLoaded(true);

    function onStorage(e: StorageEvent) {
      if (e.key === ACTIVITY_STORAGE_KEY) {
        setEntries(loadActivity());
      }
    }
    window.addEventListener("storage", onStorage);
    return () => window.removeEventListener("storage", onStorage);
  }, []);

  // Refresh "X minutes ago" labels once a minute.
  useEffect(() => {
    const id = setInterval(() => setNowMs(Date.now()), 60_000);
    return () => clearInterval(id);
  }, []);

  // KPI counters always operate on the full log (independent of filters).
  const counters = useMemo(() => {
    const today = startOfTodayMs();
    const week = startOfWeekMs();
    const month = startOfMonthMs();
    let countToday = 0;
    let countWeek = 0;
    let countMonth = 0;
    for (const e of entries) {
      const t = new Date(e.timestamp).getTime();
      if (!Number.isFinite(t)) continue;
      if (t >= today) countToday += 1;
      if (t >= week) countWeek += 1;
      if (t >= month) countMonth += 1;
    }
    return {
      today: countToday,
      week: countWeek,
      month: countMonth,
      total: entries.length,
    };
  }, [entries]);

  // All sources / entities that exist in the log (for the filter dropdowns).
  const presentSources = useMemo(() => {
    const set = new Set<ActivitySource>();
    for (const e of entries) set.add(e.source);
    return Array.from(set).sort((a, b) =>
      SOURCE_LABEL[a].localeCompare(SOURCE_LABEL[b]),
    );
  }, [entries]);

  const presentEntities = useMemo(() => {
    const slugs = new Set<string>();
    for (const e of entries) {
      if (e.entitySlug) slugs.add(e.entitySlug);
    }
    return Array.from(slugs)
      .map((slug) => {
        const org = ALL_ORGANIZATIONS.find((o) => o.slug === slug);
        return { slug, label: org ? `${org.emoji ?? "🏢"} ${org.name}` : slug };
      })
      .sort((a, b) => a.label.localeCompare(b.label));
  }, [entries]);

  // Apply filters for the visible list.
  const filtered = useMemo(() => {
    const cutoff = rangeStartMs(range);
    return entries.filter((e) => {
      if (sourceFilter !== "all" && e.source !== sourceFilter) return false;
      if (entityFilter !== "all" && e.entitySlug !== entityFilter) return false;
      if (cutoff != null) {
        const t = new Date(e.timestamp).getTime();
        if (!Number.isFinite(t) || t < cutoff) return false;
      }
      return true;
    });
  }, [entries, range, sourceFilter, entityFilter]);

  async function handleClear() {
    const ok = await confirmAlert({
      title: "Clear the activity log?",
      description: `Removes all ${entries.length} tracked event${entries.length === 1 ? "" : "s"}. Underlying records (bills, filings, etc.) are unaffected. Cannot be undone.`,
      actionLabel: "Clear log",
      destructive: true,
    });
    if (!ok) return;
    clearActivity();
    setEntries([]);
    toast({
      title: "Activity log cleared",
      variant: "info",
    });
  }

  const sourceFilterLabel =
    sourceFilter === "all" ? "All sources" : SOURCE_LABEL[sourceFilter];
  const entityFilterLabel =
    entityFilter === "all"
      ? "All entities"
      : presentEntities.find((e) => e.slug === entityFilter)?.label ?? "Entity";

  if (!loaded) {
    return (
      <div className="space-y-6">
        <KpiStrip cols={4}>
          <Skeleton className="h-24" />
          <Skeleton className="h-24" />
          <Skeleton className="h-24" />
          <Skeleton className="h-24" />
        </KpiStrip>
        <Skeleton className="h-12" />
        <Skeleton className="h-64" />
      </div>
    );
  }

  return (
    <>
      <div className="space-y-6">
        <KpiStrip cols={4}>
          <Kpi label="Today" value={String(counters.today)} />
          <Kpi label="This week" value={String(counters.week)} />
          <Kpi label="This month" value={String(counters.month)} />
          <Kpi label="Total tracked" value={String(counters.total)} tone="brand" />
        </KpiStrip>

        <Card>
          <CardContent className="p-4 flex flex-wrap items-center gap-3">
            <SegmentedControl
              value={range}
              onValueChange={(v) => setRange(v as RangeFilter)}
              aria-label="Filter by time range"
              className="flex-wrap"
            >
              <SegmentedControlItem value="all">All</SegmentedControlItem>
              <SegmentedControlItem value="today">Today</SegmentedControlItem>
              <SegmentedControlItem value="week">Week</SegmentedControlItem>
              <SegmentedControlItem value="month">Month</SegmentedControlItem>
              <SegmentedControlItem value="all-time">All time</SegmentedControlItem>
            </SegmentedControl>

            <DropdownMenu>
              <DropdownMenuTrigger>
                <span className="inline-flex h-9 items-center gap-2 rounded-md border border-input bg-background px-3 text-xs font-medium hover:bg-accent">
                  Source: {sourceFilterLabel}
                  <span aria-hidden="true">▾</span>
                </span>
              </DropdownMenuTrigger>
              <DropdownMenuContent className="max-h-80 overflow-y-auto">
                <DropdownMenuLabel>Filter by source</DropdownMenuLabel>
                <DropdownMenuItem onSelect={() => setSourceFilter("all")}>
                  All sources
                </DropdownMenuItem>
                {presentSources.length > 0 && <DropdownMenuSeparator />}
                {presentSources.map((s) => (
                  <DropdownMenuItem key={s} onSelect={() => setSourceFilter(s)}>
                    {SOURCE_LABEL[s]}
                  </DropdownMenuItem>
                ))}
              </DropdownMenuContent>
            </DropdownMenu>

            <DropdownMenu>
              <DropdownMenuTrigger>
                <span className="inline-flex h-9 items-center gap-2 rounded-md border border-input bg-background px-3 text-xs font-medium hover:bg-accent">
                  Entity: {entityFilterLabel}
                  <span aria-hidden="true">▾</span>
                </span>
              </DropdownMenuTrigger>
              <DropdownMenuContent className="max-h-80 overflow-y-auto">
                <DropdownMenuLabel>Filter by entity</DropdownMenuLabel>
                <DropdownMenuItem onSelect={() => setEntityFilter("all")}>
                  All entities
                </DropdownMenuItem>
                {presentEntities.length > 0 && <DropdownMenuSeparator />}
                {presentEntities.map((e) => (
                  <DropdownMenuItem
                    key={e.slug}
                    onSelect={() => setEntityFilter(e.slug)}
                  >
                    {e.label}
                  </DropdownMenuItem>
                ))}
              </DropdownMenuContent>
            </DropdownMenu>

            <span className="text-xs text-muted-foreground tabular-nums">
              {filtered.length} of {entries.length}
            </span>

            <Button
              variant="ghost"
              size="sm"
              className="ml-auto text-destructive hover:text-destructive"
              onClick={handleClear}
              disabled={entries.length === 0}
            >
              Clear log
            </Button>
          </CardContent>
        </Card>

        {filtered.length === 0 ? (
          <EmptyState
            icon="📜"
            title={
              entries.length === 0
                ? "No activity logged yet"
                : "No entries match the current filters"
            }
            description={
              entries.length === 0
                ? "As you pay bills, file taxes, log draws, or update employees, those changes will appear here in reverse-chronological order."
                : "Adjust the range, source, or entity filters above to see more."
            }
          />
        ) : (
          <Card>
            <CardContent className="p-0">
              <div className="overflow-x-auto">
                <table className="w-full min-w-[720px] text-sm">
                  <thead className="section-label border-b">
                    <tr>
                      <th className="px-3 py-2 text-left">When</th>
                      <th className="px-3 py-2 text-left">Source</th>
                      <th className="px-3 py-2 text-left">Verb</th>
                      <th className="px-3 py-2 text-left">What happened</th>
                      <th className="px-3 py-2 text-left">Entity</th>
                      <th className="px-3 py-2 text-right">Amount</th>
                    </tr>
                  </thead>
                  <tbody>
                    {filtered.map((e) => {
                      const org = e.entitySlug
                        ? ALL_ORGANIZATIONS.find((o) => o.slug === e.entitySlug)
                        : undefined;
                      return (
                        <tr
                          key={e.id}
                          className="border-b last:border-0 align-middle hover:bg-muted/10"
                        >
                          <td className="px-3 py-2 whitespace-nowrap">
                            <Tooltip content={formatAbsolute(e.timestamp)}>
                              <span className="text-xs text-muted-foreground tabular-nums">
                                {formatRelative(e.timestamp, nowMs)}
                              </span>
                            </Tooltip>
                          </td>
                          <td className="px-3 py-2">
                            <Badge
                              variant={SOURCE_TONE[e.source]}
                              className="text-[10px]"
                            >
                              {SOURCE_LABEL[e.source]}
                            </Badge>
                          </td>
                          <td className="px-3 py-2">
                            <Badge variant="outline" className="text-[10px]">
                              {e.verb}
                            </Badge>
                          </td>
                          <td className="px-3 py-2">
                            {e.href ? (
                              <Link
                                href={e.href}
                                className="text-foreground hover:underline"
                              >
                                {e.title}
                              </Link>
                            ) : (
                              <span className="text-foreground">{e.title}</span>
                            )}
                          </td>
                          <td className="px-3 py-2 text-xs text-muted-foreground">
                            {org ? (
                              <span className="inline-flex items-center gap-1">
                                {org.emoji} {org.name}
                              </span>
                            ) : e.entitySlug ? (
                              <span className="font-mono">{e.entitySlug}</span>
                            ) : (
                              "—"
                            )}
                          </td>
                          <td className="px-3 py-2 text-right tabular-nums">
                            {e.amount != null ? formatCurrency(e.amount) : "—"}
                          </td>
                        </tr>
                      );
                    })}
                  </tbody>
                </table>
              </div>
            </CardContent>
          </Card>
        )}

        <p className="text-xs text-muted-foreground">
          Activity is stored locally in this browser at{" "}
          <code className="font-mono">{ACTIVITY_STORAGE_KEY}</code>. The log
          keeps the most recent 500 events; older entries roll off automatically.
        </p>
      </div>
      <AlertConfirmPortal />
    </>
  );
}
