import type { Metadata } from "next";
import Link from "next/link";
import { DripFeedStatus, Prisma } from "@prisma/client";
import { Activity, Gauge, Repeat, Timer, Wallet } from "lucide-react";
import { Button } from "@/components/ui/button";
import { EmptyState } from "@/components/shared/empty-state";
import { PageHeader } from "@/components/shared/page-header";
import { FilterTabs } from "@/components/panel/bulk/filter-tabs";
import { Pager } from "@/components/panel/bulk/pager";
import { StatCard } from "@/components/panel/bulk/stat-card";
import {
  DripFeedTable,
  type DripFeedRowDTO,
} from "@/components/panel/bulk/drip-feed-table";
import { db } from "@/lib/db";
import { requireUser } from "@/lib/guards";
import { formatNumber } from "@/lib/format";
import { bulkTexts } from "@/lib/i18n/bulk";
import { partialRefundAmount } from "@/lib/pricing";
import { iso, money } from "@/lib/serialize";
import { dripUndeliveredQuantity } from "@/lib/validation/bulk";

export const metadata: Metadata = { title: "Drip-feed" };

const PER_PAGE = 20;

const STATUS_FILTERS: { value: string; label: string; status?: DripFeedStatus }[] = [
  { value: "all", label: bulkTexts.filterAll },
  { value: "active", label: bulkTexts.filterActive, status: DripFeedStatus.ACTIVE },
  { value: "paused", label: bulkTexts.filterPaused, status: DripFeedStatus.PAUSED },
  {
    value: "completed",
    label: bulkTexts.filterCompleted,
    status: DripFeedStatus.COMPLETED,
  },
  { value: "canceled", label: bulkTexts.filterCanceled, status: DripFeedStatus.CANCELED },
];

export default async function DripFeedPage(props: {
  searchParams: Promise<{ status?: string; page?: string }>;
}) {
  const user = await requireUser();
  const searchParams = await props.searchParams;

  const filterValue = (searchParams.status ?? "all").toLowerCase();
  const filter =
    STATUS_FILTERS.find((f) => f.value === filterValue) ?? STATUS_FILTERS[0];
  const page = Math.max(1, Math.trunc(Number(searchParams.page ?? 1)) || 1);

  const scope: Prisma.DripFeedWhereInput = { order: { userId: user.id } };
  const where: Prisma.DripFeedWhereInput = filter.status
    ? { ...scope, status: filter.status }
    : scope;

  const [all, counts, total, rows] = await Promise.all([
    db.dripFeed.findMany({
      where: scope,
      select: {
        runs: true,
        runsCompleted: true,
        quantityPerRun: true,
        totalQuantity: true,
        totalCharge: true,
        status: true,
      },
    }),
    db.dripFeed.groupBy({
      by: ["status"],
      where: scope,
      _count: { _all: true },
    }),
    db.dripFeed.count({ where }),
    db.dripFeed.findMany({
      where,
      orderBy: { createdAt: "desc" },
      skip: (page - 1) * PER_PAGE,
      take: PER_PAGE,
      include: {
        order: {
          select: {
            id: true,
            link: true,
            charge: true,
            status: true,
            createdAt: true,
            service: { select: { id: true, name: true } },
          },
        },
      },
    }),
  ]);

  const countByStatus = new Map(
    counts.map((c) => [c.status, c._count._all] as const),
  );
  const totalCount = all.length;

  let deliveredVolume = 0;
  let runsRemaining = 0;
  let charged = new Prisma.Decimal(0);
  for (const d of all) {
    const undelivered = dripUndeliveredQuantity(d);
    deliveredVolume += d.totalQuantity - undelivered;
    if (d.status === DripFeedStatus.ACTIVE || d.status === DripFeedStatus.PAUSED) {
      runsRemaining += Math.max(0, d.runs - d.runsCompleted);
    }
    charged = charged.plus(new Prisma.Decimal(d.totalCharge));
  }

  const dtos: DripFeedRowDTO[] = rows.map((row) => {
    const undelivered = dripUndeliveredQuantity(row);
    return {
      id: row.id,
      orderId: row.order.id,
      createdAt: iso(row.createdAt),
      link: row.order.link,
      totalCharge: money(row.order.charge),
      quantityPerRun: row.quantityPerRun,
      serviceId: row.order.service.id,
      serviceName: row.order.service.name,
      runs: row.runs,
      runsCompleted: row.runsCompleted,
      intervalMinutes: row.intervalMinutes,
      totalQuantity: row.totalQuantity,
      undeliveredQuantity: undelivered,
      status: row.status,
      orderStatus: row.order.status,
      nextRunAt: iso(row.nextRunAt),
      refundEstimate: money(
        partialRefundAmount(row.order.charge, row.totalQuantity, undelivered),
      ),
      canCancel: row.status === DripFeedStatus.ACTIVE,
    };
  });

  const tabs = STATUS_FILTERS.map((f) => ({
    value: f.value,
    label: f.label,
    count: f.status ? (countByStatus.get(f.status) ?? 0) : totalCount,
  }));

  return (
    <div className="mx-auto w-full max-w-screen-2xl p-4 sm:p-6">
      <PageHeader
        title={bulkTexts.dripTitle}
        description={bulkTexts.dripSubtitle}
        icon={Timer}
        actions={
          <Button asChild size="lg">
            <Link href="/">{bulkTexts.dripNewOrder}</Link>
          </Button>
        }
      />

      {totalCount > 0 ? (
        <div className="mb-6 grid gap-3 sm:grid-cols-2 xl:grid-cols-4">
          <StatCard
            label={bulkTexts.dripStatActive}
            value={formatNumber(countByStatus.get(DripFeedStatus.ACTIVE) ?? 0)}
            icon={Activity}
            tone="emerald"
          />
          <StatCard
            label={bulkTexts.dripStatRunsLeft}
            value={formatNumber(runsRemaining)}
            icon={Repeat}
            tone="blue"
          />
          <StatCard
            label={bulkTexts.dripStatDelivered}
            value={formatNumber(deliveredVolume)}
            icon={Gauge}
            tone="cyan"
          />
          <StatCard
            label={bulkTexts.dripStatSpent}
            value={money(charged)}
            icon={Wallet}
            tone="violet"
          />
        </div>
      ) : null}

      {totalCount === 0 ? (
        <EmptyState
          icon={Timer}
          title={bulkTexts.dripEmptyTitle}
          hint={bulkTexts.dripEmptyHint}
          action={
            <Button asChild>
              <Link href="/">{bulkTexts.dripNewOrder}</Link>
            </Button>
          }
        />
      ) : (
        <>
          <FilterTabs basePath="/drip-feed" current={filter.value} options={tabs} />
          <div className="overflow-hidden rounded-2xl border bg-card shadow-sm">
            {dtos.length === 0 ? (
              <p className="px-4 py-14 text-center text-sm text-muted-foreground">
                {bulkTexts.dripEmptyTitle}
              </p>
            ) : (
              <DripFeedTable rows={dtos} />
            )}
            <Pager
              basePath="/drip-feed"
              params={{ status: filter.value === "all" ? undefined : filter.value }}
              page={page}
              perPage={PER_PAGE}
              total={total}
            />
          </div>
        </>
      )}
    </div>
  );
}
