"use client";
import { useEffect, useState } from "react";
import { useSearchParams } from "next/navigation";
import { DataTable, type Column, type RemoteTableState } from "@/components/shared/data-table";
import {
  DetailList,
  StatusBadge,
} from "@/components/shared/page";
import { Button } from "@/components/ui/button";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { useDashboardAuth } from "@/components/layout/dashboard-auth-context";
import { currency, recentDateTime } from "@/lib/format";
import { topUps } from "./fixtures";
import type { TopUp } from "./model";
import {
  getPaymentTransactions,
  type TransactionPagination,
} from "./transactions-api";
import type { PaymentTransaction } from "./transactions-model";

const pageSizes = [10, 25, 50, 100];
const initialPagination: TransactionPagination = {
  page: 1,
  limit: 10,
  total: 0,
  pages: 1,
};

function fromPreview(row: TopUp): PaymentTransaction {
  return {
    id: row.id,
    transactionType: "TOPUP",
    amount: row.amount,
    currency: "IDR",
    status: row.status,
    channelCode: row.channel,
    createdAt: row.createdAt,
    userId: row.userId,
    email: row.email,
    gateway: row.gateway,
    reference: row.paymentRequest,
  };
}

const previewRows = topUps.map(fromPreview);

function statusLabel(status: string) {
  return status
    .toLowerCase()
    .replaceAll("_", " ")
    .replace(/\b\w/g, (letter) => letter.toUpperCase());
}

function transactionTypeLabel(type: string) {
  return type
    .toLowerCase()
    .replaceAll("_", " ")
    .replace(/\b\w/g, (letter) => letter.toUpperCase());
}

function formatAmount(amount: number, currencyCode: string) {
  const code = currencyCode.toUpperCase();
  if (code === "IDR") return currency(amount);
  try {
    return new Intl.NumberFormat("en-US", {
      style: "currency",
      currency: code,
    }).format(amount);
  } catch {
    return `${code} ${amount.toLocaleString("en-US")}`;
  }
}

function readPage(value: string | null) {
  const page = Number(value);
  return Number.isSafeInteger(page) && page > 0 ? page : 1;
}

function readLimit(value: string | null) {
  const limit = Number(value);
  return pageSizes.includes(limit) ? limit : 10;
}

export function TransactionHistory() {
  const params = useSearchParams();
  const { apiConfigured } = useDashboardAuth();
  const page = readPage(params.get("paginate_page"));
  const limit = readLimit(params.get("paginate_limit"));
  const [remoteRows, setRemoteRows] = useState<PaymentTransaction[]>([]);
  const [pagination, setPagination] =
    useState<TransactionPagination>(initialPagination);
  const [loading, setLoading] = useState(apiConfigured);
  const [error, setError] = useState("");
  const [refreshKey, setRefreshKey] = useState(0);
  const [selected, setSelected] = useState<PaymentTransaction | null>(null);

  useEffect(() => {
    if (!apiConfigured) return;
    const controller = new AbortController();
    async function load() {
      setLoading(true);
      setError("");
      try {
        const result = await getPaymentTransactions(
          { page, limit },
          controller.signal,
        );
        setRemoteRows(result.rows);
        setPagination(result.pagination);
      } catch (err: unknown) {
        if (controller.signal.aborted) return;
        setRemoteRows([]);
        setError(
          err instanceof Error
            ? err.message
            : "Could not load transactions.",
        );
      } finally {
        if (!controller.signal.aborted) setLoading(false);
      }
    }
    void load();
    return () => controller.abort();
  }, [apiConfigured, page, limit, refreshKey]);

  const rows = apiConfigured ? remoteRows : previewRows;
  const columns: Column<PaymentTransaction>[] = [
    {
      key: "id",
      label: "Transaction ID",
      sortKey: apiConfigured ? null : undefined,
    },
    {
      key: "transactionType",
      label: "Type",
      sortKey: apiConfigured ? null : undefined,
      render: (row) => transactionTypeLabel(row.transactionType),
    },
    {
      key: "amount",
      label: "Amount",
      sortKey: apiConfigured ? null : undefined,
      render: (row) => formatAmount(row.amount, row.currency),
    },
    {
      key: "status",
      label: "Status",
      sortKey: apiConfigured ? null : undefined,
      render: (row) => <StatusBadge>{statusLabel(row.status)}</StatusBadge>,
    },
    {
      key: "channelCode",
      label: "Channel",
      sortKey: apiConfigured ? null : undefined,
    },
    {
      key: "createdAt",
      label: "Created At",
      sortKey: apiConfigured ? null : undefined,
      render: (row) => (row.createdAt ? recentDateTime(row.createdAt) : "—"),
    },
  ];

  const remoteTable: RemoteTableState | undefined = apiConfigured
    ? {
        ...pagination,
        loading,
        error,
        onRefresh: () => setRefreshKey((current) => current + 1),
      }
    : undefined;

  return (
    <div className="space-y-5">
      <DataTable
        title="Transaction History"
        description="Review payment transaction types, amounts, and status."
        rows={rows}
        remote={remoteTable}
        hideSearch={apiConfigured}
        pageSizes={apiConfigured ? pageSizes : undefined}
        searchPlaceholder="Transaction, customer or channel..."
        emptyMessage={
          apiConfigured ? "No transactions found." : "No sample transactions found."
        }
        columns={columns}
        actions={(row) => (
          <Button variant="outline" size="sm" onClick={() => setSelected(row)}>
            Details
          </Button>
        )}
      />
      <Dialog
        open={!!selected}
        onOpenChange={(open) => {
          if (!open) setSelected(null);
        }}
      >
        <DialogContent>
          <DialogHeader>
            <DialogTitle>Transaction details</DialogTitle>
            <DialogDescription>
              {selected?.id} · {apiConfigured ? "Live read-only data." : "Sample data."}
            </DialogDescription>
          </DialogHeader>
          {selected && (
            <DetailList
              items={{
                Type: transactionTypeLabel(selected.transactionType),
                Amount: formatAmount(selected.amount, selected.currency),
                Status: <StatusBadge>{statusLabel(selected.status)}</StatusBadge>,
                Channel: selected.channelCode || "—",
                "Payment gateway": selected.gateway || "—",
                ...(selected.userId ? { "User ID": selected.userId } : {}),
                ...(selected.email ? { Email: selected.email } : {}),
                ...(selected.reference ? { Reference: selected.reference } : {}),
                Created: selected.createdAt
                  ? recentDateTime(selected.createdAt)
                  : "—",
              }}
            />
          )}
        </DialogContent>
      </Dialog>
    </div>
  );
}
