import type { Freight } from "@edr/types";
import {
  ActionIcon,
  Box,
  Card,
  Group,
  SegmentedControl,
  Stack,
  Text,
  TextInput,
} from "@mantine/core";
import { useDebouncedValue } from "@mantine/hooks";
import { useQuery } from "@tanstack/react-query";
import { RefreshCw, Search, X } from "lucide-react";
import { useMemo, useState } from "react";
import { useNavigate } from "react-router-dom";

import {
  InvoiceStatusBadge,
  formatDate,
  formatMoney,
  humanize,
} from "@/components/customers";
import { PageContainer, PageHeader } from "@/components/page";
import { api } from "@/services/api";
import type { Invoice } from "@/types/invoice";
import {
  DataTable,
  DataTableFooter,
  usePagination,
  type ColumnDef,
} from "@edr/ui-common";

export default function InvoicesPage() {
  const navigate = useNavigate();
  const { pagination, setPagination } = usePagination({ pageSize: 10 });
  const [query, setQuery] = useState("");
  const [debouncedQuery] = useDebouncedValue(query, 300);
  const [statusFilter, setStatusFilter] = useState<"" | Freight.InvoiceStatus>(
    "",
  );

  const filter = useMemo(
    () => ({
      page: pagination.pageIndex + 1,
      pageSize: pagination.pageSize,
      search: debouncedQuery,
      status: statusFilter || undefined,
    }),
    [pagination.pageIndex, pagination.pageSize, debouncedQuery, statusFilter],
  );

  const { data, isLoading, isError, refetch, isFetching } = useQuery(
    api.invoices.list.queryOptions({ input: { filter } }),
  );

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

  const columns: ColumnDef<Invoice>[] = useMemo(
    () => [
      {
        id: "invoiceNumber",
        header: "Invoice",
        cell: ({ row }) => (
          <Text size="sm" fw={600} c="edr-text">
            {row.original.invoiceNumber}
          </Text>
        ),
      },
      {
        id: "billedTo",
        header: "Billed to",
        cell: ({ row }) => (
          <Text size="sm" c="edr-text">
            {row.original.company?.name ?? "—"}
          </Text>
        ),
      },
      {
        id: "source",
        header: "Source",
        cell: ({ row }) => (
          <Text size="sm" c="dimmed">
            {humanize(row.original.source)}
          </Text>
        ),
      },
      {
        id: "status",
        header: "Status",
        cell: ({ row }) => <InvoiceStatusBadge status={row.original.status} />,
      },
      {
        id: "amount",
        header: "Amount",
        meta: { headerClassName: "text-right", cellClassName: "text-right" },
        cell: ({ row }) => (
          <Text size="sm" fw={600} c="edr-text">
            {formatMoney(row.original.totalAmount, row.original.currency)}
          </Text>
        ),
      },
      {
        id: "balance",
        header: "Balance",
        meta: { headerClassName: "text-right", cellClassName: "text-right" },
        cell: ({ row }) => (
          <Text size="sm" c="dimmed">
            {formatMoney(row.original.balanceAmount, row.original.currency)}
          </Text>
        ),
      },
      {
        id: "dueAt",
        header: "Due",
        meta: { headerClassName: "text-right", cellClassName: "text-right" },
        cell: ({ row }) => (
          <Text size="sm" c="dimmed">
            {formatDate(row.original.dueAt)}
          </Text>
        ),
      },
    ],
    [],
  );

  return (
    <PageContainer>
      <PageHeader
        title="Invoices"
        subtitle="Every invoice issued across bookings, warehouse fees and clearance charges."
        action={
          <ActionIcon
            variant="default"
            size="lg"
            radius="md"
            aria-label="Refresh"
            loading={isFetching}
            onClick={() => void refetch()}
          >
            <RefreshCw size={16} />
          </ActionIcon>
        }
      />

      <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 by invoice number…"
                leftSection={<Search size={18} />}
                value={query}
                onChange={(e) => setQuery(e.target.value)}
                rightSection={
                  query ? (
                    <ActionIcon
                      size="sm"
                      color="gray"
                      radius="md"
                      variant="transparent"
                      onClick={() => setQuery("")}
                    >
                      <X size={16} />
                    </ActionIcon>
                  ) : null
                }
                style={{ flex: 1, minWidth: "240px" }}
                radius="lg"
              />
              <SegmentedControl
                size="sm"
                radius="md"
                value={statusFilter || "all"}
                onChange={(v) => {
                  setStatusFilter(
                    v === "all" ? "" : (v as Freight.InvoiceStatus),
                  );
                  setPagination((prev) => ({ ...prev, pageIndex: 0 }));
                }}
                data={[
                  { label: "All", value: "all" },
                  { label: "Pending", value: "PENDING" },
                  { label: "Paid", value: "PAID" },
                  { label: "Overdue", value: "OVERDUE" },
                ]}
              />
              <Text size="sm" c="dimmed">
                {total} record{total !== 1 ? "s" : ""}
              </Text>
            </Group>
          </Box>

          <Box style={{ overflowX: "auto" }} w="100%">
            <Box miw={920}>
              <DataTable
                columns={columns}
                data={rows}
                status={isLoading ? "loading" : isError ? "error" : "success"}
                onRowClick={(row) => navigate(`/dashboard/invoices/${row.id}`)}
                emptyMessage={
                  debouncedQuery
                    ? "No invoices match your search."
                    : "No invoices yet."
                }
                error={
                  isError
                    ? {
                        message: "Failed to load invoices.",
                        onRetry: () => void refetch(),
                      }
                    : undefined
                }
                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>
          </Box>
        </Stack>
      </Card>
    </PageContainer>
  );
}
