"use client";

import { Suspense } from "react";
import Link from "next/link";
import { AlertTriangle, Bell, BellRing, Check, CheckCheck, Info, OctagonAlert, Settings2, X } from "lucide-react";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Card } from "@/components/ui/card";
import { Checkbox } from "@/components/ui/checkbox";
import { Skeleton } from "@/components/ui/skeleton";
import { Spinner } from "@/components/ui/spinner";
import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip";
import { DataTablePagination } from "@/components/app/data-table";
import { ActiveFilters, FilterSelect } from "@/components/app/filters";
import { ListPageSkeleton, PageContent, PageHeader } from "@/components/app/page";
import { cn } from "@/lib/utils";
import ProtectedRoute from "../auth/protected-route";
import AppShell from "../components/app-shell";
import { EmptyState, ErrorState } from "../components/ui/page-states";
import StatusBadge from "../components/ui/status-badge";
import { formatDateTime, humanize } from "../lib/format";
import { useUrlFilters } from "../lib/useUrlFilters";
import { INBOX_TABS, SEVERITY_OPTIONS, useNotificationInbox } from "./useNotificationInbox";

const SEVERITY_ICON = {
  critical: { icon: OctagonAlert, className: "text-destructive", label: "Critical" },
  warning: { icon: AlertTriangle, className: "text-warning", label: "Warning" },
  info: { icon: Info, className: "text-info", label: "Info" },
  normal: { icon: Bell, className: "text-muted-foreground", label: "Normal" },
};

export function NotificationsPage() {
  return <ProtectedRoute><AppShell title="Notifications" subtitle="Inbox">
    <Suspense fallback={<ListPageSkeleton filters={1} rows={6} />}><NotificationInbox /></Suspense>
  </AppShell></ProtectedRoute>;
}

function NotificationInbox() {
  const { state, update, clear } = useUrlFilters(["tab", "severity", "page"]);
  const tab = INBOX_TABS.some((entry) => entry.value === state.tab) ? state.tab : "unread";
  const inbox = useNotificationInbox({ tab, severity: state.severity, page: state.page });
  const firstLoad = inbox.isLoading && !inbox.hasLoaded;
  const chips = state.severity ? [{ key: "severity", label: "Severity", value: humanize(state.severity) }] : [];
  const allUnreadSelected = inbox.unreadOnPage.length > 0 && inbox.unreadOnPage.every((item) => inbox.selected.has(item.id));

  return <PageContent className="max-w-5xl">
    <PageHeader
      title="Notifications"
      description={`${inbox.unreadCount} unread. Assignments, approvals, failed inspections, shipment and payment alerts for you. Open one to go to the record.`}
      actions={<>
        <Button variant="outline" size="sm" asChild><Link href="/settings/notifications"><Settings2 /> Preferences</Link></Button>
        <Tooltip>
          <TooltipTrigger asChild>
            <span tabIndex={inbox.unreadCount ? -1 : 0}>
              <Button variant="outline" size="sm" disabled={!inbox.unreadCount || inbox.isBulkBusy} onClick={inbox.markAllRead}>{inbox.isBulkBusy ? <Spinner /> : <CheckCheck />} Mark all read</Button>
            </span>
          </TooltipTrigger>
          {!inbox.unreadCount && <TooltipContent>Nothing unread</TooltipContent>}
        </Tooltip>
      </>}
    />

    <div className="flex flex-col gap-3">
      <div className="flex flex-wrap items-center gap-2">
        <Tabs value={tab} onValueChange={(next) => update({ tab: next === "unread" ? "" : next })}>
          <TabsList>
            {INBOX_TABS.map((entry) => <TabsTrigger key={entry.value} value={entry.value}>
              {entry.label}{entry.value === "unread" && inbox.unreadCount > 0 && <Badge variant="secondary" className="ml-1 tabular-nums">{inbox.unreadCount}</Badge>}
            </TabsTrigger>)}
          </TabsList>
        </Tabs>
        <FilterSelect label="Severity" value={state.severity} onChange={(severity) => update({ severity })} options={SEVERITY_OPTIONS} allLabel="Any severity" />
      </div>
      <ActiveFilters chips={chips} onRemove={() => update({ severity: "" })} onClear={clear} />
    </div>

    <Card className="gap-0 overflow-hidden py-0">
      {inbox.unreadOnPage.length > 0 && <div className="flex flex-wrap items-center gap-3 border-b bg-muted/40 px-4 py-2 text-sm">
        <Checkbox id="select-unread" checked={allUnreadSelected} onCheckedChange={(on) => inbox.selectAllUnread(Boolean(on))} aria-label="Select all unread on this page" />
        <label htmlFor="select-unread" className="text-muted-foreground">{inbox.selected.size ? `${inbox.selected.size} selected` : "Select unread on this page"}</label>
        {inbox.selected.size > 0 && <Button variant="outline" size="sm" className="ml-auto" disabled={inbox.isBulkBusy} onClick={inbox.markSelectedRead}>{inbox.isBulkBusy ? <Spinner /> : <Check />} Mark selected read</Button>}
      </div>}

      <div className={cn("transition-opacity", inbox.isLoading && inbox.hasLoaded && "opacity-60")}>
        {firstLoad && <div role="status" aria-label="Loading notifications">{Array.from({ length: 6 }).map((_, index) => <div key={index} className="flex gap-3 border-b px-4 py-4 last:border-0">
          <Skeleton className="size-4 rounded-sm" /><Skeleton className="size-5 rounded-full" />
          <div className="grid flex-1 gap-2"><Skeleton className="h-4 w-2/3" /><Skeleton className="h-3 w-full max-w-md" /><Skeleton className="h-3 w-28" /></div>
          <Skeleton className="h-8 w-24" />
        </div>)}</div>}
        {!firstLoad && inbox.error && <ErrorState compact error={inbox.error} title="Notifications could not be loaded" onRetry={inbox.refresh} />}
        {!firstLoad && !inbox.error && !inbox.items.length && <EmptyState
          compact
          icon={BellRing}
          filtered={Boolean(state.severity)}
          onClearFilters={() => update({ severity: "" })}
          title={state.severity ? "No notifications match this severity" : tab === "unread" ? "You're all caught up" : tab === "dismissed" ? "Nothing dismissed" : "No notifications yet"}
          detail={state.severity ? "Choose another severity or clear the filter." : tab === "unread" ? "New assignments, approvals, and alerts will appear here and on the bell." : tab === "dismissed" ? "Notifications you dismiss are kept here." : "Assignments, failed inspections, and shipment updates appear here."}
          action={tab === "unread" && !state.severity ? <Button variant="outline" size="sm" onClick={() => update({ tab: "all" })}>View all</Button> : null}
        />}
        {!inbox.error && inbox.items.map((item) => <NotificationRow key={item.id} item={item} inbox={inbox} />)}
      </div>
      {inbox.meta && inbox.meta.total > 0 && <DataTablePagination pagination={inbox.meta} onPageChange={(page) => update({ page: String(page) })} noun="notifications" />}
    </Card>
  </PageContent>;
}

function NotificationRow({ item, inbox }) {
  const { notification } = item;
  const severity = SEVERITY_ICON[notification.severity] || SEVERITY_ICON.normal;
  const SeverityIcon = severity.icon;
  const unread = item.state === "unread";
  const route = notification.actionRoute;

  return <div className={cn("flex gap-3 border-b px-4 py-3 last:border-0", unread && "bg-primary/[0.03]")}>
    <div className="flex w-4 shrink-0 justify-center pt-0.5">
      {unread && <Checkbox checked={inbox.selected.has(item.id)} onCheckedChange={(on) => inbox.toggleSelected(item.id, Boolean(on))} aria-label={`Select ${notification.title}`} />}
    </div>
    <span className="pt-0.5" title={severity.label}><SeverityIcon className={cn("size-4", severity.className)} aria-label={`${severity.label} severity`} /></span>
    <div className="grid min-w-0 flex-1 gap-0.5 text-sm">
      <div className="flex flex-wrap items-center gap-2">
        {route
          ? <Link href={route} onClick={() => inbox.openItem(item)} className={cn("break-words hover:underline", unread ? "font-semibold" : "font-medium text-foreground/90")}>{notification.title}</Link>
          : <span className={cn("break-words", unread ? "font-semibold" : "font-medium text-foreground/90")}>{notification.title}</span>}
        {unread && <span className="sr-only">Unread</span>}
        {item.state !== "unread" && item.state !== "read" && <StatusBadge status={item.state} />}
      </div>
      {notification.summary && <p className="break-words text-muted-foreground">{notification.summary}</p>}
      <p className="text-xs text-muted-foreground">
        {formatDateTime(notification.createdAt, "")} · {humanize(notification.type)}
        {item.acknowledgedAt && ` · Acknowledged ${formatDateTime(item.acknowledgedAt, "")}`}
      </p>
    </div>
    <div className="flex shrink-0 flex-wrap items-start justify-end gap-1">
      {unread && <Button variant="ghost" size="sm" disabled={inbox.isPending(item, "read")} onClick={() => inbox.markRead(item)}>{inbox.isPending(item, "read") ? <Spinner /> : <Check />}<span className="hidden sm:inline">Mark read</span></Button>}
      {(item.state === "unread" || item.state === "read") && <Tooltip>
        <TooltipTrigger asChild><Button variant="outline" size="sm" disabled={inbox.isPending(item, "acknowledge")} onClick={() => inbox.acknowledge(item)}>{inbox.isPending(item, "acknowledge") ? <Spinner /> : <CheckCheck />}<span className="hidden sm:inline">Acknowledge</span></Button></TooltipTrigger>
        <TooltipContent>Confirm you have seen this and are handling it (saved to the activity log)</TooltipContent>
      </Tooltip>}
      {item.state !== "dismissed" && <Tooltip>
        <TooltipTrigger asChild><Button variant="ghost" size="icon-sm" disabled={inbox.isPending(item, "dismiss")} onClick={() => inbox.dismiss(item)} aria-label={`Dismiss ${notification.title}`}>{inbox.isPending(item, "dismiss") ? <Spinner /> : <X />}</Button></TooltipTrigger>
        <TooltipContent>Dismiss (kept under the Dismissed tab)</TooltipContent>
      </Tooltip>}
    </div>
  </div>;
}
