"use client";

import { isApiSuccess } from "@/lib/api-messages";
import * as React from "react";
import { useRouter } from "next/navigation";
import {
  flexRender,
  getCoreRowModel,
  useReactTable,
  type PaginationState,
} from "@tanstack/react-table";
import { toast } from "sonner";

import {
  DataTablePagination,
  useDebouncedValue,
} from "@/app/dashboard/_components/data-table";
import { Input } from "@/components/ui/input";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import { SettingsSelect } from "@/components/settings/ui/settings-select";
import { SETTINGS_INPUT_CLASS } from "@/components/settings/constants";
import { requestDashboardApi } from "@/lib/dashboard-api-client";
import { cn } from "@/lib/utils";

import {
  STATUS_FILTER_OPTIONS,
  buildAssetDefinitionHref,
  DEFAULT_PAGE_SIZE,
} from "./constants";
import { createAssetDefinitionColumns } from "./columns";
import type { AssetDefinitionRow } from "./schema";
import { formatPlainAmount } from "@/lib/format/numbers";

const DELETE_HREF = "/dashboard/master-table/asset-definition/delete";

type Props = {
  data: AssetDefinitionRow[];
  filters: {
    masterName: string;
    status: string;
  };
  totalCount: number;
  page: number;
  pageSize: number;
  pageCount: number;
};

const filterInputClass = cn(SETTINGS_INPUT_CLASS, "h-8");

export function AssetDefinitionTable({
  data,
  filters,
  totalCount,
  page,
  pageSize,
  pageCount,
}: Props) {
  const router = useRouter();
  const [masterNameDraft, setMasterNameDraft] = React.useState(filters.masterName);
  const [statusFilter, setStatusFilter] = React.useState(filters.status || "all");
  const debouncedMasterName = useDebouncedValue(masterNameDraft);

  const navigate = React.useCallback(
    (
      next: {
        masterName?: string;
        status?: string;
        page?: number;
        pageSize?: number;
      },
      options?: { replace?: boolean },
    ) => {
      const href = buildAssetDefinitionHref({
        masterName: next.masterName ?? filters.masterName,
        status: next.status ?? filters.status,
        page: next.page ?? page,
        pageSize: next.pageSize ?? pageSize,
      });

      if (options?.replace) {
        router.replace(href, { scroll: false });
        return;
      }

      router.push(href, { scroll: false });
    },
    [filters.masterName, filters.status, page, pageSize, router],
  );

  React.useEffect(() => {
    setMasterNameDraft(filters.masterName);
  }, [filters.masterName]);

  React.useEffect(() => {
    setStatusFilter(filters.status || "all");
  }, [filters.status]);

  React.useEffect(() => {
    const normalized = debouncedMasterName.trim();
    if (normalized === filters.masterName) return;
    navigate({ masterName: normalized, page: 1 }, { replace: true });
  }, [debouncedMasterName, filters.masterName, navigate]);

  const onDelete = React.useCallback(
    async (id: string) => {
      try {
        await requestDashboardApi<{ status?: string }>({
          url: DELETE_HREF,
          method: "POST",
          body: { id },
          fallbackError: "Could not delete asset definition.",
          validate: (payload) => isApiSuccess(payload),
        });
        toast.success("Asset definition deleted.");
        router.refresh();
      } catch (error) {
        toast.error(
          error instanceof Error
            ? error.message
            : "Could not delete asset definition.",
        );
      }
    },
    [router],
  );

  const columns = React.useMemo(
    () => createAssetDefinitionColumns(onDelete),
    [onDelete],
  );

  const displayData = React.useMemo(() => {
    if (!filters.status) return data;
    return data.filter((row) => row.status === filters.status);
  }, [data, filters.status]);

  const pagination = React.useMemo<PaginationState>(
    () => ({
      pageIndex: Math.max(page - 1, 0),
      pageSize,
    }),
    [page, pageSize],
  );

  const table = useReactTable({
    data: displayData,
    columns,
    state: { pagination },
    pageCount,
    manualPagination: true,
    onPaginationChange: (updater) => {
      const next = typeof updater === "function" ? updater(pagination) : updater;
      const nextPageSize = next.pageSize > 0 ? next.pageSize : pageSize;
      const nextPage = nextPageSize !== pageSize ? 1 : Math.max(next.pageIndex + 1, 1);

      navigate({
        page: nextPage,
        pageSize: nextPageSize,
      });
    },
    getCoreRowModel: getCoreRowModel(),
    getRowId: (r) => r.id,
  });

  const start = totalCount === 0 ? 0 : (page - 1) * pageSize + 1;
  const end = Math.min(page * pageSize, totalCount);
  const headers = table.getHeaderGroups()[0]?.headers ?? [];

  return (
    <div className="space-y-4">
      <p className="text-sm text-muted-foreground">
        Displaying {start}–{end} of {formatPlainAmount(totalCount)} results.
      </p>
      <div className="overflow-x-auto rounded-lg border bg-card">
        <Table>
          <TableHeader>
            <TableRow className="bg-muted/40 hover:bg-muted/40">
              {headers.map((h) => (
                <TableHead key={h.id} className="h-10 px-3 whitespace-nowrap">
                  {flexRender(h.column.columnDef.header, h.getContext())}
                </TableHead>
              ))}
            </TableRow>
            <TableRow className="bg-muted/20 hover:bg-muted/20">
              {headers.map((h) => {
                const colId = h.column.id;
                if (colId === "options" || colId === "assetTitles") {
                  return <TableHead key={h.id} className="px-3 py-2" />;
                }
                if (colId === "masterName") {
                  return (
                    <TableHead key={h.id} className="px-3 py-2">
                      <Input
                        className={filterInputClass}
                        placeholder="Filter"
                        value={masterNameDraft}
                        onChange={(e) => setMasterNameDraft(e.target.value)}
                      />
                    </TableHead>
                  );
                }
                if (colId === "status") {
                  return (
                    <TableHead key={h.id} className="px-3 py-2">
                      <SettingsSelect
                        className={filterInputClass}
                        value={statusFilter}
                        onValueChange={(v) => {
                          setStatusFilter(v);
                          navigate(
                            {
                              status: v === "all" ? "" : v,
                              page: 1,
                            },
                            { replace: true },
                          );
                        }}
                        options={STATUS_FILTER_OPTIONS}
                        placeholder="All"
                      />
                    </TableHead>
                  );
                }
                return <TableHead key={h.id} className="px-3 py-2" />;
              })}
            </TableRow>
          </TableHeader>
          <TableBody>
            {table.getRowModel().rows.length ? (
              table.getRowModel().rows.map((row) => (
                <TableRow key={row.id}>
                  {row.getVisibleCells().map((cell) => (
                    <TableCell key={cell.id} className="px-3 py-2.5">
                      {flexRender(
                        cell.column.columnDef.cell,
                        cell.getContext(),
                      )}
                    </TableCell>
                  ))}
                </TableRow>
              ))
            ) : (
              <TableRow>
                <TableCell
                  colSpan={columns.length}
                  className="h-24 text-center text-muted-foreground"
                >
                  No records found.
                </TableCell>
              </TableRow>
            )}
          </TableBody>
        </Table>
      </div>
      <DataTablePagination
        table={table}
        totalRows={totalCount}
        itemNoun="record"
        idPrefix="asset-definition"
        pageSizes={[10, 20, DEFAULT_PAGE_SIZE, 100]}
      />
    </div>
  );
}
