"use client";

import * as React from "react";

import { CustomerStandardAssetListTable } from "@/app/customer/_components/customer-standard-asset-list-table";
import { useCustomerPortalSession } from "@/app/customer/_components/customer-portal-session-context";
import type { CustomerPagePermissions } from "@/app/customer/_lib/customer-api-permissions";
import type { CustomerTransactionModuleId } from "@/app/customer/_lib/customer-asset-modules";
import { useCustomerModuleListPath } from "@/components/form/transaction-workspace/list-table-form-actions";
import { CUSTOMER_MODULE_PATHS } from "@/config/customer-module-paths";

import {
  createFixedDepositColumns,
  FALLBACK_FIXED_DEPOSIT_GRID_COLUMNS,
  FIXED_DEPOSIT_OPTIONS_COLUMN_ID,
} from "../../../fixed-deposit/_components/list-fixed-deposit-table/columns";
import { FixedDepositDetailSheet } from "../../../fixed-deposit/_components/list-fixed-deposit-table/fixed-deposit-detail-sheet";
import { FixedDepositListFilterRow } from "../../../fixed-deposit/_components/list-fixed-deposit-table/fixed-deposit-list-filter-row";
import type { FixedDepositRow } from "../../../fixed-deposit/_components/list-fixed-deposit-table/schema";
import {
  buildFixedDepositPageSearchParams,
  DEFAULT_FIXED_DEPOSIT_PAGE_SIZE,
  DEFAULT_FIXED_DEPOSIT_SORTING,
  EMPTY_FIXED_DEPOSIT_FILTERS,
  getFixedDepositFilterColumnValue,
  parseFixedDepositPageStateFromSearchParams,
  placementDateRangeToFixedDepositFilters,
  setFixedDepositFilterColumnValue,
} from "../../../fixed-deposit/_lib/fixed-deposit-filters";
import { saveDepositColumnPrefsClient } from "../../_lib/deposit-api";
import { useDepositList } from "../../_lib/use-deposit-list";
import { DepositCreateMenu } from "../deposit-create-menu";
import { usePortfolioScopePageReset } from "@/app/customer/_lib/admin/use-portfolio-scope-page-reset";

type DepositPagePermissions = CustomerPagePermissions & {
  fixed_deposit_create?: boolean;
  call_deposit_create?: boolean;
};

function isCallDepositRow(row: FixedDepositRow): boolean {
  return row.fType === "Cl" || row.type.toLowerCase().includes("call");
}

/** Own component so the session hook stays out of the toolbarActions render callback. */
function DepositToolbar({ permissions }: { permissions: DepositPagePermissions }) {
  const { canCreateTransactions } = useCustomerPortalSession();
  const showCreateMenu =
    canCreateTransactions &&
    Boolean(
      permissions.fixed_deposit_create || permissions.call_deposit_create || permissions.create,
    );

  return showCreateMenu ? <DepositCreateMenu permissions={permissions} /> : null;
}

export function ListDepositsTable() {
  const fixedDepositPath = useCustomerModuleListPath(CUSTOMER_MODULE_PATHS.fixedDeposit);
  const callDepositPath = useCustomerModuleListPath(CUSTOMER_MODULE_PATHS.callDeposit);

  // This hub lists fixed and call deposits together, so edit navigation and the
  // delete/update module have to be resolved per row rather than per page.
  const resolveFormListPath = React.useCallback(
    (row: FixedDepositRow) => (isCallDepositRow(row) ? callDepositPath : fixedDepositPath),
    [callDepositPath, fixedDepositPath],
  );

  const resolveModuleId = React.useCallback(
    (row: FixedDepositRow): CustomerTransactionModuleId =>
      isCallDepositRow(row) ? "call-deposit" : "fixed-deposit",
    [],
  );

  return (
    <CustomerStandardAssetListTable
      title="List Deposits"
      emptyMessage="No deposits found."
      rowsPerPageId="deposit-rows-per-page"
      singularName="Deposit"
      formConfig={{ listPath: CUSTOMER_MODULE_PATHS.fixedDeposit, newButtonLabel: "New deposit" }}
      resolveEditListPath={resolveFormListPath}
      resolveModuleId={resolveModuleId}
      optionsColumnId={FIXED_DEPOSIT_OPTIONS_COLUMN_ID}
      fallbackColumns={FALLBACK_FIXED_DEPOSIT_GRID_COLUMNS}
      defaultPageSize={DEFAULT_FIXED_DEPOSIT_PAGE_SIZE}
      defaultSorting={DEFAULT_FIXED_DEPOSIT_SORTING}
      emptyFilters={EMPTY_FIXED_DEPOSIT_FILTERS}
      useList={useDepositList}
      saveColumnPrefs={saveDepositColumnPrefsClient}
      parsePageState={parseFixedDepositPageStateFromSearchParams}
      buildPageSearchParams={buildFixedDepositPageSearchParams}
      getFilterColumnValue={getFixedDepositFilterColumnValue}
      setFilterColumnValue={setFixedDepositFilterColumnValue}
      placementDateRangeToFilters={placementDateRangeToFixedDepositFilters}
      // Deposits carry no price/quantity columns — amount is the only range filter.
      getRangeFilters={(filters) => ({ amount: filters.amount })}
      applyRangeFilter={(filters, field, value) =>
        field === "amount" ? { ...filters, amount: value } : filters
      }
      createColumns={(catalog, onView, onEdit, options) =>
        createFixedDepositColumns(catalog, onView, onEdit, {
          resolveFormListPath,
          pagePermissions: options.pagePermissions,
        })
      }
      DetailSheet={FixedDepositDetailSheet}
      showNewButton={false}
      toolbarActions={({ permissions }) => <DepositToolbar permissions={permissions} />}
      showFilterRow={false}
      filterRow={(ctx) => (
        <FixedDepositListFilterRow
          filterOptions={ctx.filterOptions}
          placementDateRange={ctx.placementDateRange}
          onPlacementDateRangeChange={ctx.onPlacementDateRangeChange}
          getFilterValue={ctx.getFilterValue}
          onColumnFilterChange={ctx.onColumnFilterChange}
          amountRange={ctx.filters.amount ?? {}}
          onAmountRangeChange={(value) => ctx.onRangeFilterChange("amount", value)}
        />
      )}
    />
  );
}
