import type { Metadata } from "next";
import Link from "next/link";
import { LifeBuoy } from "lucide-react";
import { Button, buttonVariants } from "@/components/ui/button";
import { PageHeader } from "@/components/shared/page-header";
import { NewTicketCard } from "@/components/panel/tickets/new-ticket-card";
import { TicketList } from "@/components/panel/tickets/ticket-list";
import type {
  TicketListItemDTO,
  TicketStatusValue,
} from "@/components/panel/tickets/types";
import { db } from "@/lib/db";
import { formatDateTime, timeAgo } from "@/lib/format";
import { requireUser } from "@/lib/guards";
import { commonTexts } from "@/lib/i18n/common";
import { ticketsTexts as tx } from "@/lib/i18n/tickets";
import { cn } from "@/lib/utils";
import { ticketRef } from "@/lib/validation/tickets";

export const dynamic = "force-dynamic";

export const metadata: Metadata = {
  title: "Tickets",
};

const PER_PAGE = 15;

function fill(template: string, values: Record<string, string | number>): string {
  return template.replace(/\{(\w+)\}/g, (_m, key: string) => String(values[key] ?? ""));
}

type SearchParams = Record<string, string | string[] | undefined>;

export default async function TicketsPage(props: {
  searchParams: Promise<SearchParams>;
}) {
  const user = await requireUser();
  const searchParams = await props.searchParams;

  const rawPage = Array.isArray(searchParams.page)
    ? searchParams.page[0]
    : searchParams.page;
  const parsedPage = Number(rawPage ?? 1);
  const page =
    Number.isFinite(parsedPage) && parsedPage >= 1 ? Math.floor(parsedPage) : 1;

  const [total, rows, recentOrders] = await Promise.all([
    db.ticket.count({ where: { userId: user.id } }),
    db.ticket.findMany({
      where: { userId: user.id },
      orderBy: { updatedAt: "desc" },
      skip: (page - 1) * PER_PAGE,
      take: PER_PAGE,
      select: {
        id: true,
        subject: true,
        status: true,
        category: true,
        subcategory: true,
        orderId: true,
        createdAt: true,
        updatedAt: true,
        _count: { select: { messages: true } },
      },
    }),
    db.order.findMany({
      where: { userId: user.id },
      orderBy: { createdAt: "desc" },
      take: 30,
      select: { id: true },
    }),
  ]);

  const tickets: TicketListItemDTO[] = rows.map((row) => ({
    id: row.id,
    ref: ticketRef(row.id),
    subject: row.subject,
    status: row.status as TicketStatusValue,
    category: row.category,
    subcategory: row.subcategory,
    orderId: row.orderId,
    messageCount: row._count.messages,
    createdAtLabel: formatDateTime(row.createdAt),
    updatedAtLabel: formatDateTime(row.updatedAt),
    updatedAgo: timeAgo(row.updatedAt),
    hasNewReply: row.status === "ANSWERED",
  }));

  const pageCount = Math.max(1, Math.ceil(total / PER_PAGE));
  const from = total === 0 ? 0 : (page - 1) * PER_PAGE + 1;
  const to = Math.min(page * PER_PAGE, total);

  return (
    <div>
      <PageHeader
        title={tx.ticketsTitle}
        description={tx.ticketsSubtitle}
        icon={LifeBuoy}
      />

      <div className="space-y-6">
        <NewTicketCard recentOrderIds={recentOrders.map((order) => order.id)} />

        <section className="space-y-3">
          <div className="flex flex-wrap items-baseline justify-between gap-2">
            <h2 className="font-display text-base font-semibold tracking-tight">
              {tx.listTitle}
            </h2>
            {total > 0 ? (
              <p className="font-mono text-xs text-muted-foreground">
                {fill(tx.showingRange, { from, to, total })}
              </p>
            ) : null}
          </div>

          <TicketList tickets={tickets} />

          {pageCount > 1 ? (
            <div className="flex items-center justify-end gap-2 pt-1">
              {page > 1 ? (
                <Link
                  href={`/tickets?page=${page - 1}`}
                  className={cn(
                    buttonVariants({ variant: "outline", size: "sm" }),
                    "rounded-lg",
                  )}
                >
                  {commonTexts.previous}
                </Link>
              ) : (
                <Button variant="outline" size="sm" disabled className="rounded-lg">
                  {commonTexts.previous}
                </Button>
              )}
              <span className="font-mono text-xs text-muted-foreground">
                {page} / {pageCount}
              </span>
              {page < pageCount ? (
                <Link
                  href={`/tickets?page=${page + 1}`}
                  className={cn(
                    buttonVariants({ variant: "outline", size: "sm" }),
                    "rounded-lg",
                  )}
                >
                  {commonTexts.next}
                </Link>
              ) : (
                <Button variant="outline" size="sm" disabled className="rounded-lg">
                  {commonTexts.next}
                </Button>
              )}
            </div>
          ) : null}
        </section>
      </div>
    </div>
  );
}
