"use client";

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

import { BankSetupTabs } from "@/app/customer/[tenant]/admin/_components/bank-setup-tabs";
import { BankAccountsSheet } from "@/app/customer/[tenant]/admin/link-bank-accounts/_components/bank-accounts-sheet";
import type { PortalLinkBankCustomerRow } from "@/app/customer/_lib/admin/link-bank-accounts-server-api";
import type { PortalUnassignedBankAccountRow } from "@/app/customer/_lib/admin/parent-banks-server-api";
import { isPortfolioScopeVisibleStatus } from "@/config/status-codes";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";

type UnassignedCustomerRow = PortalLinkBankCustomerRow & {
  unassignedCount: number;
};

type UnassignedBanksPageClientProps = {
  tenant: string;
  initialCustomers: PortalLinkBankCustomerRow[];
  initialUnassignedAccounts: PortalUnassignedBankAccountRow[];
  initialErrorMessage: string | null;
  canManage: boolean;
};

function mergeUnassignedCustomers(
  customers: PortalLinkBankCustomerRow[],
  unassignedAccounts: PortalUnassignedBankAccountRow[],
): UnassignedCustomerRow[] {
  const byId = new Map<number, UnassignedCustomerRow>();

  for (const customer of customers) {
    if (!isPortfolioScopeVisibleStatus(customer.status)) {
      continue;
    }
    byId.set(customer.customerId, {
      ...customer,
      unassignedCount: 0,
    });
  }

  for (const account of unassignedAccounts) {
    const existing = byId.get(account.customerId);
    if (!existing) {
      continue;
    }
    existing.unassignedCount += 1;
  }

  return [...byId.values()]
    .filter((row) => row.unassignedCount > 0)
    .sort((a, b) => a.fullName.localeCompare(b.fullName));
}

export function UnassignedBanksPageClient({
  tenant,
  initialCustomers,
  initialUnassignedAccounts,
  initialErrorMessage,
  canManage,
}: UnassignedBanksPageClientProps) {
  const [customers, setCustomers] = React.useState(initialCustomers);
  const [unassignedAccounts, setUnassignedAccounts] = React.useState(
    initialUnassignedAccounts,
  );
  const [search, setSearch] = React.useState("");
  const [selectedCustomer, setSelectedCustomer] =
    React.useState<PortalLinkBankCustomerRow | null>(null);
  const [sheetOpen, setSheetOpen] = React.useState(false);

  const rows = React.useMemo(
    () => mergeUnassignedCustomers(customers, unassignedAccounts),
    [customers, unassignedAccounts],
  );

  const filtered = React.useMemo(() => {
    const q = search.trim().toLowerCase();
    if (!q) return rows;
    return rows.filter((row) =>
      [row.fullName, row.email, row.company, row.subdomain, String(row.customerId)]
        .join(" ")
        .toLowerCase()
        .includes(q),
    );
  }, [rows, search]);

  const openSheet = (customer: PortalLinkBankCustomerRow) => {
    setSelectedCustomer(customer);
    setSheetOpen(true);
  };

  const refreshUnassigned = async () => {
    try {
      const response = await fetch(`/customer/${tenant}/admin/unassigned-banks/list`, {
        headers: { Accept: "application/json" },
        cache: "no-store",
      });
      const data = (await response.json().catch(() => null)) as {
        unassignedAccounts?: PortalUnassignedBankAccountRow[];
      } | null;
      if (Array.isArray(data?.unassignedAccounts)) {
        setUnassignedAccounts(data.unassignedAccounts);
      }
    } catch {
      // Keep the current list if refresh fails; the sheet save already succeeded.
    }
  };

  const handleSaved = (customerId: number, accountCount: number) => {
    setCustomers((prev) => {
      const exists = prev.some((row) => row.customerId === customerId);
      if (!exists) {
        return prev;
      }
      return prev.map((row) =>
        row.customerId === customerId ? { ...row, accountCount } : row,
      );
    });
    void refreshUnassigned();
  };

  return (
    <>
      <div className="flex flex-col gap-4">
        <div className="flex flex-wrap items-start justify-between gap-3">
          <div>
            <div className="flex items-center gap-2">
              <Landmark className="size-5 text-muted-foreground" />
              <h1 className="text-2xl tracking-tight">Unassigned banks</h1>
            </div>
            <p className="mt-1 text-sm text-muted-foreground">
              Customers with bank accounts whose parent bank is still set to None.
            </p>
          </div>
        </div>

        <BankSetupTabs tenant={tenant} active="unassigned" />

        <div className="relative w-full max-w-sm">
          <Search className="pointer-events-none absolute left-2.5 top-1/2 size-4 -translate-y-1/2 text-muted-foreground" />
          <Input
            value={search}
            placeholder="Search by name, email, company, or subdomain"
            className="pl-8"
            onChange={(event) => setSearch(event.target.value)}
          />
        </div>

        {initialErrorMessage ? (
          <p className="rounded-md border border-destructive/30 bg-destructive/5 px-3 py-2 text-sm text-destructive">
            {initialErrorMessage}
          </p>
        ) : null}

        <div className="rounded-md border">
          <Table>
            <TableHeader>
              <TableRow className="bg-muted/40 hover:bg-muted/40">
                <TableHead className="px-3">Customer</TableHead>
                <TableHead className="px-3">Subdomain</TableHead>
                <TableHead className="px-3 text-center">Bank accounts</TableHead>
                <TableHead className="px-3 text-center">Unassigned rows</TableHead>
                <TableHead className="px-3 text-right">Actions</TableHead>
              </TableRow>
            </TableHeader>
            <TableBody>
              {filtered.length ? (
                filtered.map((row) => (
                  <TableRow key={row.customerId}>
                    <TableCell className="px-3 py-2.5">
                      <div className="flex flex-col">
                        <span className="font-medium">
                          {row.fullName || `#${row.customerId}`}
                        </span>
                        <span className="text-xs text-muted-foreground">
                          {[row.email, row.company].filter(Boolean).join(" · ") ||
                            `Customer #${row.customerId}`}
                        </span>
                      </div>
                    </TableCell>
                    <TableCell className="px-3 py-2.5 text-muted-foreground">
                      {row.subdomain || "—"}
                    </TableCell>
                    <TableCell className="px-3 py-2.5 text-center">
                      <Badge variant={row.accountCount > 0 ? "secondary" : "outline"}>
                        {row.accountCount}
                      </Badge>
                    </TableCell>
                    <TableCell className="px-3 py-2.5 text-center">
                      <Badge variant={row.unassignedCount > 0 ? "outline" : "secondary"}>
                        {row.unassignedCount}
                      </Badge>
                    </TableCell>
                    <TableCell className="px-3 py-2.5 text-right">
                      <Button size="sm" variant="outline" onClick={() => openSheet(row)}>
                        <Wallet className="size-3.5" />
                        {canManage ? "Manage" : "View"}
                      </Button>
                    </TableCell>
                  </TableRow>
                ))
              ) : (
                <TableRow>
                  <TableCell colSpan={5} className="h-24 text-center text-muted-foreground">
                    {search.trim()
                      ? "No customers match this search."
                      : "Every bank account has a parent bank assigned."}
                  </TableCell>
                </TableRow>
              )}
            </TableBody>
          </Table>
        </div>
      </div>

      <BankAccountsSheet
        tenant={tenant}
        customer={selectedCustomer}
        open={sheetOpen}
        canManage={canManage}
        onOpenChange={setSheetOpen}
        onSaved={handleSaved}
      />
    </>
  );
}
