"use client";

import { useState } from "react";
import Link from "next/link";
import { useQuery } from "@tanstack/react-query";
import { ChevronRight, Package, RefreshCw } from "lucide-react";
import { PageHeader } from "@/components/shared/page-header";
import { DebouncedSearch } from "@/components/shared/debounced-search";
import { Pagination } from "@/components/shared/pagination";
import { EmptyState, ErrorState, TableSkeleton } from "@/components/shared/states";
import { OrderStatusBadge } from "@/components/shared/status-badges";
import { Button } from "@/components/ui/button";
import { Card } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import { PortalPaymentBadge } from "@/features/portal/orders/payment-badge";
import { useI18n, useT } from "@/i18n";
import { cn } from "@/lib/cn";
import { friendlyErrorMessage } from "@/lib/errors";
import { formatCurrency, formatDateTime } from "@/lib/format";
import { queryKeys } from "@/lib/query-keys";
import { ORDER_STATUSES } from "@/services/orders";
import { getPortalOrders, type PortalOrderFilters } from "@/services/portal";
import type { OrderStatus } from "@/types/order";
import type { PortalOrder, PortalPaymentStatus } from "@/types/portal";

const PAYMENT_STATUSES: PortalPaymentStatus[] = ["paid", "unpaid", "refunded"];
const PAGE_SIZE = 15;

/** How often the list asks again, so a store watching it sees an order move without reloading. */
const REFRESH_MS = 30_000;

/**
 * Every order this store has sent us, newest first, and where each one is now.
 *
 * A store opens this to answer two questions: "did you get my order?" and "where is it?". So the
 * list is searchable by both numbers (ours and its own reference), filterable by status, and it
 * refreshes itself - an order that was "pending" a minute ago is on the road now. The customer's
 * details are deliberately not here: the store already holds them.
 */
export default function PortalOrdersPage() {
  const t = useT();
  const { locale } = useI18n();

  const [page, setPage] = useState(1);
  const [search, setSearch] = useState("");
  const [status, setStatus] = useState<OrderStatus | "">("");
  const [payment, setPayment] = useState<PortalPaymentStatus | "">("");
  const [from, setFrom] = useState("");
  const [to, setTo] = useState("");

  const filters: PortalOrderFilters = {
    page,
    rows: PAGE_SIZE,
    search: search || undefined,
    status: status || undefined,
    payment_status: payment || undefined,
    from: from || undefined,
    to: to || undefined,
  };
  const filtered = Boolean(search || status || payment || from || to);

  const { data, isLoading, isError, error, refetch, isFetching, dataUpdatedAt } = useQuery({
    queryKey: queryKeys.portal.orders(filters),
    queryFn: () => getPortalOrders(filters),
    refetchInterval: REFRESH_MS,
    // Said rather than left to the library's default: a store user's hidden tab must not keep asking the server every 30 seconds all day.
    refetchIntervalInBackground: false,
    // Page 2 -> 3 keeps page 2 on screen until 3 arrives, instead of flashing a skeleton.
    placeholderData: (previous) => previous,
  });

  const orders = data?.Model ?? [];

  const reset = () => {
    setPage(1);
    setSearch("");
    setStatus("");
    setPayment("");
    setFrom("");
    setTo("");
  };

  return (
    <div>
      <PageHeader
        title={t("portal.orders.title")}
        subtitle={t("portal.orders.subtitle")}
        actions={
          <div className="flex items-center gap-3">
            {dataUpdatedAt ? (
              <span className="numeric hidden text-xs text-muted-foreground sm:inline">
                {t("portal.orders.updatedAt", { time: formatDateTime(new Date(dataUpdatedAt).toISOString(), locale) })}
              </span>
            ) : null}
            <Button variant="outline" size="sm" onClick={() => void refetch()} disabled={isFetching}>
              <RefreshCw className={cn(isFetching && "animate-spin")} aria-hidden />
              {t("portal.orders.refresh")}
            </Button>
          </div>
        }
      />

      <Card>
        <div className="flex flex-col gap-3 kap-toolbar lg:flex-row lg:flex-wrap lg:items-center">
          <DebouncedSearch
            value={search}
            onChange={(value) => {
              setPage(1);
              setSearch(value);
            }}
            placeholder={t("portal.orders.searchPlaceholder")}
            ariaLabel={t("common.search")}
            className="w-full lg:w-80"
          />

          <FilterField label={t("common.status")}>
            <Select
              value={status || "all"}
              onValueChange={(value) => {
                setPage(1);
                setStatus(value === "all" ? "" : (value as OrderStatus));
              }}
            >
              <SelectTrigger className="w-[10.5rem]">
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="all">{t("common.all")}</SelectItem>
                {ORDER_STATUSES.map((option) => (
                  <SelectItem key={option} value={option}>
                    {t(`orders.status.${option}`)}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </FilterField>

          <FilterField label={t("portal.orders.filterPayment")}>
            <Select
              value={payment || "all"}
              onValueChange={(value) => {
                setPage(1);
                setPayment(value === "all" ? "" : (value as PortalPaymentStatus));
              }}
            >
              <SelectTrigger className="w-[9.5rem]">
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="all">{t("common.all")}</SelectItem>
                {PAYMENT_STATUSES.map((option) => (
                  <SelectItem key={option} value={option}>
                    {t(`portal.orders.payment.${option}`)}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </FilterField>

          <div className="flex flex-wrap items-center gap-x-4 gap-y-2">
            <FilterField label={t("portal.orders.from")}>
              <Input
                type="date"
                value={from}
                max={to || undefined}
                onChange={(event) => {
                  setPage(1);
                  setFrom(event.target.value);
                }}
                className="w-[9.75rem]"
                dir="ltr"
              />
            </FilterField>

            <FilterField label={t("portal.orders.to")}>
              <Input
                type="date"
                value={to}
                min={from || undefined}
                onChange={(event) => {
                  setPage(1);
                  setTo(event.target.value);
                }}
                className="w-[9.75rem]"
                dir="ltr"
              />
            </FilterField>
          </div>

          {filtered ? (
            <Button variant="ghost" size="sm" onClick={reset}>
              {t("common.clearFilters")}
            </Button>
          ) : null}
        </div>

        {isLoading ? (
          <TableSkeleton rows={8} cols={7} />
        ) : isError ? (
          <ErrorState message={friendlyErrorMessage(error, t)} onRetry={() => void refetch()} />
        ) : orders.length === 0 ? (
          filtered ? (
            <EmptyState
              title={t("common.noResults")}
              action={
                <Button variant="outline" size="sm" onClick={reset}>
                  {t("common.clearFilters")}
                </Button>
              }
            />
          ) : (
            <EmptyState title={t("portal.orders.empty")} description={t("portal.orders.emptyHint")} icon={Package} />
          )
        ) : (
          <>
            <div className="overflow-x-auto">
              <Table>
                <TableHeader>
                  <TableRow>
                    <TableHead>{t("portal.orders.col.order")}</TableHead>
                    <TableHead>{t("portal.orders.col.reference")}</TableHead>
                    <TableHead>{t("common.status")}</TableHead>
                    <TableHead>{t("portal.orders.col.captain")}</TableHead>
                    <TableHead>{t("portal.orders.col.cash")}</TableHead>
                    <TableHead>{t("portal.orders.col.eta")}</TableHead>
                    <TableHead>{t("portal.orders.col.received")}</TableHead>
                    <TableHead aria-label={t("common.actions")} />
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {orders.map((order) => (
                    <OrderRow key={order.uuid} order={order} />
                  ))}
                </TableBody>
              </Table>
            </div>
            <Pagination
              perPage={PAGE_SIZE}
              page={data?.Page ?? 1}
              totalPages={data?.Total ?? 1}
              records={data?.Records ?? 0}
              onPageChange={setPage}
            />
            <p className="border-t px-4 py-2 text-[0.7rem] text-muted-foreground">{t("portal.orders.autoRefresh")}</p>
          </>
        )}
      </Card>
    </div>
  );
}

function FilterField({ label, children }: { label: string; children: React.ReactNode }) {
  return (
    <div className="flex items-center gap-2">
      <span className="text-xs text-muted-foreground">{label}</span>
      {children}
    </div>
  );
}

function OrderRow({ order }: { order: PortalOrder }) {
  const t = useT();
  const { locale, dir } = useI18n();
  const href = `/portal/orders/${order.uuid}`;
  const prepaid = order.cash.method === "prepaid";

  return (
    <TableRow>
      <TableCell>
        <Link
          href={href}
          aria-label={t("portal.orders.open", { number: order.order_number })}
          className="whitespace-nowrap text-sm font-semibold text-primary hover:underline"
          dir="ltr"
        >
          {order.order_number}
        </Link>
      </TableCell>
      <TableCell className="numeric text-sm" dir="ltr">
        {order.external_order_id ?? "—"}
      </TableCell>
      <TableCell>
        <OrderStatusBadge status={order.status} label={order.status_label} />
      </TableCell>
      <TableCell className="text-sm">
        {order.captain?.name ? (
          order.captain.name
        ) : (
          <span className="text-muted-foreground">{t("portal.orders.noCaptain")}</span>
        )}
      </TableCell>
      <TableCell>
        <div className="flex flex-col items-start gap-1">
          <span className="numeric text-sm font-medium">
            {prepaid
              ? t("portal.orders.nothingToCollect")
              : formatCurrency(order.cash.amount_to_collect, order.cash.currency, locale)}
          </span>
          <PortalPaymentBadge
            status={order.cash.status}
            label={order.cash.status ? t(`portal.orders.payment.${order.cash.status}`) : ""}
          />
        </div>
      </TableCell>
      <TableCell className="numeric text-xs text-muted-foreground">{formatDateTime(order.eta_at, locale)}</TableCell>
      <TableCell className="numeric text-xs text-muted-foreground">
        {formatDateTime(order.timestamps.received_at, locale)}
      </TableCell>
      <TableCell>
        <Link href={href} aria-hidden tabIndex={-1} className="text-muted-foreground hover:text-primary">
          <ChevronRight className={cn("h-4 w-4", dir === "rtl" && "rotate-180")} />
        </Link>
      </TableCell>
    </TableRow>
  );
}
