import { useCallback, useEffect, useMemo, useState } from "react"
import { Link } from "react-router"
import {
  Activity,
  AlertTriangle,
  Building2,
  CheckCircle2,
  CircleAlert,
  HeartPulse,
  RefreshCw,
  Users as UsersIcon,
} from "lucide-react"

import { useArcadiaClient } from "@crema/arcadia-core-client"
import { AlertBanner } from "@crema/feedback-ui"

import { AppShell } from "~/components/layout/app-shell"
import { PageHeader } from "~/components/layout/page-header"
import { Button } from "~/components/ui/button"
import { Skeleton } from "~/components/ui/skeleton"
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "~/components/ui/card"
import { listAuditLogs, type AuditLog } from "~/lib/arcadia/audit-logs"
import {
  getHealth,
  SUBSYSTEMS,
  type HealthStatus,
  type HealthSubsystem,
  type OverallHealth,
} from "~/lib/arcadia/health"
import { listTenants, type Tenant } from "~/lib/arcadia/tenants"
import { listUsers, type User } from "~/lib/arcadia/users"
import { useRegisterContext } from "@crema/aifirst-ui/context"
import { pageTitle } from "~/lib/page-meta"
import { errorMessage } from "~/lib/errors"
import { useSession } from "~/lib/session"

export const meta = () => pageTitle("Overview")

interface DashboardData {
  tenants: Tenant[]
  users: User[]
  audit: AuditLog[]
  health: OverallHealth | null
}

const EMPTY: DashboardData = { tenants: [], users: [], audit: [], health: null }

export default function HomeRoute() {
  const session = useSession()
  const arcadia = useArcadiaClient()

  const [data, setData] = useState<DashboardData>(EMPTY)
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState<unknown>(null)
  const [refreshedAt, setRefreshedAt] = useState<Date | null>(null)

  const refresh = useCallback(async () => {
    setError(null)
    setLoading(true)
    const [tenants, users, audit, health] = await Promise.all([
      listTenants(arcadia).catch((err) => {
        throw err
      }),
      listUsers(arcadia),
      listAuditLogs(arcadia, { limit: 10 }),
      getHealth(arcadia).catch(() => null),
    ]).catch((err) => {
      setError(err)
      return [[], [], [], null] as [Tenant[], User[], AuditLog[], OverallHealth | null]
    })
    setData({ tenants, users, audit, health })
    setRefreshedAt(new Date())
    setLoading(false)
  }, [arcadia])

  useEffect(() => {
    if (session) refresh()
  }, [session, refresh])

  const stats = useMemo(() => {
    const activeTenants = data.tenants.filter((t) => t.status === "active").length
    const activeUsers = data.users.filter((u) => u.status === "active").length
    const errorEvents = data.audit.filter(
      (a) => a.severity === "error" || a.severity === "critical",
    ).length
    return {
      tenants: { total: data.tenants.length, active: activeTenants },
      users: { total: data.users.length, active: activeUsers },
      audit: { recent: data.audit.length, errors: errorEvents },
      health: deriveOverallStatus(data.health),
    }
  }, [data])

  useRegisterContext("overview", stats)

  return (
    <AppShell>
      <PageHeader
        title="Overview"
        description={
          <>
            Live snapshot of the platform — tenants, users, recent activity, and health.
            {refreshedAt ? (
              <>
                {" "}
                Refreshed {refreshedAt.toLocaleTimeString()}.
              </>
            ) : null}
          </>
        }
        actions={
          <Button
            data-action="overview-refresh"
            variant="outline"
            size="sm"
            onClick={refresh}
            disabled={loading}
          >
            <RefreshCw className={loading ? "size-4 animate-spin" : "size-4"} />
            Refresh
          </Button>
        }
      />

      {error ? (
        <AlertBanner variant="error" dismissible onDismiss={() => setError(null)}>
          {errorMessage(error, "load the overview")}
        </AlertBanner>
      ) : null}

      <div className="grid gap-4 md:grid-cols-2 lg:grid-cols-4">
        <StatTile
          to="/tenants"
          dataAction="overview-tile-tenants"
          icon={Building2}
          label="Tenants"
          value={stats.tenants.total}
          sub={`${stats.tenants.active} active`}
          loading={loading}
        />
        <StatTile
          to="/users"
          dataAction="overview-tile-users"
          icon={UsersIcon}
          label="Users"
          value={stats.users.total}
          sub={`${stats.users.active} active`}
          loading={loading}
        />
        <StatTile
          to="/activity"
          dataAction="overview-tile-activity"
          icon={Activity}
          label="Recent events"
          value={stats.audit.recent}
          sub={
            stats.audit.errors > 0
              ? `${stats.audit.errors} error${stats.audit.errors === 1 ? "" : "s"}`
              : "no errors"
          }
          loading={loading}
          tone={stats.audit.errors > 0 ? "warning" : "default"}
        />
        <StatTile
          to="/monitoring"
          dataAction="overview-tile-health"
          icon={HeartPulse}
          label="Platform health"
          value={statusLabel(stats.health)}
          sub={data.health ? `as of ${new Date(data.health.checked_at).toLocaleTimeString()}` : "unreachable"}
          loading={loading}
          tone={statusTone(stats.health)}
        />
      </div>

      <div className="grid gap-4 lg:grid-cols-3">
        <Card className="lg:col-span-2">
          <CardHeader className="flex-row items-center justify-between gap-2">
            <div>
              <CardTitle>Recent activity</CardTitle>
              <CardDescription>
                Latest audit events across the platform.
              </CardDescription>
            </div>
            <Link
              to="/activity"
              data-action="overview-activity-all"
              className="text-xs font-medium text-muted-foreground hover:text-foreground"
            >
              View all →
            </Link>
          </CardHeader>
          <CardContent>
            <RecentActivity logs={data.audit} loading={loading} />
          </CardContent>
        </Card>

        <Card>
          <CardHeader>
            <CardTitle>Subsystems</CardTitle>
            <CardDescription>
              Live probe of each platform subsystem.
            </CardDescription>
          </CardHeader>
          <CardContent>
            <SubsystemList health={data.health} loading={loading} />
          </CardContent>
        </Card>
      </div>
    </AppShell>
  )
}

function StatTile({
  to,
  dataAction,
  icon: Icon,
  label,
  value,
  sub,
  loading,
  tone = "default",
}: {
  to: string
  dataAction: string
  icon: React.ComponentType<{ className?: string }>
  label: string
  value: number | string
  sub: string
  loading: boolean
  tone?: "default" | "warning" | "error" | "ok"
}) {
  const accent =
    tone === "error"
      ? "border-destructive/40 bg-destructive/5"
      : tone === "warning"
        ? "border-amber-500/40 bg-amber-500/5"
        : tone === "ok"
          ? "border-emerald-500/40 bg-emerald-500/5"
          : ""

  return (
    <Link
      to={to}
      data-action={dataAction}
      className="group block focus:outline-none"
    >
      <Card className={`h-full transition-colors hover:border-foreground/20 ${accent}`}>
        <CardHeader className="pb-2">
          <div className="flex items-center justify-between">
            <span className="text-xs font-medium uppercase tracking-wide text-muted-foreground">
              {label}
            </span>
            <Icon className="size-4 text-muted-foreground" />
          </div>
        </CardHeader>
        <CardContent className="flex flex-col gap-1">
          {loading ? (
            <Skeleton className="h-9 w-20" />
          ) : (
            <span className="text-3xl font-semibold tabular-nums">{value}</span>
          )}
          {loading ? (
            <Skeleton className="h-3 w-24" />
          ) : (
            <span className="text-xs text-muted-foreground">{sub}</span>
          )}
        </CardContent>
      </Card>
    </Link>
  )
}

function RecentActivity({ logs, loading }: { logs: AuditLog[]; loading: boolean }) {
  if (loading && logs.length === 0) {
    return (
      <p className="py-4 text-sm text-muted-foreground">
        <RefreshCw className="mr-1 inline size-3.5 animate-spin" /> Loading…
      </p>
    )
  }
  if (logs.length === 0) {
    return (
      <p className="py-4 text-sm text-muted-foreground">No recent events.</p>
    )
  }
  return (
    <ul className="flex flex-col divide-y">
      {logs.slice(0, 8).map((l) => (
        <li
          key={l.id}
          className="flex items-start justify-between gap-3 py-2.5 text-sm"
        >
          <div className="flex min-w-0 flex-col">
            <span className="flex items-center gap-2">
              <code className="rounded bg-muted px-1.5 py-0.5 font-mono text-xs">
                {l.action}
              </code>
              <span className="truncate text-xs text-muted-foreground">
                {l.resource_type}
                {l.resource_id ? ` · ${l.resource_id.slice(0, 8)}…` : ""}
              </span>
            </span>
            <span className="truncate text-xs text-muted-foreground">
              {l.user?.email ?? "system"}
            </span>
          </div>
          <div className="flex shrink-0 flex-col items-end gap-0.5">
            <SeverityDot severity={l.severity} />
            <time
              className="text-[11px] text-muted-foreground"
              dateTime={l.inserted_at}
            >
              {timeAgo(l.inserted_at)}
            </time>
          </div>
        </li>
      ))}
    </ul>
  )
}

function SubsystemList({
  health,
  loading,
}: {
  health: OverallHealth | null
  loading: boolean
}) {
  if (loading && !health) {
    return (
      <p className="py-4 text-sm text-muted-foreground">
        <RefreshCw className="mr-1 inline size-3.5 animate-spin" /> Probing…
      </p>
    )
  }
  if (!health) {
    return (
      <p className="py-4 text-sm text-muted-foreground">
        Health endpoint unreachable.
      </p>
    )
  }
  return (
    <ul className="flex flex-col divide-y">
      {SUBSYSTEMS.map((sys) => {
        const sub = health.subsystems[sys]
        return (
          <li
            key={sys}
            className="flex items-center justify-between gap-3 py-2.5 text-sm"
          >
            <span className="font-medium capitalize">{labelFor(sys)}</span>
            <span className="flex items-center gap-2">
              <StatusIcon status={sub?.status ?? "unconfigured"} />
              <span className="text-xs text-muted-foreground">
                {sub?.message ?? statusLabel(sub?.status ?? "unconfigured")}
              </span>
            </span>
          </li>
        )
      })}
    </ul>
  )
}

function SeverityDot({ severity }: { severity: string }) {
  const tone =
    severity === "critical" || severity === "error"
      ? "bg-destructive"
      : severity === "warning"
        ? "bg-amber-500"
        : "bg-emerald-500"
  return (
    <span
      aria-label={severity}
      title={severity}
      className={`size-2 rounded-full ${tone}`}
    />
  )
}

function StatusIcon({ status }: { status: HealthStatus }) {
  if (status === "ok")
    return <CheckCircle2 className="size-4 text-emerald-500" aria-label="ok" />
  if (status === "degraded")
    return <AlertTriangle className="size-4 text-amber-500" aria-label="degraded" />
  if (status === "error")
    return <CircleAlert className="size-4 text-destructive" aria-label="error" />
  return <CircleAlert className="size-4 text-muted-foreground" aria-label="unconfigured" />
}

function labelFor(sys: HealthSubsystem): string {
  if (sys === "api") return "API"
  if (sys === "db") return "Database"
  return sys
}

function statusLabel(status: HealthStatus | string): string {
  if (status === "ok") return "Healthy"
  if (status === "degraded") return "Degraded"
  if (status === "error") return "Down"
  return "Unknown"
}

/**
 * The overall health hero must never say "Unknown" while its own Subsystems
 * card reports everything Healthy. When the backend gives no meaningful overall
 * status (unknown/unconfigured/missing), derive it from the subsystem probes
 * the same card shows: any error → Down, any degraded → Degraded, otherwise
 * Healthy if at least one subsystem reported ok.
 */
function deriveOverallStatus(health: OverallHealth | null): HealthStatus | string {
  if (!health) return "unconfigured"
  if (health.status === "ok" || health.status === "degraded" || health.status === "error") {
    return health.status
  }
  const statuses = Object.values(health.subsystems ?? {}).map((s) => s?.status)
  if (statuses.some((s) => s === "error")) return "error"
  if (statuses.some((s) => s === "degraded")) return "degraded"
  if (statuses.some((s) => s === "ok")) return "ok"
  return health.status ?? "unconfigured"
}

function statusTone(status: HealthStatus | string): "default" | "ok" | "warning" | "error" {
  if (status === "ok") return "ok"
  if (status === "degraded") return "warning"
  if (status === "error") return "error"
  return "default"
}

function timeAgo(iso: string): string {
  const t = new Date(iso).getTime()
  if (Number.isNaN(t)) return ""
  const diff = Date.now() - t
  const sec = Math.round(diff / 1000)
  if (sec < 60) return `${sec}s ago`
  const min = Math.round(sec / 60)
  if (min < 60) return `${min}m ago`
  const hr = Math.round(min / 60)
  if (hr < 24) return `${hr}h ago`
  const d = Math.round(hr / 24)
  return `${d}d ago`
}

export { RouteErrorBoundary as ErrorBoundary } from "~/components/route-error"
