import {
  ActionIcon,
  Box,
  Card,
  Group,
  Badge,
  Badge as MantineBadge,
  Select,
  Stack,
  Tabs,
  Text,
  TextInput,
} from "@mantine/core";
import {
  CheckCircle2,
  CircleDollarSign,
  LayoutGrid,
  Loader2,
  RotateCcw,
  Search,
  X,
  XCircle,
} from "lucide-react";
import { useMemo, useState } from "react";

import { useQuery } from "@tanstack/react-query";

import { KpiStrip, PageContainer, PageHeader } from "@/components/page";
import { api } from "@/services/api";
import type { PaymentMethod, PaymentRow } from "@/services/payments.service";
import {
  DataTable,
  DataTableFooter,
  usePagination,
  type ColumnDef,
} from "@edr/ui-common";

const STATUS_TABS = [
  {
    key: "all",
    label: "All",
    statuses: undefined as string | undefined,
    icon: LayoutGrid,
  },
  { key: "success", label: "Success", statuses: "success", icon: CheckCircle2 },
  {
    key: "processing",
    label: "Processing",
    statuses: "processing,action-required",
    icon: Loader2,
  },
  {
    key: "failed",
    label: "Failed",
    statuses: "failed,canceled",
    icon: XCircle,
  },
  { key: "refunded", label: "Refunded", statuses: "refunded", icon: RotateCcw },
] as const;

type StatusTabKey = (typeof STATUS_TABS)[number]["key"];

const METHOD_OPTIONS: { value: PaymentMethod; label: string }[] = [
  { value: "telebirr", label: "Telebirr" },
  { value: "waafi", label: "Waafi" },
  { value: "cbe-birr", label: "CBE Birr" },
  { value: "ebirr", label: "E-Birr" },
  { value: "card", label: "Card" },
  { value: "dmoney", label: "D-Money" },
  { value: "cac-bank", label: "CAC Bank" },
];

const STATUS_COLORS: Record<string, string> = {
  success: "edr-green",
  processing: "yellow",
  "action-required": "yellow",
  failed: "red",
  canceled: "gray",
  refunded: "indigo",
};

function formatAmount(amount: number, currency: string): string {
  return `${currency} ${Number(amount).toLocaleString(undefined, {
    minimumFractionDigits: 2,
  })}`;
}

function formatDate(iso: string | null): string {
  if (!iso) return "—";
  const d = new Date(iso);
  return Number.isNaN(d.getTime())
    ? "—"
    : d.toLocaleDateString(undefined, {
      year: "numeric",
      month: "short",
      day: "numeric",
    });
}

const tableHeader =
  "text-xs font-semibold uppercase tracking-wide text-muted-foreground";

export default function PaymentsPage() {
  const { pagination, setPagination } = usePagination({ pageSize: 10 });
  const [query, setQuery] = useState("");
  const [statusTab, setStatusTab] = useState<StatusTabKey>("all");
  const [method, setMethod] = useState<string | null>(null);

  const statuses = STATUS_TABS.find((t) => t.key === statusTab)?.statuses;

  const filter = useMemo(
    () => ({
      search: query.trim() || undefined,
      status: statuses,
      method: method ?? undefined,
      page: pagination.pageIndex + 1,
      pageSize: pagination.pageSize,
    }),
    [query, statuses, method, pagination.pageIndex, pagination.pageSize],
  );

  const { data, isLoading, isError } = useQuery(
    api.payments.list.queryOptions({ input: { filter } }),
  );
  const { data: summary, isLoading: summaryLoading } = useQuery(
    api.payments.summary.queryOptions({ staleTime: 30_000 }),
  );

  const rows = data?.items ?? [];
  const total = data?.total ?? 0;
  const pageCount = Math.max(1, Math.ceil(total / pagination.pageSize));

  const tabCounts: Record<StatusTabKey, number | undefined> = {
    all:
      summary === undefined
        ? undefined
        : (summary.success ?? 0) +
        (summary.processing ?? 0) +
        (summary.failed ?? 0) +
        (summary.refunded ?? 0),
    success: summary?.success,
    processing: summary?.processing,
    failed: summary?.failed,
    refunded: summary?.refunded,
  };

  const columns: ColumnDef<PaymentRow>[] = [
    {
      id: "order",
      header: () => <span className={tableHeader}>Order</span>,
      cell: ({ row }) => (
        <div className="min-w-0 py-1">
          <p className="truncate font-medium text-foreground">
            {row.original.merchantOrderId ?? row.original.id.slice(0, 8)}
          </p>
          <p className="mt-0.5 truncate text-xs text-muted-foreground">
            Booking {row.original.bookingId?.slice(0, 8) ?? "—"}
          </p>
        </div>
      ),
    },
    {
      id: "amount",
      header: () => <span className={tableHeader}>Amount</span>,
      cell: ({ row }) => (
        <span className="font-mono text-sm font-semibold tabular-nums text-foreground">
          {formatAmount(row.original.amount, row.original.currency)}
        </span>
      ),
    },
    {
      id: "method",
      header: () => <span className={tableHeader}>Method</span>,
      cell: ({ row }) => (
        <Badge variant="light" radius="sm">
          {METHOD_OPTIONS.find((m) => m.value === row.original.method)?.label ??
            row.original.method}
        </Badge>
      ),
    },
    {
      id: "status",
      header: () => <span className={tableHeader}>Status</span>,
      cell: ({ row }) => (
        <Badge
          color={STATUS_COLORS[row.original.status] ?? "gray"}
          variant="light"
          radius="sm"
          tt="capitalize"
        >
          {row.original.status.replace(/-/g, " ")}
        </Badge>
      ),
    },
    {
      id: "date",
      header: () => <span className={tableHeader}>Date</span>,
      cell: ({ row }) => (
        <span className="text-sm text-muted-foreground">
          {formatDate(row.original.paidAt ?? row.original.createdAt)}
        </span>
      ),
    },
  ];

  return (
    <PageContainer>
      <PageHeader
        title="Payments"
        subtitle="View and reconcile booking payment transactions."
      />

      <KpiStrip
        loading={summaryLoading}
        items={[
          {
            label: "Total collected",
            value: `ETB ${Number(summary?.paidAmount ?? 0).toLocaleString()}`,
            icon: CircleDollarSign,
            color: "edr-green",
          },
          {
            label: "Successful",
            value: summary?.success ?? 0,
            icon: CheckCircle2,
            color: "edr-green",
          },
          {
            label: "Processing",
            value: summary?.processing ?? 0,
            icon: Loader2,
            color: "yellow",
          },
          {
            label: "Failed",
            value: summary?.failed ?? 0,
            icon: XCircle,
            color: "red",
          },
          {
            label: "Refunded",
            value: summary?.refunded ?? 0,
            icon: RotateCcw,
            color: "indigo",
          },
        ]}
      />

      <Tabs
        value={statusTab}
        onChange={(value) => {
          setStatusTab((value as StatusTabKey) ?? "all");
          setPagination({ pageIndex: 0, pageSize: pagination.pageSize });
        }}
        variant="pills"
        color="edr-green"
        keepMounted={false}
      >
        <Tabs.List>
          {STATUS_TABS.map((t) => {
            const isActive = statusTab === t.key;
            const count = tabCounts[t.key];
            const Icon = t.icon;
            return (
              <Tabs.Tab
                key={t.key}
                value={t.key}
                leftSection={<Icon size={17} strokeWidth={1.85} />}
                rightSection={
                  count !== undefined ? (
                    <MantineBadge
                      size="sm"
                      radius="sm"
                      variant={isActive ? "white" : "light"}
                      color={isActive ? "edr-green" : "gray"}
                    >
                      {count}
                    </MantineBadge>
                  ) : undefined
                }
              >
                {t.label}
              </Tabs.Tab>
            );
          })}
        </Tabs.List>
      </Tabs>

      <Card p={0}>
        <Stack gap={0}>
          <Box px="md" pt="md" pb="sm" w="100%">
            <Group justify="space-between" gap="md" wrap="wrap">
              <TextInput
                placeholder="Search order, booking, or transaction…"
                leftSection={<Search size={18} />}
                value={query}
                onChange={(e) => {
                  setQuery(e.target.value);
                  setPagination({
                    pageIndex: 0,
                    pageSize: pagination.pageSize,
                  });
                }}
                rightSection={
                  query && (
                    <ActionIcon
                      size="sm"
                      color="gray"
                      radius="md"
                      variant="transparent"
                      onClick={() => setQuery("")}
                    >
                      <X size={16} />
                    </ActionIcon>
                  )
                }
                style={{ flex: 1, minWidth: "200px" }}
              />
              <Select
                placeholder="All methods"
                clearable
                data={METHOD_OPTIONS}
                value={method}
                onChange={(value) => {
                  setMethod(value);
                  setPagination({
                    pageIndex: 0,
                    pageSize: pagination.pageSize,
                  });
                }}
                style={{ minWidth: 180 }}
              />
              <Text size="sm" c="dimmed">
                {total} record{total !== 1 ? "s" : ""}
              </Text>
            </Group>
          </Box>

          <Box style={{ overflowX: "auto" }} w="100%">
            <DataTable
              columns={columns}
              data={rows}
              status={isLoading ? "loading" : isError ? "error" : "success"}
              pagination={{
                pageIndex: pagination.pageIndex,
                pageSize: pagination.pageSize,
                pageCount,
                totalCount: total,
              }}
              tableOptions={{
                state: { pagination },
                onPaginationChange: setPagination,
                manualPagination: true,
                pageCount,
              }}
              containerClassName="border-0 shadow-none bg-transparent"
              footer={DataTableFooter}
            />
          </Box>
        </Stack>
      </Card>
    </PageContainer>
  );
}
