"use client";

import * as React from "react";
import { Landmark, Wallet } from "lucide-react";

import { Badge } from "@/components/ui/badge";
import { Label } from "@/components/ui/label";
import { NativeSelect, NativeSelectOption } from "@/components/ui/native-select";

import { fetchCashBalanceFormContextClient } from "../_lib/cash-api";
import { CashBalanceEditor } from "./cash-balance-editor";
import { ListCashTable } from "./list-cash-table/table";

type SelectOption = { id: string; name: string };

const ALL_VALUE = "All";

function resolveBankOptions(
  banks: Array<{ bank_id?: string | number | null; bank_name?: string | null }>,
): SelectOption[] {
  const seen = new Set<string>();
  const options: SelectOption[] = [];

  for (const bank of banks) {
    const id = String(bank.bank_id ?? "").trim();
    const name = String(bank.bank_name ?? "").trim();
    if (!id || id === "0" || !name || seen.has(id)) continue;
    seen.add(id);
    options.push({ id, name });
  }

  options.sort((a, b) => a.name.localeCompare(b.name));
  return options;
}

function resolveCustomerOptions(
  customers: Array<{ customer_id?: string | number | null; customer_name?: string | null }>,
): SelectOption[] {
  const seen = new Set<string>();
  const options: SelectOption[] = [];

  for (const row of customers) {
    const id = String(row.customer_id ?? "").trim();
    if (!id || id === "0" || seen.has(id)) continue;
    const name = String(row.customer_name ?? "").trim() || id;
    seen.add(id);
    options.push({ id, name });
  }

  options.sort((a, b) => a.name.localeCompare(b.name));
  return options;
}

export function CorporateCashPage() {
  const [userId, setUserId] = React.useState(ALL_VALUE);
  const [bankId, setBankId] = React.useState(ALL_VALUE);
  const [users, setUsers] = React.useState<SelectOption[]>([]);
  const [banks, setBanks] = React.useState<SelectOption[]>([]);
  const [optionsError, setOptionsError] = React.useState<string | null>(null);
  const [isUsersLoading, setIsUsersLoading] = React.useState(true);
  const [isBanksLoading, setIsBanksLoading] = React.useState(true);
  const usersLoadedRef = React.useRef(false);

  React.useEffect(() => {
    let cancelled = false;

    async function loadFilters() {
      setIsBanksLoading(true);
      if (!usersLoadedRef.current) {
        setIsUsersLoading(true);
      }
      setOptionsError(null);

      try {
        const payload =
          userId !== ALL_VALUE
            ? { clientid: userId, customer_id: userId, impersonated_customer_ids: userId }
            : {};
        const formContext = await fetchCashBalanceFormContextClient(payload);
        if (cancelled) return;

        if (!usersLoadedRef.current) {
          setUsers(resolveCustomerOptions(formContext.customers ?? []));
          usersLoadedRef.current = true;
        }

        const nextBanks = resolveBankOptions(formContext.banks ?? []);
        setBanks(nextBanks);
        setBankId((current) => {
          if (current === ALL_VALUE) return current;
          return nextBanks.some((bank) => bank.id === current) ? current : ALL_VALUE;
        });
      } catch (error) {
        if (!cancelled) {
          if (!usersLoadedRef.current) {
            setUsers([]);
          }
          setBanks([]);
          setOptionsError(error instanceof Error ? error.message : "Failed to load cash filters.");
        }
      } finally {
        if (!cancelled) {
          setIsUsersLoading(false);
          setIsBanksLoading(false);
        }
      }
    }

    void loadFilters();
    return () => {
      cancelled = true;
    };
  }, [userId]);

  const showCardView = userId !== ALL_VALUE && bankId !== ALL_VALUE;
  const listAccountId = userId !== ALL_VALUE ? userId : undefined;
  const listBankId = bankId !== ALL_VALUE ? bankId : undefined;
  const isOptionsLoading = isUsersLoading || isBanksLoading;

  return (
    <div className="flex min-h-full w-full min-w-0 flex-1 flex-col bg-muted/20">
      <div className="flex w-full min-w-0 flex-1 flex-col gap-6 px-4 pt-6 pb-10 lg:gap-8 lg:px-6 lg:pt-8">
        <header className="flex w-full min-w-0 flex-col gap-4 border-b border-border/60 pb-5">
          <div className="flex min-w-0 items-start gap-4">
            <div className="flex size-11 shrink-0 items-center justify-center rounded-xl border border-primary/20 bg-primary/10 text-primary shadow-xs">
              {showCardView ? <Wallet className="size-5" /> : <Landmark className="size-5" />}
            </div>
            <div className="min-w-0">
              <div className="flex flex-wrap items-center gap-2">
                <h1 className="font-semibold text-2xl tracking-tight text-foreground">
                  {showCardView ? "List Cash Balance" : "Cash Transaction"}
                </h1>
                <Badge variant="outline" className="font-normal">
                  FX &amp; Currency
                </Badge>
              </div>
              <p className="mt-1 text-muted-foreground text-sm leading-relaxed">
                {showCardView
                  ? "Currency balances for the selected user and bank."
                  : "Browse cash balances across users and banks."}
              </p>
            </div>
          </div>
        </header>

        <section className="overflow-hidden rounded-xl border border-border/60 bg-card shadow-sm">
          <div className="border-b border-border/50 bg-muted/25 px-5 py-4 sm:px-6">
            <p className="font-semibold text-base tracking-tight">Filters</p>
            <p className="mt-0.5 text-muted-foreground text-sm">
              Select a specific user and bank to open the balance cards. Otherwise the cash
              transaction list is shown.
            </p>
          </div>

          <div className="grid gap-4 px-5 py-5 sm:grid-cols-2 sm:px-6 lg:max-w-3xl">
            <div className="grid gap-2">
              <Label htmlFor="corporate-cash-user">User</Label>
              <NativeSelect
                id="corporate-cash-user"
                value={userId}
                disabled={isUsersLoading}
                onChange={(event) => {
                  setUserId(event.target.value || ALL_VALUE);
                  setBankId(ALL_VALUE);
                }}
                className="w-full"
              >
                <NativeSelectOption value={ALL_VALUE}>All</NativeSelectOption>
                {users.map((user) => (
                  <NativeSelectOption key={`user-${user.id}`} value={user.id}>
                    {user.name}
                  </NativeSelectOption>
                ))}
              </NativeSelect>
            </div>

            <div className="grid gap-2">
              <Label htmlFor="corporate-cash-bank">Bank</Label>
              <NativeSelect
                id="corporate-cash-bank"
                value={bankId}
                disabled={isOptionsLoading}
                onChange={(event) => setBankId(event.target.value || ALL_VALUE)}
                className="w-full"
              >
                <NativeSelectOption value={ALL_VALUE}>All</NativeSelectOption>
                {banks.map((bank) => (
                  <NativeSelectOption key={`bank-${bank.id}`} value={bank.id}>
                    {bank.name}
                  </NativeSelectOption>
                ))}
              </NativeSelect>
            </div>
          </div>

          {optionsError ? (
            <p className="px-5 pb-5 text-destructive text-sm sm:px-6">{optionsError}</p>
          ) : null}
        </section>

        {showCardView ? (
          <CashBalanceEditor
            corporateView
            lockedBankId={bankId}
            lockedCustomerId={userId}
            hidePageChrome
          />
        ) : (
          <ListCashTable accountId={listAccountId} bankId={listBankId} />
        )}
      </div>
    </div>
  );
}
