import {
  ActionIcon,
  Badge,
  Box,
  Card,
  Group,
  SegmentedControl,
  Stack,
  Text,
  TextInput,
  Tooltip,
} from "@mantine/core";
import { useDebouncedValue } from "@mantine/hooks";
import { useQuery } from "@tanstack/react-query";
import {
  Building2,
  CheckCircle2,
  Clock,
  Hourglass,
  Mail,
  Phone,
  RefreshCw,
  Search,
  ShieldOff,
  Users,
  X,
} from "lucide-react";
import { useMemo, useState } from "react";
import { useNavigate } from "react-router-dom";

import {
  CompanyStatusBadge,
  CompanyTypeBadge,
  ProfileChips,
  formatDate,
} from "@/components/customers";
import { KpiStrip, PageContainer, PageHeader } from "@/components/page";
import { api } from "@/services/api";
import type { Company, CompanyStatus } from "@/types/customer";
import { isOnboardingDraft } from "@/types/customer";
import {
  DataTable,
  DataTableFooter,
  usePagination,
  type ColumnDef,
} from "@edr/ui-common";

/**
 * The list's segmented views. "Pending approval" means submitted-and-awaiting-
 * review, so it excludes drafts — a company row exists from the onboarding
 * wizard's first click and would otherwise pad the review queue. Those drafts
 * get their own view instead of disappearing, so staff can still chase them.
 */
type CustomerView = "all" | "pending" | "onboarding" | "active";

const VIEW_FILTERS: Record<
  CustomerView,
  { status?: CompanyStatus; onboardingCompleted?: boolean }
> = {
  all: {},
  pending: { status: "pending", onboardingCompleted: true },
  onboarding: { onboardingCompleted: false },
  active: { status: "active" },
};

export default function CustomersPage() {
  const navigate = useNavigate();
  const { pagination, setPagination } = usePagination({ pageSize: 10 });
  const [query, setQuery] = useState("");
  const [debouncedQuery] = useDebouncedValue(query, 300);
  const [view, setView] = useState<CustomerView>("all");

  const filter = useMemo(
    () => ({
      page: pagination.pageIndex + 1,
      pageSize: pagination.pageSize,
      search: debouncedQuery,
      ...VIEW_FILTERS[view],
    }),
    [pagination.pageIndex, pagination.pageSize, debouncedQuery, view],
  );

  const { data: stats } = useQuery(api.customers.stats.queryOptions({ input: {} }));

  const { data, isLoading, isError, refetch, isFetching } = useQuery(
    api.customers.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<Company>[] = useMemo(
    () => [
      {
        id: "company",
        header: "Company",
        cell: ({ row }) => {
          const c = row.original;
          return (
            <Group gap="sm" wrap="nowrap">
              <Box
                className="flex size-9 shrink-0 items-center justify-center rounded-lg"
                style={{
                  background: "var(--mantine-color-edr-green-1)",
                  color: "var(--mantine-color-edr-green-7)",
                }}
              >
                <Building2 size={18} strokeWidth={1.9} />
              </Box>
              <div style={{ minWidth: 0 }}>
                <Group gap={8} wrap="nowrap">
                  <Text fw={600} c="edr-text" truncate>
                    {c.name}
                  </Text>
                  <CompanyTypeBadge type={c.type} />
                </Group>
                <Text size="xs" c="dimmed">
                  TIN {c.tin}
                  {c.country ? ` · ${c.country}` : ""}
                </Text>
              </div>
            </Group>
          );
        },
      },
      {
        id: "profiles",
        header: "Profiles",
        cell: ({ row }) => <ProfileChips profiles={row.original.companyProfiles} />,
      },
      {
        id: "status",
        header: "Status",
        cell: ({ row }) => {
          // A draft's profiles are all `pending` by construction, so the
          // "N pending" review hint would be a lie until they submit.
          if (isOnboardingDraft(row.original)) {
            return (
              <Tooltip label="Customer is still filling in the onboarding wizard">
                <Badge color="gray" variant="light" size="sm" radius="sm">
                  Onboarding
                </Badge>
              </Tooltip>
            );
          }
          const pending = (row.original.companyProfiles ?? []).filter(
            (p) => p.status === "pending",
          ).length;
          return (
            <Group gap={6} wrap="nowrap">
              <CompanyStatusBadge status={row.original.status} />
              {pending > 0 ? (
                <Tooltip
                  label={`${pending} profile${pending > 1 ? "s" : ""} awaiting approval`}
                >
                  <Badge color="yellow" variant="light" size="sm" radius="sm">
                    {pending} pending
                  </Badge>
                </Tooltip>
              ) : null}
            </Group>
          );
        },
      },
      {
        id: "contact",
        header: "Contact",
        cell: ({ row }) => {
          const c = row.original;
          return (
            <Stack gap={2}>
              {c.contactPersonName ? (
                <Text size="sm" c="edr-text">
                  {c.contactPersonName}
                </Text>
              ) : null}
              {c.phone ? (
                <Text
                  size="xs"
                  c="dimmed"
                  className="inline-flex items-center gap-1"
                >
                  <Phone size={12} /> {c.phone}
                </Text>
              ) : null}
              {c.email ? (
                <Text
                  size="xs"
                  c="dimmed"
                  className="inline-flex items-center gap-1"
                  truncate
                >
                  <Mail size={12} /> {c.email}
                </Text>
              ) : null}
            </Stack>
          );
        },
      },
      {
        id: "created",
        header: "Registered",
        meta: { headerClassName: "text-right", cellClassName: "text-right" },
        cell: ({ row }) => (
          <Text size="sm" c="dimmed">
            {formatDate(row.original.createdAt)}
          </Text>
        ),
      },
    ],
    [],
  );

  return (
    <PageContainer>
      <PageHeader
        title="Customers"
        subtitle="Companies registered for freight services, with their role profiles."
        action={
          <ActionIcon
            variant="default"
            size="lg"
            radius="md"
            aria-label="Refresh"
            loading={isFetching}
            onClick={() => void refetch()}
          >
            <RefreshCw size={16} />
          </ActionIcon>
        }
      />

      <KpiStrip
        items={[
          { label: "Companies", value: stats?.total ?? "—", icon: Users, color: "edr-green" },
          { label: "Active", value: stats?.active ?? "—", icon: CheckCircle2, color: "edr-green" },
          { label: "Pending", value: stats?.pending ?? "—", icon: Clock, color: "yellow" },
          {
            label: "Onboarding",
            value: stats?.onboarding ?? "—",
            icon: Hourglass,
            color: "gray",
          },
          {
            label: "Blacklisted",
            value: stats?.blacklisted ?? "—",
            icon: ShieldOff,
            color: "red",
          },
        ]}
      />

      <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 company, TIN, email or profile reference…"
                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={view}
                onChange={(v) => {
                  setView(v as CustomerView);
                  setPagination((prev) => ({ ...prev, pageIndex: 0 }));
                }}
                data={[
                  { label: "All", value: "all" },
                  { label: "Pending approval", value: "pending" },
                  { label: "Onboarding", value: "onboarding" },
                  { label: "Active", value: "active" },
                ]}
              />
              <Text size="sm" c="dimmed">
                {total} record{total !== 1 ? "s" : ""}
              </Text>
            </Group>
          </Box>

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