"use client";

import Link from "next/link";
import * as React from "react";
import {
  Bell,
  Loader2,
  Lock,
  MessagesSquare,
  Pin,
  Plus,
  RefreshCw,
  Search,
} from "lucide-react";

import { fetchDiscussionBoardListClient } from "@/app/customer/[tenant]/discussion-board/_lib/discussion-board-api";
import type {
  DiscussionListFilters,
  DiscussionTagOption,
  DiscussionThreadListItem,
} from "@/app/customer/[tenant]/discussion-board/_lib/types";
import {
  DISCUSSION_STATUS_FILTER_OPTIONS,
  DISCUSSION_STATUS_LABELS,
} 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 { Checkbox } from "@/components/ui/checkbox";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import { SETTINGS_INPUT_CLASS } from "@/components/settings/constants";
import { customerUrl } from "@/lib/tenant";
import { cn } from "@/lib/utils";

type CustomerDiscussionBoardPageProps = {
  tenant: string;
  initialItems: DiscussionThreadListItem[];
  initialTags: DiscussionTagOption[];
  initialTotalCount: number;
  initialPage: number;
  initialPageSize: number;
  initialPageCount: number;
  initialUnreadCount: number;
  initialNotificationUnreadCount: number;
  initialCanCreate: boolean;
  initialErrorMessage?: string | null;
  permissionDenied?: boolean;
};

function statusLabel(status: string) {
  return DISCUSSION_STATUS_LABELS[status] ?? status;
}

export function CustomerDiscussionBoardPage({
  tenant,
  initialItems,
  initialTags,
  initialTotalCount,
  initialPage,
  initialPageSize,
  initialPageCount,
  initialUnreadCount,
  initialNotificationUnreadCount,
  initialCanCreate,
  initialErrorMessage = null,
  permissionDenied = false,
}: CustomerDiscussionBoardPageProps) {
  const [items, setItems] = React.useState(initialItems);
  const [tags] = React.useState(initialTags);
  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 [notificationUnreadCount, setNotificationUnreadCount] = React.useState(
    initialNotificationUnreadCount,
  );
  const [canCreate] = React.useState(initialCanCreate);
  const [listError, setListError] = React.useState(initialErrorMessage);
  const [isRefreshing, setIsRefreshing] = React.useState(false);

  const [searchInput, setSearchInput] = React.useState("");
  const [filters, setFilters] = React.useState<DiscussionListFilters>({});

  const notificationsHref = customerUrl(tenant, "/discussion-board/notifications");
  const createHref = customerUrl(tenant, "/discussion-board/create");

  const refreshList = React.useCallback(
    async (nextPage = page, nextFilters = filters, nextSearch = searchInput) => {
      setIsRefreshing(true);
      setListError(null);
      try {
        const data = await fetchDiscussionBoardListClient(
          tenant,
          {
            ...nextFilters,
            q: nextSearch.trim() || undefined,
          },
          { page: nextPage, pageSize },
        );
        setItems(data.items);
        setTotalCount(data.totalCount);
        setPage(nextPage);
        setPageCount(data.pageCount);
        setUnreadCount(data.unreadCount);
        setNotificationUnreadCount(data.notificationUnreadCount);
      } catch (error) {
        setListError(error instanceof Error ? error.message : "Failed to load discussion threads");
      } finally {
        setIsRefreshing(false);
      }
    },
    [filters, page, pageSize, searchInput, tenant],
  );

  React.useEffect(() => {
    const timer = window.setTimeout(() => {
      void refreshList(1, filters, searchInput);
    }, 300);
    return () => window.clearTimeout(timer);
  }, [filters, searchInput]); // eslint-disable-line react-hooks/exhaustive-deps

  if (permissionDenied) {
    return (
      <div className="flex flex-col gap-3 md:gap-4">
        <div className="flex items-center gap-2 border-b pb-3">
          <MessagesSquare className="size-5 text-violet-600" />
          <h1 className="font-semibold text-base tracking-tight">Discussion Board</h1>
        </div>
        <ErrorBanner message="You do not have permission to access the Discussion Board." />
      </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">
          <MessagesSquare className="size-5 text-violet-600" />
          <h1 className="font-semibold text-base tracking-tight">Discussion Board</h1>
        </div>
        <div className="flex flex-wrap items-center gap-2">
          {unreadCount > 0 ? (
            <span className="text-muted-foreground text-xs">{unreadCount} unread thread(s)</span>
          ) : null}
          <Button variant="outline" size="sm" className="relative gap-1.5" asChild>
            <Link href={notificationsHref}>
              <Bell className="size-4" />
              Notifications
              {notificationUnreadCount > 0 ? (
                <Badge className="absolute -top-1.5 -right-1.5 flex size-5 items-center justify-center rounded-full p-0 text-[10px]">
                  {notificationUnreadCount > 99 ? "99+" : notificationUnreadCount}
                </Badge>
              ) : null}
            </Link>
          </Button>
          {canCreate ? (
            <Button size="sm" className="gap-1.5" asChild>
              <Link href={createHref}>
                <Plus className="size-4" />
                New topic
              </Link>
            </Button>
          ) : null}
          <Button
            type="button"
            {...TABLE_TOOLBAR_BTN_OUTLINE}
            disabled={isRefreshing}
            onClick={() => void refreshList(page)}
          >
            {isRefreshing ? <Loader2 className="size-3.5 animate-spin" /> : <RefreshCw className="size-3.5" />}
            Refresh
          </Button>
        </div>
      </div>

      <p className="text-muted-foreground text-sm">
        Browse topics, join conversations, and stay updated on new replies.
      </p>

      <ErrorBanner message={listError} />

      <section className="rounded-lg border">
        <div className="border-b bg-muted/30 px-3 py-2">
          <h2 className="text-sm font-semibold">Filters</h2>
        </div>
        <div className="grid gap-3 p-3 sm:grid-cols-2 lg:grid-cols-4">
          <div className="space-y-1.5 sm:col-span-2">
            <Label className="text-xs">Search</Label>
            <div className="relative">
              <Search className="text-muted-foreground absolute top-1/2 left-3 size-4 -translate-y-1/2" />
              <Input
                className={cn(SETTINGS_INPUT_CLASS, "h-9 pl-9")}
                value={searchInput}
                onChange={(event) => setSearchInput(event.target.value)}
                placeholder="Search topics…"
              />
            </div>
          </div>
          <div className="space-y-1.5">
            <Label className="text-xs">Status</Label>
            <Select
              value={filters.status || "__all__"}
              onValueChange={(value) =>
                setFilters((prev) => ({ ...prev, status: value === "__all__" ? "" : value }))
              }
            >
              <SelectTrigger className={cn(SETTINGS_INPUT_CLASS, "h-9")}>
                <SelectValue placeholder="All statuses" />
              </SelectTrigger>
              <SelectContent>
                {DISCUSSION_STATUS_FILTER_OPTIONS.map((option) => (
                  <SelectItem key={option.value || "__all__"} value={option.value || "__all__"}>
                    {option.label}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>
          <div className="space-y-1.5">
            <Label className="text-xs">Tag</Label>
            <Select
              value={filters.tag_id ? String(filters.tag_id) : "__all__"}
              onValueChange={(value) =>
                setFilters((prev) => ({
                  ...prev,
                  tag_id: value === "__all__" ? undefined : Number(value),
                }))
              }
            >
              <SelectTrigger className={cn(SETTINGS_INPUT_CLASS, "h-9")}>
                <SelectValue placeholder="All tags" />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="__all__">All tags</SelectItem>
                {tags.map((tag) => (
                  <SelectItem key={tag.tag_id} value={String(tag.tag_id)}>
                    {tag.label}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>
          <div className="flex items-end gap-2 pb-0.5">
            <Checkbox
              id="unread-only"
              checked={Boolean(filters.unread)}
              onCheckedChange={(checked) =>
                setFilters((prev) => ({ ...prev, unread: checked === true }))
              }
            />
            <Label htmlFor="unread-only" className="text-xs font-normal">
              Unread only
            </Label>
          </div>
        </div>
      </section>

      <section className="rounded-lg border">
        <div className="overflow-x-auto">
          <Table>
            <TableHeader>
              <TableRow>
                <TableHead>Topic</TableHead>
                <TableHead>Author</TableHead>
                <TableHead>Status</TableHead>
                <TableHead className="w-20 text-center">Votes</TableHead>
                <TableHead className="w-20 text-center">Comments</TableHead>
                <TableHead>Last activity</TableHead>
              </TableRow>
            </TableHeader>
            <TableBody>
              {items.length === 0 ? (
                <TableRow>
                  <TableCell colSpan={6} className="text-muted-foreground h-24 text-center">
                    No topics found.
                  </TableCell>
                </TableRow>
              ) : (
                items.map((thread) => {
                  const viewHref = customerUrl(
                    tenant,
                    `/discussion-board/view/${encodeURIComponent(thread.token)}`,
                  );
                  return (
                    <TableRow key={thread.thread_id} className={thread.is_unread ? "bg-muted/20" : ""}>
                      <TableCell>
                        <Link
                          href={viewHref}
                          className="flex flex-col gap-0.5 font-medium hover:underline"
                        >
                          <span className="flex items-center gap-1.5">
                            {thread.is_pinned ? <Pin className="size-3.5 text-amber-600" /> : null}
                            {thread.is_locked ? <Lock className="size-3.5 text-muted-foreground" /> : null}
                            {thread.is_unread ? (
                              <span className="size-2 rounded-full bg-violet-600" aria-hidden />
                            ) : null}
                            <span className="truncate">{thread.title}</span>
                          </span>
                          <span className="text-muted-foreground truncate text-xs font-normal">
                            {thread.visibilityLabel}
                          </span>
                        </Link>
                      </TableCell>
                      <TableCell className="text-sm">{thread.authorDisplayName || "—"}</TableCell>
                      <TableCell>
                        <Badge variant="secondary" className="text-xs">
                          {statusLabel(thread.status)}
                        </Badge>
                      </TableCell>
                      <TableCell className="text-center text-xs">
                        <span className="text-green-700">+{thread.upvote_count}</span>
                        {" / "}
                        <span className="text-red-700">-{thread.downvote_count}</span>
                      </TableCell>
                      <TableCell className="text-center text-sm">{thread.comment_count}</TableCell>
                      <TableCell className="whitespace-nowrap text-xs">
                        {thread.last_activity_at || thread.published_at || "—"}
                      </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 topics"
              : `Page ${page} of ${Math.max(pageCount, 1)} · ${totalCount} topic${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>
  );
}
