import type { Metadata } from "next";
import Link from "next/link";
import { CancelTaskStatus, OrderStatus, Prisma, RefillStatus } from "@prisma/client";
import { ListOrdered, Plus, SearchX } from "lucide-react";
import { Button } from "@/components/ui/button";
import { EmptyState } from "@/components/shared/empty-state";
import { PageHeader } from "@/components/shared/page-header";
import { OrdersSearch } from "@/components/panel/orders/orders-search";
import { OrdersTable } from "@/components/panel/orders/orders-table";
import { PaginationBar } from "@/components/panel/orders/pagination-bar";
import { TabLinks, type TabItem } from "@/components/panel/orders/tab-links";
import { TableCard } from "@/components/panel/orders/table-card";
import { readPage, readParam } from "@/components/panel/orders/query";
import type { OrderRow } from "@/components/panel/orders/types";
import { db } from "@/lib/db";
import { requireUser } from "@/lib/guards";
import { canRequestCancel, canRequestRefill } from "@/lib/orders";
import { iso, money } from "@/lib/serialize";
import { ordersTexts } from "@/lib/i18n/orders";

export const dynamic = "force-dynamic";

export const metadata: Metadata = { title: "Orders" };

const PATHNAME = "/orders";
const PER_PAGE = 20;

/** Cancel is only offered for these statuses (SPEC), on top of lib/orders guards. */
const CANCELABLE: OrderStatus[] = [
  OrderStatus.AWAITING,
  OrderStatus.PENDING,
  OrderStatus.IN_PROGRESS,
  OrderStatus.PROCESSING,
];

const OPEN_REFILLS: RefillStatus[] = [RefillStatus.PENDING, RefillStatus.IN_PROGRESS];
const OPEN_CANCELS: CancelTaskStatus[] = [CancelTaskStatus.PENDING, CancelTaskStatus.AWAITING];

type StatusTab = { value: string; label: string; statuses: OrderStatus[] | null };

// AWAITING orders (queued for dispatch) are shown to the customer as Pending.
const STATUS_TABS: StatusTab[] = [
  { value: "", label: ordersTexts.tabAll, statuses: null },
  {
    value: "pending",
    label: ordersTexts.tabPending,
    statuses: [OrderStatus.AWAITING, OrderStatus.PENDING],
  },
  { value: "in-progress", label: ordersTexts.tabInProgress, statuses: [OrderStatus.IN_PROGRESS] },
  { value: "processing", label: ordersTexts.tabProcessing, statuses: [OrderStatus.PROCESSING] },
  { value: "completed", label: ordersTexts.tabCompleted, statuses: [OrderStatus.COMPLETED] },
  { value: "partial", label: ordersTexts.tabPartial, statuses: [OrderStatus.PARTIAL] },
  { value: "canceled", label: ordersTexts.tabCanceled, statuses: [OrderStatus.CANCELED] },
];

export default async function OrdersPage(props: {
  searchParams: Promise<Record<string, string | string[] | undefined>>;
}) {
  const searchParams = await props.searchParams;
  const user = await requireUser();

  const statusParam = readParam(searchParams.status).toLowerCase();
  const activeTab = STATUS_TABS.find((t) => t.value === statusParam) ?? STATUS_TABS[0];
  const q = readParam(searchParams.q);
  const requestedPage = readPage(searchParams.page);

  const params = { status: activeTab.value || undefined, q: q || undefined };

  const searchFilter: Prisma.OrderWhereInput = {};
  if (q) {
    const asId = Math.trunc(Number(q));
    const or: Prisma.OrderWhereInput[] = [{ link: { contains: q, mode: "insensitive" } }];
    if (Number.isInteger(asId) && asId > 0) or.push({ id: asId });
    searchFilter.OR = or;
  }

  const baseWhere: Prisma.OrderWhereInput = { userId: user.id, ...searchFilter };
  const where: Prisma.OrderWhereInput = activeTab.statuses
    ? { ...baseWhere, status: { in: activeTab.statuses } }
    : baseWhere;

  const [total, grouped] = await Promise.all([
    db.order.count({ where }),
    db.order.groupBy({ by: ["status"], where: baseWhere, _count: { _all: true } }),
  ]);

  const countByStatus = new Map<string, number>(
    grouped.map((g) => [g.status as string, g._count._all]),
  );
  const totalAll = grouped.reduce((sum, g) => sum + g._count._all, 0);

  const pages = Math.max(1, Math.ceil(total / PER_PAGE));
  const page = Math.min(requestedPage, pages);

  const orders = await db.order.findMany({
    where,
    orderBy: { id: "desc" },
    skip: (page - 1) * PER_PAGE,
    take: PER_PAGE,
    select: {
      id: true,
      createdAt: true,
      updatedAt: true,
      link: true,
      charge: true,
      startCount: true,
      quantity: true,
      remains: true,
      status: true,
      serviceId: true,
      service: {
        select: {
          id: true,
          name: true,
          refillEnabled: true,
          refillDays: true,
          cancelEnabled: true,
        },
      },
      refills: { where: { status: { in: OPEN_REFILLS } }, select: { id: true }, take: 1 },
      cancelTasks: { where: { status: { in: OPEN_CANCELS } }, select: { id: true }, take: 1 },
    },
  });

  const now = new Date();
  const rows: OrderRow[] = orders.map((order) => {
    const refillPending = order.refills.length > 0;
    const cancelPending = order.cancelTasks.length > 0;
    return {
      id: order.id,
      createdAt: iso(order.createdAt),
      charge: money(order.charge),
      link: order.link,
      startCount: order.startCount ?? null,
      quantity: order.quantity,
      remains: order.remains,
      status: order.status,
      serviceId: order.service?.id ?? order.serviceId,
      serviceName: order.service?.name ?? `Service ${order.serviceId}`,
      canRefill: canRequestRefill(order, order.service, refillPending, now),
      canCancel:
        CANCELABLE.includes(order.status) &&
        canRequestCancel(order, order.service, cancelPending),
      refillPending,
      cancelPending,
    };
  });

  const tabs: TabItem[] = STATUS_TABS.map((tab) => ({
    value: tab.value,
    label: tab.label,
    count: tab.statuses
      ? tab.statuses.reduce((sum, s) => sum + (countByStatus.get(s) ?? 0), 0)
      : totalAll,
  }));

  const filtered = Boolean(q) || Boolean(activeTab.statuses);

  return (
    <div className="space-y-6">
      <PageHeader
        title={ordersTexts.ordersTitle}
        description={ordersTexts.ordersSubtitle}
        icon={ListOrdered}
        actions={
          <Button asChild size="sm" className="gap-1.5 rounded-lg">
            <Link href="/">
              <Plus className="size-4" />
              {ordersTexts.ordersEmptyCta}
            </Link>
          </Button>
        }
      />

      <TableCard
        toolbar={
          <>
            <TabLinks
              pathname={PATHNAME}
              params={params}
              active={activeTab.value}
              tabs={tabs}
              className="lg:flex-1"
            />
            <OrdersSearch pathname={PATHNAME} params={params} />
          </>
        }
        footer={
          rows.length ? (
            <PaginationBar
              pathname={PATHNAME}
              params={params}
              page={page}
              perPage={PER_PAGE}
              total={total}
            />
          ) : null
        }
      >
        {rows.length ? (
          <OrdersTable rows={rows} />
        ) : (
          <EmptyState
            className="m-4 border-0"
            icon={filtered ? SearchX : ListOrdered}
            title={
              filtered ? ordersTexts.ordersEmptyFilteredTitle : ordersTexts.ordersEmptyTitle
            }
            hint={filtered ? ordersTexts.ordersEmptyFilteredHint : ordersTexts.ordersEmptyHint}
            action={
              filtered ? (
                <Button asChild variant="outline" size="sm" className="rounded-lg">
                  <Link href={PATHNAME}>
                    {q ? ordersTexts.clearSearch : ordersTexts.showAllOrders}
                  </Link>
                </Button>
              ) : (
                <Button asChild size="sm" className="gap-1.5 rounded-lg">
                  <Link href="/">
                    <Plus className="size-4" />
                    {ordersTexts.ordersEmptyCta}
                  </Link>
                </Button>
              )
            }
          />
        )}
      </TableCard>
    </div>
  );
}
