import type { Metadata } from "next";
import Link from "next/link";
import { OrderStatus, Prisma, TransactionType } from "@prisma/client";
import { CalendarRange, Receipt, Undo2 } from "lucide-react";
import { Button } from "@/components/ui/button";
import { EmptyState } from "@/components/shared/empty-state";
import { PageHeader } from "@/components/shared/page-header";
import { PaginationBar } from "@/components/panel/orders/pagination-bar";
import { RefundsTable } from "@/components/panel/orders/refunds-table";
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 { RefundRow } from "@/components/panel/orders/types";
import { db } from "@/lib/db";
import { requireUser } from "@/lib/guards";
import { formatNumber } from "@/lib/format";
import { iso, money } from "@/lib/serialize";
import { ordersTexts } from "@/lib/i18n/orders";

export const dynamic = "force-dynamic";

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

const PATHNAME = "/orders/refunds";
const PER_PAGE = 20;
const WINDOW_DAYS = 90;

const REFUNDABLE: OrderStatus[] = [OrderStatus.CANCELED, OrderStatus.PARTIAL];

type RefundTab = { value: string; label: string; statuses: OrderStatus[] };

const REFUND_TABS: RefundTab[] = [
  { value: "", label: ordersTexts.tabAll, statuses: REFUNDABLE },
  { value: "canceled", label: ordersTexts.tabCanceled, statuses: [OrderStatus.CANCELED] },
  { value: "partial", label: ordersTexts.tabPartial, statuses: [OrderStatus.PARTIAL] },
];

function StatChip({
  icon: Icon,
  label,
  value,
}: {
  icon: typeof Receipt;
  label: string;
  value: string;
}) {
  return (
    <div className="flex items-center gap-3 rounded-2xl border bg-card px-4 py-3 shadow-sm">
      <div className="flex size-9 shrink-0 items-center justify-center rounded-xl bg-primary/10 text-primary">
        <Icon className="size-[18px]" />
      </div>
      <div>
        <p className="text-xs text-muted-foreground">{label}</p>
        <p className="font-mono text-base font-semibold tabular-nums">{value}</p>
      </div>
    </div>
  );
}

export default async function RefundsPage(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 = REFUND_TABS.find((t) => t.value === statusParam) ?? REFUND_TABS[0];
  const requestedPage = readPage(searchParams.page);
  const params = { status: activeTab.value || undefined };

  const since = new Date(Date.now() - WINDOW_DAYS * 24 * 60 * 60 * 1000);
  const windowWhere: Prisma.OrderWhereInput = {
    userId: user.id,
    createdAt: { gte: since },
    status: { in: REFUNDABLE },
  };
  const where: Prisma.OrderWhereInput = { ...windowWhere, status: { in: activeTab.statuses } };

  const [total, grouped, refundedTotal] = await Promise.all([
    db.order.count({ where }),
    db.order.groupBy({ by: ["status"], where: windowWhere, _count: { _all: true } }),
    db.transaction.aggregate({
      where: { type: TransactionType.REFUND, order: { is: windowWhere } },
      _sum: { amount: 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,
      charge: true,
      status: true,
      serviceId: true,
      service: { select: { id: true, name: true } },
    },
  });

  const ids = orders.map((o) => o.id);
  const refundSums = ids.length
    ? await db.transaction.groupBy({
        by: ["orderId"],
        where: { type: TransactionType.REFUND, orderId: { in: ids } },
        _sum: { amount: true },
      })
    : [];

  const refundedByOrder = new Map<number, Prisma.Decimal>();
  for (const row of refundSums) {
    if (row.orderId !== null && row._sum.amount) {
      refundedByOrder.set(row.orderId, row._sum.amount);
    }
  }

  const rows: RefundRow[] = orders.map((order) => {
    const refunded = refundedByOrder.get(order.id) ?? null;
    return {
      id: order.id,
      createdAt: iso(order.createdAt),
      serviceId: order.service?.id ?? order.serviceId,
      serviceName: order.service?.name ?? `Service ${order.serviceId}`,
      charge: money(order.charge),
      refunded: refunded && !refunded.equals(0) ? money(refunded) : null,
      status: order.status,
    };
  });

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

  return (
    <div className="space-y-6">
      <PageHeader
        title={ordersTexts.refundsTitle}
        description={ordersTexts.refundsSubtitle}
        icon={Undo2}
        actions={
          <span className="inline-flex items-center gap-1.5 rounded-lg border px-2.5 py-1 text-xs text-muted-foreground">
            <CalendarRange className="size-3.5" />
            {ordersTexts.refundsWindowNote}
          </span>
        }
      />

      <div className="grid gap-3 sm:grid-cols-2 lg:max-w-xl">
        <StatChip
          icon={Undo2}
          label={ordersTexts.refundsTotalRefunded}
          value={money(refundedTotal._sum.amount ?? 0)}
        />
        <StatChip
          icon={Receipt}
          label={ordersTexts.refundsOrdersCount}
          value={formatNumber(totalAll, 0)}
        />
      </div>

      <TableCard
        toolbar={
          <TabLinks
            pathname={PATHNAME}
            params={params}
            active={activeTab.value}
            tabs={tabs}
          />
        }
        footer={
          rows.length ? (
            <PaginationBar
              pathname={PATHNAME}
              params={params}
              page={page}
              perPage={PER_PAGE}
              total={total}
            />
          ) : null
        }
      >
        {rows.length ? (
          <RefundsTable rows={rows} />
        ) : (
          <EmptyState
            className="m-4 border-0"
            icon={Undo2}
            title={ordersTexts.refundsEmptyTitle}
            hint={ordersTexts.refundsEmptyHint}
            action={
              <Button asChild variant="outline" size="sm" className="rounded-lg">
                <Link href="/orders">{ordersTexts.ordersTitle}</Link>
              </Button>
            }
          />
        )}
      </TableCard>
    </div>
  );
}
