"use client";

import * as React from "react";

import { getCoreRowModel, useReactTable, type Header } from "@tanstack/react-table";

import {
  DataTablePagination,
  DataTableShell,
  MasterSelectFilterCell,
  MasterTextFilterCell,
  usePrioritySave,
  useServerPagination,
  type ServerPaginationMeta,
} from "@/app/dashboard/_components/data-table";
import { useMasterListFilters } from "@/hooks/use-master-list-filters";
import { Button } from "@/components/ui/button";

import { createCurrencyColumns } from "./columns";
import {
  CURRENCY_STATUS_OPTIONS,
  YES_NO_FILTER_OPTIONS,
  type CurrencyFilters,
  type CurrencyRow,
} from "./schema";

const PRIORITY_SAVE_HREF = "/dashboard/master/currencies/priority";

const FILTER_KEYS = ["name", "code", "isDefault", "status"] as const;
const TEXT_FILTER_KEYS = ["name", "code"] as const;

type Props = {
  data: CurrencyRow[];
  initialFilters: CurrencyFilters;
  pagination: ServerPaginationMeta;
};

export function CurrenciesTable({
  data,
  initialFilters,
  pagination: serverPagination,
}: Props) {
  const { filters, setFilter, drafts, setDraft } = useMasterListFilters(
    initialFilters,
    FILTER_KEYS,
    TEXT_FILTER_KEYS,
  );
  const { priorities, setPriority, savePriorities } = usePrioritySave({
    saveHref: PRIORITY_SAVE_HREF,
    rows: data,
    fallbackError: "Currency priority could not be updated.",
  });
  const { pagination, onPaginationChange, totalCount } = useServerPagination(serverPagination);

  const columns = React.useMemo(
    () => createCurrencyColumns({ priorities, onPriorityChange: setPriority }),
    [priorities, setPriority],
  );

  const table = useReactTable({
    data,
    columns,
    state: { pagination },
    onPaginationChange,
    manualPagination: true,
    pageCount: serverPagination.pageCount,
    rowCount: totalCount,
    getCoreRowModel: getCoreRowModel(),
    getRowId: (row) => String(row.id),
  });

  const renderFilterCell = (header: Header<CurrencyRow, unknown>) => {
    switch (header.column.id) {
      case "name":
        return (
          <MasterTextFilterCell
            cellKey={header.id}
            value={drafts.name}
            placeholder="Currency name"
            onChange={(value) => setDraft("name", value)}
          />
        );
      case "code":
        return (
          <MasterTextFilterCell
            cellKey={header.id}
            value={drafts.code}
            placeholder="Code"
            inputClassName="font-mono uppercase"
            onChange={(value) => setDraft("code", value.toUpperCase())}
          />
        );
      case "isDefault":
        return (
          <MasterSelectFilterCell
            cellKey={header.id}
            value={filters.isDefault}
            placeholder="Is default"
            options={YES_NO_FILTER_OPTIONS}
            onChange={(value) => setFilter("isDefault", value)}
          />
        );
      case "status":
        return (
          <MasterSelectFilterCell
            cellKey={header.id}
            value={filters.status}
            placeholder="Status"
            options={CURRENCY_STATUS_OPTIONS}
            onChange={(value) => setFilter("status", value)}
          />
        );
      default:
        return null;
    }
  };

  return (
    <div className="space-y-4">
      <DataTableShell
        table={table}
        columnCount={columns.length}
        emptyMessage="No currencies match your filters."
        renderFilterCell={renderFilterCell}
      />

      <DataTablePagination
        table={table}
        totalRows={totalCount}
        itemNoun="currency"
        idPrefix="currencies"
      />

      <div className="flex justify-end border-t pt-4">
        <Button type="button" onClick={savePriorities}>
          Update priority
        </Button>
      </div>
    </div>
  );
}
