"use client";

import Link from "next/link";
import { AlertTriangle, Bell, Info, Mail, Send } from "lucide-react";
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
import { Button } from "@/components/ui/button";
import { Skeleton } from "@/components/ui/skeleton";
import { Spinner } from "@/components/ui/spinner";
import { Switch } from "@/components/ui/switch";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip";
import { SectionCard } from "@/components/app/page";
import { cn } from "@/lib/utils";
import { useAuth } from "../../auth/auth-context";
import { EmptyState, ErrorState } from "../../components/ui/page-states";
import { SettingsLayout, UnsavedHint } from "../settings-layout";
import { useNotificationPreferences } from "../useSettings";

// [field, label, help, unavailable reason]
const CHANNELS = [
  ["inAppEnabled", "In-app", "Shown under the bell in the top bar. Off files the event straight into your notification history. Critical alerts always show."],
  ["emailEnabled", "Email", "One email to your sign-in address as soon as the event happens."],
  ["pushEnabled", "Push", "Browser and phone push notifications are not available yet.", "Push notifications are not available yet."],
  ["digestEnabled", "Daily digest", "One summary email a day with the events you have not opened yet. If Email is also on, the event is emailed at once and left out of the summary."],
];

export function NotificationSettingsPage() {
  const prefs = useNotificationPreferences();
  const { can } = useAuth();
  const ready = !prefs.isLoading && !prefs.error;
  const delivery = prefs.emailDelivery;

  return <SettingsLayout title="Notifications" description="Choose how you hear about events. In-app notifications appear under the bell in the top bar.">
    <SectionCard title="Channels by event" icon={Bell} description="Applies to you only. Changes take effect for new events after you save." contentClassName="grid gap-4">
      {prefs.isLoading && <PreferencesSkeleton />}
      {!prefs.isLoading && prefs.error && <ErrorState compact error={prefs.error} title="Preferences could not be loaded" onRetry={prefs.retry} />}
      {ready && !prefs.preferences.length && <EmptyState compact title="No notification types configured yet" detail="Event types come from the Notification type reference list. Once events are defined, you can choose channels for each here." />}

      {ready && delivery && <EmailDeliveryNote delivery={delivery} canManage={can("organization.manage")} onTest={prefs.sendTestEmail} isTesting={prefs.isTesting} />}

      {ready && prefs.preferences.length > 0 && <>
        {/* Desktop: event x channel matrix */}
        <div className={cn("hidden overflow-hidden rounded-lg border md:block", prefs.isSaving && "opacity-60")}>
          <Table>
            <TableHeader className="bg-muted/50">
              <TableRow className="hover:bg-transparent">
                <TableHead className="h-10 text-xs">Event</TableHead>
                {CHANNELS.map(([field, label, help]) => <TableHead key={field} className="h-10 w-28 text-center text-xs">
                  <span className="inline-flex items-center gap-1">{label}
                    <Tooltip><TooltipTrigger asChild><button type="button" className="rounded-sm text-muted-foreground hover:text-foreground focus-visible:outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50" aria-label={`About ${label}`}><Info className="size-3.5" /></button></TooltipTrigger><TooltipContent className="max-w-60">{help}</TooltipContent></Tooltip>
                  </span>
                </TableHead>)}
              </TableRow>
            </TableHeader>
            <TableBody>
              {prefs.preferences.map((item) => <TableRow key={item.notificationType}>
                <TableCell className="py-3 whitespace-normal">
                  <div className="grid gap-0.5"><span className="font-medium">{item.label}</span>{item.description && <span className="text-xs text-muted-foreground">{item.description}</span>}</div>
                </TableCell>
                {CHANNELS.map(([field, label, , unavailable]) => <TableCell key={field} className="text-center">
                  <span title={unavailable || undefined}><Switch checked={!unavailable && Boolean(item[field])} disabled={prefs.isSaving || Boolean(unavailable)} onCheckedChange={() => prefs.toggle(item.notificationType, field)} aria-label={unavailable ? `${label} for ${item.label}: not available yet` : `${label} for ${item.label}`} /></span>
                </TableCell>)}
              </TableRow>)}
            </TableBody>
          </Table>
        </div>

        {/* Mobile: one card per event */}
        <ul className={cn("grid gap-3 md:hidden", prefs.isSaving && "opacity-60")}>
          {prefs.preferences.map((item) => <li key={item.notificationType} className="rounded-lg border p-3">
            <p className="font-medium">{item.label}</p>
            {item.description && <p className="text-xs text-muted-foreground">{item.description}</p>}
            <div className="mt-3 grid grid-cols-2 gap-3">
              {CHANNELS.map(([field, label, , unavailable]) => <label key={field} className={cn("flex items-center justify-between gap-2 rounded-md bg-muted/40 px-2.5 py-2 text-sm", unavailable && "text-muted-foreground")}>
                <span className="grid">{label}{unavailable && <span className="text-xs">Not available yet</span>}</span>
                <Switch checked={!unavailable && Boolean(item[field])} disabled={prefs.isSaving || Boolean(unavailable)} onCheckedChange={() => prefs.toggle(item.notificationType, field)} aria-label={unavailable ? `${label} for ${item.label}: not available yet` : `${label} for ${item.label}`} />
              </label>)}
            </div>
          </li>)}
        </ul>
      </>}

      {ready && <>
        <p className="text-xs text-muted-foreground">Email subjects only name the kind of event, never a buyer, order or amount. The daily digest goes out once a day and skips anything you already opened.</p>
        <div className="flex flex-wrap items-center justify-end gap-3 border-t pt-4">
          <UnsavedHint show={prefs.isDirty} />
          {prefs.isDirty && <Button type="button" variant="outline" disabled={prefs.isSaving} onClick={prefs.reset}>Discard</Button>}
          <Tooltip>
            <TooltipTrigger asChild>
              <span tabIndex={prefs.isDirty ? -1 : 0}>
                <Button type="button" disabled={prefs.isSaving || !prefs.isDirty} onClick={prefs.save}>{prefs.isSaving && <Spinner />} Save preferences</Button>
              </span>
            </TooltipTrigger>
            {!prefs.isDirty && <TooltipContent>Change a channel to enable saving</TooltipContent>}
          </Tooltip>
        </div>
      </>}
    </SectionCard>
  </SettingsLayout>;
}

/** Where notification email goes, whether this server can send it, and a button to try it. */
function EmailDeliveryNote({ delivery, canManage, onTest, isTesting }) {
  const testButton = <Button type="button" variant="outline" size="sm" disabled={isTesting} onClick={onTest}>{isTesting ? <Spinner /> : <Send />} Send test email</Button>;

  if (!delivery.deliverable) {
    return <Alert>
      <AlertTriangle className="text-warning" />
      <AlertTitle>Email notifications cannot be delivered yet</AlertTitle>
      <AlertDescription className="grid gap-2">
        <span>{delivery.note || "Outgoing email is not set up."}</span>
        <span className="flex flex-wrap items-center gap-2">
          {canManage && <Button asChild variant="outline" size="sm"><Link href="/settings/system-email">Set up system email</Link></Button>}
          {testButton}
        </span>
      </AlertDescription>
    </Alert>;
  }

  return <div className="flex flex-wrap items-center justify-between gap-3 rounded-lg border bg-muted/30 px-3 py-2.5">
    <p className="flex min-w-0 items-start gap-2 text-sm text-muted-foreground">
      <Mail className="mt-0.5 size-4 shrink-0" aria-hidden="true" />
      <span>Emails go to <span className="font-medium text-foreground">{delivery.address}</span>, sent {delivery.via === "organization" ? "from your organization's system email" : "by the platform mail service"}.</span>
    </p>
    {testButton}
  </div>;
}

function PreferencesSkeleton() {
  return <div className="overflow-hidden rounded-lg border" aria-hidden="true">
    <Skeleton className="h-10 rounded-none" />
    {Array.from({ length: 6 }).map((_, index) => <div key={index} className="flex items-center gap-4 border-t px-4 py-3">
      <div className="grid flex-1 gap-1.5"><Skeleton className="h-4 w-48" /><Skeleton className="h-3 w-64 max-w-full" /></div>
      {Array.from({ length: 4 }).map((__, cell) => <Skeleton key={cell} className="hidden h-5 w-9 rounded-full md:block" />)}
    </div>)}
  </div>;
}
