"use client";

import { useState } from "react";
import { AlertTriangleIcon, CheckCircle2Icon, CloudOffIcon, ClockIcon, PackageIcon, RefreshCwIcon, XCircleIcon, type LucideIcon } from "lucide-react";

import { Avatar, AvatarFallback } from "@/components/ui/avatar";
import { Button } from "@/components/ui/button";
import { Checkbox } from "@/components/ui/checkbox";
import { NativeSelect, NativeSelectOption } from "@/components/ui/native-select";
import { initials } from "@/lib/format";
import { cn } from "@/lib/utils";
import { TONE_CLASS, type RoleName, type StatusTone } from "./status";

/* ------------------------------------------------------ Activity / audit row */

export function ActivityRow({
  actor,
  action,
  detail,
  at,
  variant = "feed",
}: {
  actor: string;
  action: string;
  detail: string;
  at: string;
  /** feed: avatar list on the dashboard. audit: dense row with a reference column. */
  variant?: "feed" | "audit";
}) {
  if (variant === "audit") {
    return (
      <div className="grid grid-cols-[9.5rem_8rem_12rem_1fr] items-baseline gap-3 border-b border-border px-3 py-1.5 text-xs last:border-b-0">
        <time className="tabular-nums text-muted-foreground">{at}</time>
        <span className="truncate text-foreground">{actor}</span>
        <span className="font-medium text-foreground">{action}</span>
        <span className="truncate text-muted-foreground">{detail}</span>
      </div>
    );
  }
  return (
    <div className="flex items-start gap-2.5 border-b border-border px-3 py-2 last:border-b-0">
      <Avatar size="sm">
        <AvatarFallback className="bg-muted text-xs font-medium text-muted-foreground">{initials(actor)}</AvatarFallback>
      </Avatar>
      <div className="min-w-0 flex-1 text-sm">
        <p className="text-foreground">
          <span className="font-medium">{actor}</span> <span className="text-muted-foreground">{action.toLowerCase()}</span>
        </p>
        <p className="truncate text-xs text-muted-foreground">{detail}</p>
      </div>
      <time className="shrink-0 text-xs tabular-nums text-muted-foreground">{at}</time>
    </div>
  );
}

/* ----------------------------------------------------- Notification list item */

export type NotificationKind = "low-stock" | "expiring" | "mpesa-success" | "mpesa-failed";
const NOTE: Record<NotificationKind, { icon: LucideIcon; tone: StatusTone }> = {
  "low-stock": { icon: PackageIcon, tone: "warning" },
  expiring: { icon: ClockIcon, tone: "warning" },
  "mpesa-success": { icon: CheckCircle2Icon, tone: "success" },
  "mpesa-failed": { icon: XCircleIcon, tone: "error" },
};

export function NotificationItem({
  kind,
  title,
  body,
  at,
  unread,
  action,
}: {
  kind: NotificationKind;
  title: string;
  body: string;
  at: string;
  unread?: boolean;
  action?: { label: string; onClick?: () => void };
}) {
  const { icon: Icon, tone } = NOTE[kind];
  return (
    <div className={cn("flex items-start gap-3 border-b border-border px-3 py-2.5 last:border-b-0", unread && "bg-accent/50")}>
      <span className={cn("mt-0.5 flex size-6 shrink-0 items-center justify-center rounded-md border", TONE_CLASS[tone])}>
        <Icon className="size-3.5" aria-hidden />
      </span>
      <div className="min-w-0 flex-1">
        <p className="flex items-center gap-1.5 text-sm font-medium text-foreground">
          {title}
          {unread ? <span className="size-1.5 rounded-full bg-primary" aria-label="Unread" /> : null}
        </p>
        <p className="text-xs text-muted-foreground">{body}</p>
        {action ? (
          <Button variant="link" size="xs" className="mt-1 h-auto px-0" onClick={action.onClick}>
            {action.label}
          </Button>
        ) : null}
      </div>
      <time className="shrink-0 text-xs tabular-nums text-muted-foreground">{at}</time>
    </div>
  );
}

/* ----------------------------------------------------- Offline / sync banner */

export type SyncState = "offline" | "syncing" | "synced" | "error";
const SYNC: Record<SyncState, { icon: LucideIcon; tone: StatusTone }> = {
  offline: { icon: CloudOffIcon, tone: "warning" },
  syncing: { icon: RefreshCwIcon, tone: "info" },
  synced: { icon: CheckCircle2Icon, tone: "success" },
  error: { icon: AlertTriangleIcon, tone: "error" },
};

export function SyncBanner({ state, pending = 0, onRetry }: { state: SyncState; pending?: number; onRetry?: () => void }) {
  const { icon: Icon, tone } = SYNC[state];
  const text =
    state === "offline"
      ? `You are offline. Sales are saved on this device${pending ? ` (${pending} waiting to sync)` : ""} and will upload when the connection returns.`
      : state === "syncing"
        ? `Syncing ${pending} saved ${pending === 1 ? "sale" : "sales"} to the server.`
        : state === "synced"
          ? "All sales are synced. Last sync 16:42."
          : `${pending} ${pending === 1 ? "sale" : "sales"} could not be synced. Nothing is lost; they remain on this device.`;
  return (
    <div role={state === "error" ? "alert" : "status"} className={cn("flex items-center gap-2 rounded-lg border px-3 py-2 text-sm", TONE_CLASS[tone])}>
      <Icon className={cn("size-4 shrink-0", state === "syncing" && "animate-spin")} aria-hidden />
      <p className="flex-1 leading-5">{text}</p>
      {state === "error" ? (
        <Button variant="outline" size="xs" onClick={onRetry}>
          Retry now
        </Button>
      ) : null}
    </div>
  );
}

/* ---------------------------------------------------------- Branch switcher */

export function BranchSwitcher({
  branches,
  initial,
  locked,
}: {
  branches: { id: number; name: string; town: string }[];
  initial: number;
  /** A user assigned to one branch sees it but cannot change it. */
  locked?: boolean;
}) {
  const [value, setValue] = useState(String(initial));
  const id = `bs-${locked ? "locked" : "open"}`;
  return (
    <div className="flex items-center gap-2">
      <label htmlFor={id} className="text-xs text-muted-foreground">
        Branch
      </label>
      <NativeSelect id={id} size="sm" className="w-52" value={value} disabled={locked} onChange={(e) => setValue(e.target.value)}>
        {branches.map((b) => (
          <NativeSelectOption key={b.id} value={String(b.id)}>
            {b.name}, {b.town}
          </NativeSelectOption>
        ))}
      </NativeSelect>
      {locked ? <span className="text-xs text-muted-foreground">Assigned by an admin</span> : null}
    </div>
  );
}

/* -------------------------------------------------------- Permission matrix */

export function PermissionMatrix({
  roles,
  modules,
  initial,
  disabled,
}: {
  roles: RoleName[];
  modules: string[];
  /** Keyed `${role}:${module}`. */
  initial: Record<string, boolean>;
  disabled?: boolean;
}) {
  const [grid, setGrid] = useState(initial);
  return (
    <div className="overflow-hidden rounded-lg border border-border bg-card">
      <table className="w-full text-sm">
        <thead>
          <tr className="border-b border-[var(--color-border-panel)] bg-[var(--color-bg-surface-subtle)]">
            <th scope="col" className="px-3 py-2 text-left text-xs font-medium text-muted-foreground">
              Module
            </th>
            {roles.map((r) => (
              <th key={r} scope="col" className="w-28 px-3 py-2 text-center text-xs font-medium text-muted-foreground">
                {r}
              </th>
            ))}
          </tr>
        </thead>
        <tbody>
          {modules.map((m) => (
            <tr key={m} className="border-b border-border last:border-b-0">
              <th scope="row" className="px-3 py-2 text-left font-normal text-foreground">
                {m}
              </th>
              {roles.map((r) => {
                const key = `${r}:${m}`;
                const locked = r === "Admin";
                return (
                  <td key={r} className="px-3 py-2 text-center">
                    <Checkbox
                      aria-label={`${r} can access ${m}`}
                      checked={locked || !!grid[key]}
                      disabled={locked || disabled}
                      onCheckedChange={(v) => setGrid((g) => ({ ...g, [key]: !!v }))}
                    />
                  </td>
                );
              })}
            </tr>
          ))}
        </tbody>
      </table>
      <p className="flex items-center gap-1.5 border-t border-border px-3 py-2 text-xs text-muted-foreground">
        Admin access is fixed so the pharmacy cannot lock itself out.
      </p>
    </div>
  );
}
