"use client";

import * as React from "react";

import {
  getCoreRowModel,
  useReactTable,
  type Header,
  type PaginationState,
} from "@tanstack/react-table";
import { useRouter } from "next/navigation";
import { toast } from "sonner";

import {
  DataTablePagination,
  DataTableShell,
  useDebouncedValue,
} from "@/app/dashboard/_components/data-table";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { TableCell } from "@/components/ui/table";

import { missingAccumulatorMasterColumns } from "./columns";
import {
  buildMissingAccumulatorMasterHref,
  DEFAULT_PAGE_SIZE,
} from "./constants";
import type { MissingAccumulatorMasterRow } from "./schema";

type Props = {
  data: MissingAccumulatorMasterRow[];
  filters: {
    ticker: string;
    xmlId: string;
    bankName: string;
    tempId: string;
  };
  totalCount: number;
  page: number;
  pageSize: number;
  pageCount: number;
};

export function MissingAccumulatorMasterTable({
  data,
  filters,
  totalCount,
  page,
  pageSize,
  pageCount,
}: Props) {
  const router = useRouter();
  const [tickerDraft, setTickerDraft] = React.useState(filters.ticker);
  const [xmlIdDraft, setXmlIdDraft] = React.useState(filters.xmlId);
  const [bankNameDraft, setBankNameDraft] = React.useState(filters.bankName);
  const [tempIdDraft, setTempIdDraft] = React.useState(filters.tempId);
  const debouncedTicker = useDebouncedValue(tickerDraft);
  const debouncedXmlId = useDebouncedValue(xmlIdDraft);
  const debouncedBankName = useDebouncedValue(bankNameDraft);
  const debouncedTempId = useDebouncedValue(tempIdDraft);

  const navigate = React.useCallback(
    (
      next: {
        ticker?: string;
        xmlId?: string;
        bankName?: string;
        tempId?: string;
        page?: number;
        pageSize?: number;
      },
      options?: { replace?: boolean },
    ) => {
      const href = buildMissingAccumulatorMasterHref({
        ticker: next.ticker ?? filters.ticker,
        xmlId: next.xmlId ?? filters.xmlId,
        bankName: next.bankName ?? filters.bankName,
        tempId: next.tempId ?? filters.tempId,
        page: next.page ?? page,
        pageSize: next.pageSize ?? pageSize,
      });

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

      router.push(href, { scroll: false });
    },
    [
      filters.bankName,
      filters.tempId,
      filters.ticker,
      filters.xmlId,
      page,
      pageSize,
      router,
    ],
  );

  React.useEffect(() => {
    setTickerDraft(filters.ticker);
  }, [filters.ticker]);

  React.useEffect(() => {
    setXmlIdDraft(filters.xmlId);
  }, [filters.xmlId]);

  React.useEffect(() => {
    setBankNameDraft(filters.bankName);
  }, [filters.bankName]);

  React.useEffect(() => {
    setTempIdDraft(filters.tempId);
  }, [filters.tempId]);

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

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

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

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

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

  const table = useReactTable({
    data,
    columns: missingAccumulatorMasterColumns,
    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: (row) => String(row.id),
  });

  return (
    <div className="space-y-4">
      <DataTableShell
        table={table}
        columnCount={missingAccumulatorMasterColumns.length}
        emptyMessage="No records found."
        renderFilterCell={(header) =>
          renderFilterCell(
            header,
            tickerDraft,
            setTickerDraft,
            xmlIdDraft,
            setXmlIdDraft,
            bankNameDraft,
            setBankNameDraft,
            tempIdDraft,
            setTempIdDraft,
          )
        }
      />

      <DataTablePagination
        table={table}
        totalRows={totalCount}
        itemNoun="record"
        idPrefix="missing-accumulator-master"
        pageSizes={[25, DEFAULT_PAGE_SIZE, 100]}
      />

      <div className="flex justify-end border-t pt-4">
        <Button
          type="button"
          onClick={() => toast.success("Priority updated (mock — connect API when ready)")}
        >
          Update priority
        </Button>
      </div>
    </div>
  );
}

function renderFilterCell(
  header: Header<MissingAccumulatorMasterRow, unknown>,
  tickerDraft: string,
  setTickerDraft: (value: string) => void,
  xmlIdDraft: string,
  setXmlIdDraft: (value: string) => void,
  bankNameDraft: string,
  setBankNameDraft: (value: string) => void,
  tempIdDraft: string,
  setTempIdDraft: (value: string) => void,
) {
  if (header.column.id === "ticker") {
    return (
      <TableCell key={header.id} className="p-2">
        <Input
          value={tickerDraft}
          onChange={(event) => setTickerDraft(event.target.value)}
          placeholder="Ticker"
          className="h-8 bg-background font-mono text-xs"
        />
      </TableCell>
    );
  }

  if (header.column.id === "xmlId") {
    return (
      <TableCell key={header.id} className="p-2">
        <Input
          value={xmlIdDraft}
          onChange={(event) => setXmlIdDraft(event.target.value)}
          placeholder="Upload / Bank API"
          className="h-8 bg-background text-xs"
        />
      </TableCell>
    );
  }

  if (header.column.id === "bankName") {
    return (
      <TableCell key={header.id} className="p-2">
        <Input
          value={bankNameDraft}
          onChange={(event) => setBankNameDraft(event.target.value)}
          placeholder="Bank API"
          className="h-8 bg-background text-xs"
        />
      </TableCell>
    );
  }

  if (header.column.id === "id") {
    return (
      <TableCell key={header.id} className="p-2">
        <Input
          value={tempIdDraft}
          onChange={(event) => setTempIdDraft(event.target.value)}
          placeholder="Temp ID"
          className="h-8 bg-background text-xs"
        />
      </TableCell>
    );
  }

  return null;
}
