"use client"

import { useEffect, useMemo, useState } from "react"
import Link from "next/link"
import { useRouter } from "next/navigation"
import {
  ArrowLeft,
  Bell,
  BellOff,
  CheckCheck,
  ChevronRight,
  Flag,
  Trophy,
  UserPlus,
  Users,
} from "lucide-react"
import { Wordmark } from "@/components/wordmark"
import { cn } from "@/lib/utils"

// V0-designet (zip 20, varsler-runden 2026-07-25) -- datalag skrevet om fra
// mock til ekte fetch mot GET /notifications + POST .../read + .../read-all
// (app/routers/notifications.py). Scenario-veksleren fra V0-eksporten fjernet.

type NotificationKind = "friend" | "tournament" | "round" | "result"

type ApiNotification = {
  id: string
  type: NotificationKind
  message: string
  link_path: string
  created_at: string
  read_at: string | null
}

const KIND_ICON: Record<NotificationKind, typeof Bell> = {
  friend: UserPlus,
  tournament: Trophy,
  round: Flag,
  result: Users,
}

const KIND_LABEL: Record<NotificationKind, string> = {
  friend: "Venneforespørsel",
  tournament: "Turnering",
  round: "Runde",
  result: "Resultat",
}

function formatRelativeTime(iso: string): string {
  const minutesAgo = Math.max(0, (Date.now() - new Date(iso).getTime()) / 60000)
  if (minutesAgo < 1) return "akkurat nå"
  if (minutesAgo < 60) {
    const m = Math.round(minutesAgo)
    return `for ${m} ${m === 1 ? "minutt" : "minutter"} siden`
  }
  const hours = Math.floor(minutesAgo / 60)
  if (hours < 24) {
    return `for ${hours} ${hours === 1 ? "time" : "timer"} siden`
  }
  const days = Math.floor(hours / 24)
  if (days < 7) {
    return `for ${days} ${days === 1 ? "dag" : "dager"} siden`
  }
  const weeks = Math.floor(days / 7)
  return `for ${weeks} ${weeks === 1 ? "uke" : "uker"} siden`
}

export function Notifications() {
  const router = useRouter()
  const [items, setItems] = useState<ApiNotification[] | null>(null)

  useEffect(() => {
    fetch("/notifications", { credentials: "include" })
      .then((res) => {
        if (res.status === 401) {
          router.replace("/")
          return null
        }
        return res.ok ? res.json() : []
      })
      .then((data: ApiNotification[] | null) => {
        if (data) setItems(data)
      })
      .catch(() => setItems([]))
  }, [router])

  const sorted = useMemo(
    () => [...(items ?? [])].sort((a, b) => (a.created_at < b.created_at ? 1 : -1)),
    [items],
  )
  const unreadCount = sorted.filter((n) => n.read_at === null).length

  async function markAllRead() {
    setItems((prev) => (prev ? prev.map((n) => ({ ...n, read_at: n.read_at ?? new Date().toISOString() })) : prev))
    await fetch("/notifications/read-all", { method: "POST", credentials: "include" })
  }

  async function markRead(id: string) {
    setItems((prev) => (prev ? prev.map((n) => (n.id === id ? { ...n, read_at: n.read_at ?? new Date().toISOString() } : n)) : prev))
    await fetch(`/notifications/${id}/read`, { method: "POST", credentials: "include" })
  }

  return (
    <div className="flex min-h-[100dvh] flex-col bg-background">
      <header className="sticky top-0 z-10 border-b border-border bg-background/80 backdrop-blur">
        <div className="mx-auto flex w-full max-w-3xl items-center justify-between gap-4 px-5 py-4">
          <Link
            href="/dashboard"
            className="inline-flex min-h-[44px] items-center gap-1.5 rounded-lg px-2 py-1.5 text-sm font-semibold text-muted-foreground transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
          >
            <ArrowLeft aria-hidden="true" className="size-4" />
            Til dashbord
          </Link>
          <Wordmark compact />
        </div>
      </header>

      <main className="mx-auto w-full max-w-3xl flex-1 px-5 pb-28 pt-6 sm:pt-8">
        <div className="flex flex-col gap-4">
          <div className="flex flex-col gap-2">
            <h1 className="text-2xl font-extrabold tracking-tight text-foreground text-balance">Varsler</h1>
            <p className="text-base leading-relaxed text-muted-foreground text-pretty">
              {items === null
                ? "Henter varsler …"
                : unreadCount > 0
                  ? unreadCount === 1
                    ? "Du har 1 ulest varsel."
                    : `Du har ${unreadCount} uleste varsler.`
                  : "Alt er lest. Her dukker nye varsler opp."}
            </p>
          </div>

          {sorted.length > 0 && (
            <div className="flex">
              <button
                type="button"
                onClick={markAllRead}
                disabled={unreadCount === 0}
                className="inline-flex min-h-[44px] items-center gap-2 rounded-xl border border-border bg-card px-4 py-2 text-sm font-bold text-foreground transition-colors hover:bg-accent/50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50"
              >
                <CheckCheck aria-hidden="true" className="size-4" />
                Merk alle som lest
              </button>
            </div>
          )}
        </div>

        {items !== null && sorted.length === 0 ? (
          <EmptyState />
        ) : (
          <ul className="mt-4 flex flex-col gap-2.5">
            {sorted.map((n) => (
              <li key={n.id}>
                <NotificationRow notification={n} onActivate={() => markRead(n.id)} />
              </li>
            ))}
          </ul>
        )}
      </main>
    </div>
  )
}

function NotificationRow({
  notification,
  onActivate,
}: {
  notification: ApiNotification
  onActivate: () => void
}) {
  const Icon = KIND_ICON[notification.type]
  const unread = notification.read_at === null
  const readState = unread ? "Ulest" : "Lest"

  return (
    <Link
      href={notification.link_path}
      onClick={onActivate}
      aria-label={`${readState}. ${KIND_LABEL[notification.type]}: ${notification.message} ${formatRelativeTime(
        notification.created_at,
      )}`}
      className={cn(
        "group flex items-center gap-3 rounded-2xl border p-4 text-left shadow-sm shadow-black/5 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
        unread
          ? "border-brand-orange/40 bg-brand-orange/5 hover:bg-brand-orange/10"
          : "border-border bg-card hover:bg-accent/50",
      )}
    >
      {/* Ulest-indikator: en prikk i en reservert plass, slik at leste rader forblir på linje. */}
      <span className="flex w-3 shrink-0 justify-center" aria-hidden="true">
        {unread && <span className="size-3 rounded-full bg-brand-orange" />}
      </span>

      <span
        aria-hidden="true"
        className={cn(
          "flex size-11 shrink-0 items-center justify-center rounded-xl",
          unread ? "bg-brand-orange/15 text-foreground" : "bg-muted text-muted-foreground",
        )}
      >
        <Icon className="size-5" />
      </span>

      <div className="flex min-w-0 flex-1 flex-col gap-1">
        <span className="flex items-center gap-2">
          <span
            className={cn(
              "text-xs uppercase tracking-wide",
              unread ? "font-bold text-foreground" : "font-semibold text-muted-foreground",
            )}
          >
            {KIND_LABEL[notification.type]}
          </span>
          {unread && (
            <span className="rounded-full bg-brand-orange px-2 py-0.5 text-[11px] font-bold leading-none text-brand-orange-foreground">
              Ny
            </span>
          )}
        </span>
        <span
          className={cn(
            "text-base leading-snug text-foreground text-pretty",
            unread ? "font-bold" : "font-normal",
          )}
        >
          {notification.message}
        </span>
        <span className="text-sm font-medium text-muted-foreground tabular-nums">
          {formatRelativeTime(notification.created_at)}
        </span>
      </div>

      <ChevronRight
        aria-hidden="true"
        className="size-5 shrink-0 self-center text-muted-foreground transition-transform group-hover:translate-x-0.5"
      />
    </Link>
  )
}

function EmptyState() {
  return (
    <div className="mt-6 flex flex-col items-center gap-4 rounded-3xl border border-dashed border-border bg-card px-6 py-14 text-center">
      <span
        aria-hidden="true"
        className="flex size-16 items-center justify-center rounded-2xl bg-muted text-muted-foreground"
      >
        <BellOff className="size-8" />
      </span>
      <div className="flex flex-col gap-2">
        <h2 className="text-lg font-extrabold tracking-tight text-foreground">Ingen varsler ennå</h2>
        <p className="mx-auto max-w-xs text-base leading-relaxed text-muted-foreground text-pretty">
          Når noe skjer med rundene, turneringene eller vennene dine, dukker det opp her.
        </p>
      </div>
      <Link
        href="/dashboard"
        className="inline-flex min-h-[44px] items-center gap-1.5 rounded-xl bg-primary px-5 text-base font-bold text-primary-foreground shadow-sm transition-colors hover:bg-primary/90 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
      >
        Tilbake til dashbord
      </Link>
    </div>
  )
}
