"use client";

import { toastApiError } from "@/lib/toast-api-error";
import Link from "next/link";
import * as React from "react";
import { ArrowLeft, Bell, CheckCheck, Loader2, MessagesSquare } from "lucide-react";
import { toast } from "sonner";

import {
  fetchNotificationsClient,
  markAllNotificationsReadClient,
  markNotificationReadClient,
} from "@/app/customer/[tenant]/discussion-board/_lib/discussion-board-api";
import type { DiscussionNotification } from "@/app/customer/[tenant]/discussion-board/_lib/types";
import { ErrorBanner } from "@/components/shared/error-banner";
import { TABLE_TOOLBAR_BTN_OUTLINE } from "@/components/shared/table-ui";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import { customerUrl } from "@/lib/tenant";

type CustomerDiscussionNotificationsPageProps = {
  tenant: string;
  initialItems: DiscussionNotification[];
  initialTotalCount: number;
  initialPage: number;
  initialPageSize: number;
  initialPageCount: number;
  initialUnreadCount: number;
  initialErrorMessage?: string | null;
  permissionDenied?: boolean;
};

export function CustomerDiscussionNotificationsPage({
  tenant,
  initialItems,
  initialTotalCount,
  initialPage,
  initialPageSize,
  initialPageCount,
  initialUnreadCount,
  initialErrorMessage = null,
  permissionDenied = false,
}: CustomerDiscussionNotificationsPageProps) {
  const [items, setItems] = React.useState(initialItems);
  const [totalCount, setTotalCount] = React.useState(initialTotalCount);
  const [page, setPage] = React.useState(initialPage);
  const [pageSize] = React.useState(initialPageSize);
  const [pageCount, setPageCount] = React.useState(initialPageCount);
  const [unreadCount, setUnreadCount] = React.useState(initialUnreadCount);
  const [listError, setListError] = React.useState(initialErrorMessage);
  const [isRefreshing, setIsRefreshing] = React.useState(false);
  const [markingId, setMarkingId] = React.useState<number | null>(null);
  const [markingAll, setMarkingAll] = React.useState(false);

  const boardHref = customerUrl(tenant, "/discussion-board");

  const refreshList = React.useCallback(
    async (nextPage = page) => {
      setIsRefreshing(true);
      setListError(null);
      try {
        const data = await fetchNotificationsClient(tenant, nextPage, pageSize);
        setItems(data.items);
        setTotalCount(data.totalCount);
        setPage(nextPage);
        setPageCount(data.pageCount);
        setUnreadCount(data.unreadCount);
      } catch (error) {
        setListError(error instanceof Error ? error.message : "Failed to load notifications");
      } finally {
        setIsRefreshing(false);
      }
    },
    [page, pageSize, tenant],
  );

  const markRead = async (notificationId: number) => {
    setMarkingId(notificationId);
    try {
      const nextUnread = await markNotificationReadClient(tenant, notificationId);
      setUnreadCount(nextUnread);
      setItems((prev) =>
        prev.map((item) =>
          item.notification_id === notificationId ? { ...item, is_read: true } : item,
        ),
      );
    } catch (error) {
      toastApiError(error, "Failed to mark as read");
    } finally {
      setMarkingId(null);
    }
  };

  const markAllRead = async () => {
    setMarkingAll(true);
    try {
      await markAllNotificationsReadClient(tenant);
      setUnreadCount(0);
      setItems((prev) => prev.map((item) => ({ ...item, is_read: true })));
      toast.success("All notifications marked as read");
    } catch (error) {
      toastApiError(error, "Failed to mark all as read");
    } finally {
      setMarkingAll(false);
    }
  };

  if (permissionDenied) {
    return (
      <div className="flex flex-col gap-3 md:gap-4">
        <div className="flex items-center gap-2 border-b pb-3">
          <Bell className="size-5 text-violet-600" />
          <h1 className="font-semibold text-base tracking-tight">Notifications</h1>
        </div>
        <ErrorBanner message="You do not have permission to access notifications." />
      </div>
    );
  }

  return (
    <div className="flex flex-col gap-3 md:gap-4">
      <div className="flex flex-col gap-2 border-b pb-3 sm:flex-row sm:items-center sm:justify-between">
        <div className="flex items-center gap-2">
          <Bell className="size-5 text-violet-600" />
          <h1 className="font-semibold text-base tracking-tight">Notifications</h1>
          {unreadCount > 0 ? (
            <Badge variant="secondary" className="text-xs">
              {unreadCount} unread
            </Badge>
          ) : null}
        </div>
        <div className="flex flex-wrap gap-2">
          <Button variant="outline" size="sm" className="gap-1.5" asChild>
            <Link href={boardHref}>
              <ArrowLeft className="size-4" />
              Back to board
            </Link>
          </Button>
          <Button
            type="button"
            variant="outline"
            size="sm"
            className="gap-1.5"
            disabled={markingAll || unreadCount === 0}
            onClick={() => void markAllRead()}
          >
            {markingAll ? <Loader2 className="size-4 animate-spin" /> : <CheckCheck className="size-4" />}
            Mark all read
          </Button>
        </div>
      </div>

      <ErrorBanner message={listError} />

      <section className="rounded-lg border">
        <div className="overflow-x-auto">
          <Table>
            <TableHeader>
              <TableRow>
                <TableHead>Type</TableHead>
                <TableHead>Date</TableHead>
                <TableHead className="w-28">Status</TableHead>
                <TableHead className="w-36">Actions</TableHead>
              </TableRow>
            </TableHeader>
            <TableBody>
              {items.length === 0 ? (
                <TableRow>
                  <TableCell colSpan={4} className="text-muted-foreground h-24 text-center">
                    No notifications.
                  </TableCell>
                </TableRow>
              ) : (
                items.map((notification) => {
                  const viewHref = customerUrl(
                    tenant,
                    `/discussion-board/view/${encodeURIComponent(notification.threadToken)}`,
                  );
                  return (
                    <TableRow
                      key={notification.notification_id}
                      className={!notification.is_read ? "bg-muted/20" : ""}
                    >
                      <TableCell>
                        <Link href={viewHref} className="flex items-center gap-1.5 hover:underline">
                          <MessagesSquare className="size-3.5 text-muted-foreground" />
                          <span className="text-sm">{notification.type || "Update"}</span>
                        </Link>
                      </TableCell>
                      <TableCell className="whitespace-nowrap text-xs">
                        {notification.date_added}
                      </TableCell>
                      <TableCell>
                        <Badge variant={notification.is_read ? "outline" : "default"} className="text-xs">
                          {notification.is_read ? "Read" : "Unread"}
                        </Badge>
                      </TableCell>
                      <TableCell>
                        {!notification.is_read ? (
                          <Button
                            type="button"
                            {...TABLE_TOOLBAR_BTN_OUTLINE}
                            className="h-7 px-2 text-xs"
                            disabled={markingId === notification.notification_id}
                            onClick={() => void markRead(notification.notification_id)}
                          >
                            {markingId === notification.notification_id ? (
                              <Loader2 className="size-3.5 animate-spin" />
                            ) : null}
                            Mark read
                          </Button>
                        ) : (
                          <span className="text-muted-foreground text-xs">—</span>
                        )}
                      </TableCell>
                    </TableRow>
                  );
                })
              )}
            </TableBody>
          </Table>
        </div>
        <div className="flex items-center justify-between border-t px-3 py-2 text-xs">
          <span className="text-muted-foreground">
            {totalCount === 0
              ? "No notifications"
              : `Page ${page} of ${Math.max(pageCount, 1)} · ${totalCount} notification${totalCount === 1 ? "" : "s"}`}
          </span>
          <div className="flex gap-1">
            <Button
              type="button"
              {...TABLE_TOOLBAR_BTN_OUTLINE}
              disabled={page <= 1 || isRefreshing || totalCount === 0}
              onClick={() => void refreshList(page - 1)}
            >
              Previous
            </Button>
            <Button
              type="button"
              {...TABLE_TOOLBAR_BTN_OUTLINE}
              disabled={page >= pageCount || isRefreshing || totalCount === 0 || pageCount <= 1}
              onClick={() => void refreshList(page + 1)}
            >
              Next
            </Button>
          </div>
        </div>
      </section>
    </div>
  );
}
