"use client";

import { useMemo, useState } from "react";
import Link from "next/link";
import { Bell, Gift, Send as SendIcon, ShieldCheck, UserCog } from "lucide-react";
import { Container } from "@/components/common/Container";
import { Card } from "@/components/common/Card";
import { Pagination } from "@/components/app/Pagination";
import { useNotifications } from "@/hooks/useNotifications";
import { useTranslation } from "@/hooks/useTranslation";
import { cn } from "@/lib/utils";
import type { AppNotification, NotificationType } from "@/types";

type Filter = "all" | "unread" | "read";

const TYPE_META: Record<NotificationType, { icon: React.ComponentType<{ className?: string }>; color: string; bg: string }> = {
  transfer: { icon: SendIcon,   color: "text-emerald-600 dark:text-emerald-400", bg: "bg-emerald-50 dark:bg-emerald-500/10" },
  security: { icon: ShieldCheck, color: "text-rose-600 dark:text-rose-400",       bg: "bg-rose-50 dark:bg-rose-500/10"     },
  promo:    { icon: Gift,        color: "text-amber-600 dark:text-amber-400",     bg: "bg-amber-50 dark:bg-amber-500/10"   },
  account:  { icon: UserCog,     color: "text-brand-600 dark:text-brand-400",     bg: "bg-brand-50 dark:bg-brand-500/10"   },
  system:   { icon: Bell,        color: "text-slate-600 dark:text-slate-400",     bg: "bg-slate-100 dark:bg-slate-800"     },
};

const PAGE_SIZE = 10;

export default function NotificationsPage() {
  const { t } = useTranslation();
  const { notifications, unreadCount, isLoading, markRead, markAllRead } = useNotifications();

  const [filter, setFilter] = useState<Filter>("unread");
  const [page, setPage] = useState(1);

  const filtered = useMemo(() => {
    if (filter === "unread") return notifications.filter((n) => !n.read);
    if (filter === "read")   return notifications.filter((n) => n.read);
    return notifications;
  }, [notifications, filter]);

  const pageCount   = Math.ceil(filtered.length / PAGE_SIZE);
  const safePage    = Math.min(page, pageCount || 1);
  const pageStart   = (safePage - 1) * PAGE_SIZE;
  const pagedNotifs = filtered.slice(pageStart, pageStart + PAGE_SIZE);

  function handleFilterChange(f: Filter) {
    setFilter(f);
    setPage(1);
  }

  const TABS: { key: Filter; label: string; count: number }[] = [
    { key: "all",    label: t("app.notifications.tabAll"),    count: notifications.length },
    { key: "unread", label: t("app.notifications.tabUnread"), count: unreadCount },
    { key: "read",   label: t("app.notifications.tabRead"),   count: notifications.length - unreadCount },
  ];

  return (
    <Container className="max-w-full space-y-6 lg:space-y-8">
      {/* Page Header */}
      <header className="flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
        <div className="flex items-center gap-4">
          <div>
            <h1 className="text-2xl font-bold tracking-tight text-slate-900 dark:text-white">
              {t("app.notifications.title")}
            </h1>
            <p className="mt-1 text-sm text-slate-500 dark:text-slate-400">
              {t("app.notifications.subtitle")}
            </p>
          </div>
        </div>

        {notifications.length > 0 && unreadCount > 0 && (
          <button
            type="button"
            onClick={markAllRead}
            className="inline-flex h-9 items-center justify-center rounded-xl bg-white px-4 text-sm font-semibold text-slate-700 shadow-sm ring-1 ring-inset ring-slate-200 transition hover:bg-slate-50 dark:bg-slate-900 dark:text-slate-200 dark:ring-slate-800 dark:hover:bg-slate-800"
          >
            {t("app.notifications.markAllRead")}
          </button>
        )}
      </header>

      <Card className="overflow-hidden">
        {/* Filter tabs */}
        <div className="flex items-center gap-1 px-6 pt-5 sm:px-7">
          {TABS.map((tab) => {
            const active = filter === tab.key;
            return (
              <button
                key={tab.key}
                type="button"
                onClick={() => handleFilterChange(tab.key)}
                className={cn(
                  "inline-flex items-center gap-2 rounded-lg px-3.5 py-2 text-sm font-semibold transition-colors",
                  active
                    ? "bg-brand-50 text-brand-600 dark:bg-brand-500/10 dark:text-brand-400"
                    : "text-slate-500 hover:bg-slate-100 hover:text-slate-700 dark:text-slate-400 dark:hover:bg-slate-800/60 dark:hover:text-slate-200",
                )}
              >
                {tab.label}
                {tab.count > 0 && (
                  <span
                    className={cn(
                      "inline-flex h-5 min-w-[20px] items-center justify-center rounded-full px-1.5 text-xs font-bold",
                      active
                        ? "bg-brand-100 text-brand-700 dark:bg-brand-500/20 dark:text-brand-300"
                        : "bg-slate-100 text-slate-600 dark:bg-slate-800 dark:text-slate-400",
                    )}
                  >
                    {tab.count}
                  </span>
                )}
              </button>
            );
          })}
        </div>

        {/* Separator */}
        <div className="mt-4 border-b border-slate-100 dark:border-slate-800/80 sm:mt-5" />

        {/* Rows */}
        <div>
          {isLoading ? (
            <div className="grid grid-cols-1 gap-3 p-4 sm:p-5 lg:grid-cols-2">
              {Array.from({ length: 6 }).map((_, i) => (
                <div key={i} className="flex gap-4 rounded-2xl border border-slate-100 px-5 py-4 dark:border-slate-800/80">
                  <div className="h-10 w-10 shrink-0 animate-pulse rounded-full bg-slate-200 dark:bg-slate-800" />
                  <div className="flex-1 space-y-2 py-1">
                    <div className="h-4 w-3/4 animate-pulse rounded bg-slate-200 dark:bg-slate-800" />
                    <div className="h-3 w-1/4 animate-pulse rounded bg-slate-200 dark:bg-slate-800" />
                  </div>
                </div>
              ))}
            </div>
          ) : !filtered.length ? (
            <div className="flex flex-col items-center justify-center py-24 text-center">
              <div className="mb-6 grid h-20 w-20 place-items-center rounded-full bg-slate-50 dark:bg-slate-800/50">
                <Bell className="h-10 w-10 text-slate-300 dark:text-slate-600" />
              </div>
              <h3 className="text-lg font-bold text-slate-900 dark:text-white">
                {filter === "unread" ? t("app.notifications.noUnread") : filter === "read" ? t("app.notifications.noRead") : t("app.notifications.noNotifications")}
              </h3>
              <p className="mt-2 text-sm text-slate-500 dark:text-slate-400">
                {filter !== "all" ? t("app.notifications.tryFilter") : t("app.notifications.willAppearHere")}
              </p>
            </div>
          ) : (
            <div className="grid grid-cols-1 gap-3 p-4 sm:p-5 lg:grid-cols-2">
              {pagedNotifs.map((n) => (
                <NotifRow key={n.id} n={n} markRead={markRead} newBadgeLabel={t("app.notifications.newBadge")} />
              ))}
            </div>
          )}
        </div>

        {/* Pagination footer */}
        {filtered.length > PAGE_SIZE && (
          <div className="flex flex-col items-center justify-between gap-4 border-t border-slate-100/80 px-6 py-6 dark:border-white/5 sm:flex-row sm:px-7 sm:py-7">
            <p className="text-xs font-medium text-slate-400">
              {t("app.notifications.showing")
                .replace("{start}", String(pageStart + 1))
                .replace("{end}", String(Math.min(pageStart + PAGE_SIZE, filtered.length)))
                .replace("{total}", String(filtered.length))}
            </p>
            <Pagination page={safePage} pageCount={pageCount} onPageChange={setPage} />
          </div>
        )}
      </Card>
    </Container>
  );
}

function NotifRow({
  n,
  markRead,
  newBadgeLabel,
}: {
  n: AppNotification;
  markRead: (id: string) => void;
  newBadgeLabel: string;
}) {
  const { dir } = useTranslation();
  const meta = TYPE_META[n.type] ?? TYPE_META.system;
  const Icon = meta.icon;
  // Some sources (e.g. this API) only send one message string — the "title" is then
  // just a truncated prefix of the body. Collapse to a single line in that case
  // instead of showing the same sentence twice.
  const titleIsRedundant = n.body.startsWith(n.title.replace(/…$/, ""));

  const inner = (
    <div className="flex w-full items-start gap-4 rounded-2xl border border-slate-100 px-5 py-4 text-start transition-colors hover:border-brand-200 hover:bg-brand-50/80 dark:border-slate-800/80 dark:hover:border-brand-500/30 dark:hover:bg-brand-500/10">
      <div className={cn("relative flex h-10 w-10 shrink-0 items-center justify-center rounded-full", meta.bg)}>
        <Icon
          className={cn(
            "h-4.5 w-4.5",
            meta.color,
            n.type === "transfer" && dir === "rtl" && "[transform:scaleX(-1)]",
          )}
          aria-hidden
        />
        {!n.read && (
          <span className="absolute -bottom-0.5 -end-0.5 h-2.5 w-2.5 rounded-full border-2 border-white bg-brand-500 dark:border-slate-900" />
        )}
      </div>

      <div className="min-w-0 flex-1">
        {titleIsRedundant ? (
          <p className={cn(
            "line-clamp-2 text-sm leading-relaxed",
            n.read ? "font-normal text-slate-500 dark:text-slate-400" : "font-semibold text-slate-800 dark:text-slate-200",
          )}>
            {n.body}
          </p>
        ) : (
          <>
            <p className={cn(
              "text-sm leading-relaxed",
              n.read ? "font-normal text-slate-500 dark:text-slate-400" : "font-semibold text-slate-800 dark:text-slate-200",
            )}>
              {n.title}
            </p>
            <p className="mt-0.5 line-clamp-2 text-xs leading-relaxed text-slate-500 dark:text-slate-400">
              {n.body}
            </p>
          </>
        )}
        <p className="mt-1.5 text-xs font-medium text-slate-400 dark:text-slate-500">
          {new Intl.DateTimeFormat("en-US", { month: "short", day: "numeric", year: "numeric" }).format(new Date(n.createdAt))}
        </p>
      </div>

      {!n.read && (
        <span className="mt-0.5 shrink-0 self-start rounded-full bg-brand-500/10 px-2 py-0.5 text-2xs font-bold uppercase tracking-wide text-brand-600 dark:text-brand-400">
          {newBadgeLabel}
        </span>
      )}
    </div>
  );

  return n.href ? (
    <Link href={n.href} onClick={() => markRead(n.id)} className="block w-full text-start">
      {inner}
    </Link>
  ) : (
    <button type="button" onClick={() => markRead(n.id)} className="block w-full text-start">
      {inner}
    </button>
  );
}
