"use client";

import Link from "next/link";
import { useCallback, useEffect, useMemo, useState } from "react";
import { useSearchParams } from "next/navigation";
import { useTranslation } from "react-i18next";
import { toast } from "sonner";
import { ArrowUpRight, Database, FileDown, FileSpreadsheet, Search } from "lucide-react";

import { getAdminAuditLogs } from "@/api/admin-audit";
import { useAdminPlayTypeCatalog } from "@/hooks/use-admin-play-type-catalog";
import { useCachedPlayTypeOptions } from "@/hooks/use-cached-play-type-options";
import { useTranslationRef } from "@/hooks/use-translation-ref";
import { getAdminDrawFinanceSummary } from "@/api/admin-draws";
import { DrawStatusBadge } from "@/modules/draws/draw-status-badge";
import { drawStatusLabel } from "@/modules/draws/draw-display";
import { getAdminPlayers } from "@/api/admin-player";
import { downloadAdminReportJob, postAdminReportJob } from "@/api/admin-report-jobs";
import {
  getAdminReportDailyProfit,
  getAdminReportPlayDimension,
  getAdminReportPlayerWinLoss,
} from "@/api/admin-reports";
import {
  buildReportJobParameters,
  REPORT_UI_TO_JOB_TYPE,
  type ReportUiKey,
} from "@/lib/report-export-map";
import { getAdminRiskPoolDetail, getAdminRiskPools } from "@/api/admin-risk";
import { getAdminUsers } from "@/api/admin-users";
import { getAdminTransferOrders } from "@/api/admin-wallet";
import { adminHasAnyPermission } from "@/lib/admin-permissions";
import { PRD_REPORT_EXPORT } from "@/lib/admin-prd";
import { useAdminProfile } from "@/stores/admin-session";
import { AdminNoResourceState } from "@/components/admin/admin-no-resource-state";
import { AdminDateRangeField } from "@/components/admin/admin-date-range-field";
import { AdminListPaginationFooter } from "@/components/admin/admin-list-pagination-footer";
import { AdminSubnav, AdminSubnavLink } from "@/components/admin/admin-subnav";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
import { AdminLoadingInline } from "@/components/admin/admin-loading-state";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { useAdminCurrencyCatalog } from "@/hooks/use-admin-currency-catalog";
import { cn } from "@/lib/utils";
import { LotteryApiBizError } from "@/types/api/errors";
import { getAdminDraws } from "@/api/admin-draws";

import { ReportPreviewTable } from "@/modules/reports/report-preview-tables";
import {
  CATEGORY_SHORTCUT_HREF,
  REPORT_CATEGORY_ORDER,
  REPORT_DEFINITIONS,
  type FieldKey,
  type ReportCategory,
  type ReportKey,
} from "@/modules/reports/reports-definitions";
import {
  buildDailyProfitRowsAndSummary,
  buildPlayDimensionRowsAndSummary,
  buildPlayerTransferRowsAndSummary,
  createDefaultFilters,
  downloadBlob,
  drawRowsFromSummary,
  emptyFilters,
  emptySearch,
  formatPlainMoney,
  formatUsagePercent,
  headlineStats,
  metaFromList,
  normalizeFilenamePart,
  optionText,
  parsePositiveInteger,
  reportHasPeriodField,
  reportListParams,
  resolveDisplayCurrency,
  resolveDraw,
  type ExportFormat,
  type ReportFilters,
  type ReportResult,
  type SearchKind,
  type SearchState,
} from "@/modules/reports/reports-utils";

export type { ReportCategory } from "@/modules/reports/reports-definitions";

type ReportsConsoleProps = {
  initialCategory?: ReportCategory;
};

export function ReportsConsole({ initialCategory = "profit" }: ReportsConsoleProps) {
  const { t } = useTranslation(["reports", "common"]);
  const profile = useAdminProfile();
  const permissionSlugs = useMemo(() => profile?.permissions ?? [], [profile?.permissions]);
  const canExportReports = adminHasAnyPermission(permissionSlugs, [PRD_REPORT_EXPORT]);

  useAdminCurrencyCatalog();
  useAdminPlayTypeCatalog();
  const playOptions = useCachedPlayTypeOptions();
  const tRef = useTranslationRef(["reports", "common"]);
  const searchParams = useSearchParams();
  const drawNoFromUrl = (searchParams.get("draw_no") ?? "").trim();

  const visibleReports = useMemo(
    () => REPORT_DEFINITIONS.filter((report) => adminHasAnyPermission(permissionSlugs, report.requiredAny)),
    [permissionSlugs],
  );

  const categoriesWithReports = useMemo(
    () => REPORT_CATEGORY_ORDER.filter((cat) => visibleReports.some((report) => report.category === cat)),
    [visibleReports],
  );

  const activeCategory = categoriesWithReports.includes(initialCategory)
    ? initialCategory
    : (categoriesWithReports[0] ?? "profit");

  const categoryReports = useMemo(
    () => visibleReports.filter((report) => report.category === activeCategory),
    [activeCategory, visibleReports],
  );

  const [selectedKey, setSelectedKey] = useState<ReportKey>(categoryReports[0]?.key ?? "daily_profit");
  const [filters, setFilters] = useState<ReportFilters>(createDefaultFilters);
  const [displayCurrency, setDisplayCurrency] = useState<string>(() => resolveDisplayCurrency(null));
  const [result, setResult] = useState<ReportResult | null>(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [page, setPage] = useState(1);
  const [perPage, setPerPage] = useState(20);
  const [exporting, setExporting] = useState<ExportFormat | null>(null);
  const [search, setSearch] = useState<SearchState>(emptySearch);

  const selectedReport =
    categoryReports.find((report) => report.key === selectedKey) ?? categoryReports[0] ?? REPORT_DEFINITIONS[0];

  const canQuerySelected = adminHasAnyPermission(permissionSlugs, selectedReport.requiredAny);

  useEffect(() => {
    if (categoryReports.length === 0) {
      return;
    }
    if (!categoryReports.some((report) => report.key === selectedKey)) {
      setSelectedKey(categoryReports[0].key);
    }
  }, [categoryReports, selectedKey]);

  const pageScopedLabel = useCallback(
    (statKey: string) => t(`preview.stats.${statKey}`),
    [t],
  );

  const exportFileBase = useMemo(() => {
    const segments: string[] = [selectedReport.key];
    if (filters.drawNo.trim()) segments.push(filters.drawNo.trim());
    if (filters.number.trim()) segments.push(filters.number.trim());
    if (filters.player.trim()) segments.push(filters.player.trim());
    if (filters.play.trim()) segments.push(filters.play.trim());
    if (filters.operator.trim()) segments.push(filters.operator.trim());
    if (filters.dateFrom) segments.push(filters.dateFrom);
    if (filters.dateTo) segments.push(filters.dateTo);
    return normalizeFilenamePart(segments.join("-")) || selectedReport.key;
  }, [selectedReport.key, filters]);

  const loadSearchOptions = useCallback(async (kind: SearchKind, query: string) => {
    setSearch((prev) => ({ ...prev, loading: true }));
    try {
      if (kind === "draw") {
        const payload = await getAdminDraws({ draw_no: query.trim() || undefined, page: 1, per_page: 8 });
        setSearch((prev) => ({ ...prev, draws: payload.items, loading: false }));
        return;
      }
      if (kind === "player") {
        const payload = await getAdminPlayers({ keyword: query.trim() || undefined, page: 1, per_page: 8 });
        setSearch((prev) => ({ ...prev, players: payload.items, loading: false }));
        return;
      }
      const payload = await getAdminUsers({ keyword: query.trim() || undefined, page: 1, per_page: 8 });
      setSearch((prev) => ({ ...prev, operators: payload.items, loading: false }));
    } catch {
      setSearch((prev) => ({ ...prev, loading: false }));
    }
  }, []);

  useEffect(() => {
    if (search.open === null) {
      return;
    }
    const timer = window.setTimeout(() => {
      void loadSearchOptions(search.open as SearchKind, search.query);
    }, 250);
    return () => window.clearTimeout(timer);
  }, [search.open, search.query, loadSearchOptions]);

  const queryReport = useCallback(async () => {
    if (!canQuerySelected) {
      return;
    }
    setLoading(true);
    setError(null);
    try {
      switch (selectedReport.key) {
        case "draw_profit": {
          const draw = await resolveDraw(filters, {
            drawNoRequired: tRef.current("validation.drawNoRequired", { ns: "reports" }),
            drawNoNotFound: (drawNo) =>
              tRef.current("validation.drawNoNotFound", { ns: "reports", drawNo }),
          });
          const summary = await getAdminDrawFinanceSummary(draw.id);
          setDisplayCurrency(resolveDisplayCurrency(summary.currency_code));
          setResult({
            key: "draw_profit",
            raw: summary,
            rows: drawRowsFromSummary(summary),
            meta: null,
            summary: [
              {
                label: t("preview.stats.houseGross"),
                value: formatPlainMoney(summary.approx_house_gross_minor, summary.currency_code),
                tone: summary.approx_house_gross_minor >= 0 ? "good" : "bad",
              },
              { label: t("preview.stats.orders"), value: String(summary.order_count) },
            ],
          });
          break;
        }
        case "daily_profit": {
          const payload = await getAdminReportDailyProfit(reportListParams(filters, page, perPage));
          const currencyCode = resolveDisplayCurrency(payload.currency_code);
          setDisplayCurrency(currencyCode);
          const next = buildDailyProfitRowsAndSummary(
            payload.items,
            payload.meta.total,
            t,
            pageScopedLabel,
            currencyCode,
          );
          setResult({
            key: "daily_profit",
            raw: payload.items,
            rows: next.rows,
            meta: metaFromList(payload.meta),
            summary: next.summary,
          });
          break;
        }
        case "player_win_loss": {
          const payload = await getAdminReportPlayerWinLoss(reportListParams(filters, page, perPage));
          const currencyCode = resolveDisplayCurrency(payload.currency_code);
          setDisplayCurrency(currencyCode);
          const houseGross = payload.items.reduce((sum, item) => sum - item.net_win_loss_minor, 0);
          setResult({
            key: "player_win_loss",
            raw: payload.items,
            rows: payload.items.map((item) => ({
              player_id: item.player_id,
              username: item.username,
              total_bet_minor: item.total_bet_minor,
              total_payout_minor: item.total_payout_minor,
              net_win_loss_minor: item.net_win_loss_minor,
            })),
            meta: metaFromList(payload.meta),
            summary: [
              { label: t("preview.stats.records"), value: String(payload.meta.total) },
              {
                label: pageScopedLabel("houseGross"),
                value: formatPlainMoney(houseGross, currencyCode),
                tone: houseGross >= 0 ? "good" : "bad",
              },
            ],
          });
          break;
        }
        case "player_transfer": {
          const playerId = filters.playerId ?? parsePositiveInteger(filters.player);
          const payload = await getAdminTransferOrders({
            page,
            per_page: perPage,
            player_id: playerId ?? undefined,
            player_account: playerId ? undefined : filters.player.trim() || undefined,
            created_from: filters.dateFrom || undefined,
            created_to: filters.dateTo || undefined,
          });
          const next = buildPlayerTransferRowsAndSummary(
            payload.items,
            payload.total,
            payload.page,
            payload.per_page,
            t,
          );
          setDisplayCurrency(resolveDisplayCurrency(payload.items[0]?.currency_code));
          setResult({
            key: "player_transfer",
            raw: payload.items,
            rows: next.rows,
            meta: next.meta,
            summary: next.summary,
          });
          break;
        }
        case "hot_number_risk": {
          if (!filters.number.trim()) {
            throw new LotteryApiBizError(tRef.current("validation.drawNoNumberRequired"), -1, null);
          }
          const draw = await resolveDraw(filters, {
            drawNoRequired: tRef.current("validation.drawNoRequired", { ns: "reports" }),
            drawNoNotFound: (drawNo) =>
              tRef.current("validation.drawNoNotFound", { ns: "reports", drawNo }),
          });
          const detail = await getAdminRiskPoolDetail(draw.id, filters.number.trim(), { page, per_page: perPage });
          setDisplayCurrency(resolveDisplayCurrency(detail.currency_code));
          setResult({
            key: "hot_number_risk",
            raw: detail,
            rows: [],
            meta: metaFromList(detail.logs.meta),
            summary: [
              {
                label: t("preview.stats.usage"),
                value: formatUsagePercent(detail.pool.usage_ratio),
                tone: detail.pool.is_sold_out ? "bad" : "warn",
              },
              { label: t("preview.stats.logs"), value: String(detail.logs.meta.total) },
            ],
          });
          break;
        }
        case "sold_out_number": {
          const draw = await resolveDraw(filters, {
            drawNoRequired: tRef.current("validation.drawNoRequired", { ns: "reports" }),
            drawNoNotFound: (drawNo) =>
              tRef.current("validation.drawNoNotFound", { ns: "reports", drawNo }),
          });
          const payload = await getAdminRiskPools(draw.id, {
            page,
            per_page: perPage,
            sold_out_only: true,
            sort: "number_asc",
          });
          setDisplayCurrency(resolveDisplayCurrency(payload.currency_code));
          setResult({
            key: "sold_out_number",
            raw: payload.items,
            rows: payload.items.map((item) => ({ normalized_number: item.normalized_number })),
            meta: metaFromList(payload.meta),
            summary: [
              {
                label: t("preview.stats.records"),
                value: String(payload.meta.total),
                tone: payload.meta.total > 0 ? "bad" : "good",
              },
              { label: t("preview.stats.drawNo"), value: payload.draw_no },
            ],
          });
          break;
        }
        case "play_dimension": {
          const payload = await getAdminReportPlayDimension(reportListParams(filters, page, perPage));
          const currencyCode = resolveDisplayCurrency(payload.currency_code);
          setDisplayCurrency(currencyCode);
          const next = buildPlayDimensionRowsAndSummary(payload.items, payload.meta.total, t, currencyCode);
          setResult({
            key: "play_dimension",
            raw: payload.items,
            rows: next.rows,
            meta: metaFromList(payload.meta),
            summary: next.summary,
          });
          break;
        }
        case "admin_audit": {
          const operatorId = filters.operatorId ?? parsePositiveInteger(filters.operator);
          const payload = await getAdminAuditLogs({
            page,
            per_page: perPage,
            operator_id: operatorId ?? undefined,
            operator_type: operatorId ? undefined : filters.operator.trim() || undefined,
            start_date: filters.dateFrom || undefined,
            end_date: filters.dateTo || undefined,
          });
          setResult({
            key: "admin_audit",
            raw: payload.items,
            rows: payload.items.map((item) => ({ id: item.id })),
            meta: metaFromList(payload.meta),
            summary: [
              { label: t("preview.stats.records"), value: String(payload.meta.total) },
              {
                label: t("preview.stats.operators"),
                value: String(new Set(payload.items.map((item) => item.operator_id)).size),
              },
            ],
          });
          break;
        }
        default:
          setResult(null);
          setError(tRef.current("loadFailed"));
      }
    } catch (err) {
      setResult(null);
      setError(err instanceof LotteryApiBizError ? err.message : tRef.current("loadFailed"));
    } finally {
      setLoading(false);
    }
  }, [canQuerySelected, filters, page, perPage, pageScopedLabel, selectedReport.key, t, tRef]);

  useEffect(() => {
    setResult(null);
    setError(null);
    setPage(1);
  }, [selectedKey]);

  useEffect(() => {
    setFilters((prev) => ({
      ...prev,
      drawNo: drawNoFromUrl || prev.drawNo,
    }));
    if (drawNoFromUrl && visibleReports.some((report) => report.key === "draw_profit")) {
      setSelectedKey("draw_profit");
    }
  }, [drawNoFromUrl, visibleReports]);

  useEffect(() => {
    if (!result || result.key !== selectedReport.key || !selectedReport.connected) {
      return;
    }
    void queryReport();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [page, perPage]);

  function updateFilter<K extends keyof ReportFilters>(key: K, value: ReportFilters[K]): void {
    setFilters((prev) => ({ ...prev, [key]: value }));
  }

  function resetFilters(): void {
    setFilters(reportHasPeriodField(selectedReport) ? createDefaultFilters() : { ...emptyFilters });
    setResult(null);
    setError(null);
    setPage(1);
  }

  async function exportReport(format: ExportFormat): Promise<void> {
    if (!canExportReports) {
      return;
    }
    setExporting(format);
    try {
      const parameters = buildReportJobParameters(selectedReport.key as ReportUiKey, {
        dateFrom: filters.dateFrom,
        dateTo: filters.dateTo,
        playerId: filters.playerId,
        play: filters.play,
        operatorId: filters.operatorId,
        drawId: filters.drawId,
        drawNo: filters.drawNo,
        number: filters.number,
      });
      const job = await postAdminReportJob({
        report_type: REPORT_UI_TO_JOB_TYPE[selectedReport.key as ReportUiKey],
        export_format: format === "excel" ? "xlsx" : "csv",
        parameters,
      });
      const { blob, filename } = await downloadAdminReportJob(job.id);
      const ext = job.export_format === "xlsx" ? "xlsx" : "csv";
      downloadBlob(blob, filename ?? `${exportFileBase}.${ext}`);
      toast.success(
        t("exportSuccess", {
          report: t(`items.${selectedReport.key}.title`),
          format: t(`formats.${format}`),
        }),
      );
    } catch (err) {
      toast.error(err instanceof LotteryApiBizError ? err.message : t("exportFailed"));
    } finally {
      setExporting(null);
    }
  }

  const renderSearchPicker = (kind: SearchKind) => {
    const value =
      kind === "draw" ? filters.drawNo : kind === "player" ? filters.player : filters.operator;
    const labelKey = kind === "draw" ? "drawNo" : kind === "player" ? "player" : "operator";
    const open = search.open === kind;

    return (
      <div className="min-w-[12rem] flex-1">
        <Label className="sr-only" htmlFor={`report-${kind}`}>
          {t(`fields.${labelKey}`)}
        </Label>
        <Popover
          open={open}
          onOpenChange={(nextOpen) => {
            setSearch((prev) =>
              nextOpen ? { ...prev, open: kind, query: value } : emptySearch,
            );
          }}
          modal={false}
        >
          <div className="flex gap-1.5">
            <Input
              id={`report-${kind}`}
              className="h-8"
              value={value}
              onChange={(e) => {
                const next = e.target.value;
                if (kind === "draw") {
                  setFilters((prev) => ({ ...prev, drawNo: next, drawId: null }));
                } else if (kind === "player") {
                  setFilters((prev) => ({ ...prev, player: next, playerId: null }));
                } else {
                  setFilters((prev) => ({ ...prev, operator: next, operatorId: null }));
                }
              }}
              placeholder={t(`placeholders.${labelKey}`)}
            />
            <PopoverTrigger
              render={
                <Button
                  type="button"
                  variant="outline"
                  size="sm"
                  className="h-8 shrink-0 px-2"
                  aria-label={t("searchPicker.open")}
                />
              }
            >
              <Search className="size-3.5" />
            </PopoverTrigger>
          </div>
          <PopoverContent
            align="start"
            side="bottom"
            sideOffset={6}
            className="z-[80] w-[var(--anchor-width)] min-w-[min(24rem,calc(100vw-2rem))] max-w-[calc(100vw-2rem)] p-2"
          >
            <Input
              value={search.query}
              placeholder={t("searchPicker.keyword")}
              onChange={(e) => setSearch((prev) => ({ ...prev, query: e.target.value }))}
            />
            <div className="mt-2 max-h-64 overflow-auto">
              {search.loading ? <AdminLoadingInline className="py-2" /> : null}
              {!search.loading && kind === "draw"
                ? search.draws.map((item) => (
                    <button
                      key={item.id}
                      type="button"
                      className="flex w-full items-center justify-between rounded-md px-2 py-2 text-left text-sm hover:bg-muted"
                      onClick={() => {
                        setFilters((prev) => ({ ...prev, drawNo: item.draw_no, drawId: item.id }));
                        setSearch(emptySearch);
                      }}
                    >
                      <span className="font-medium">{item.draw_no}</span>
                      <DrawStatusBadge
                        status={item.status}
                        label={drawStatusLabel(item.status, t)}
                      />
                    </button>
                  ))
                : null}
              {!search.loading && kind === "player"
                ? search.players.map((item) => (
                    <button
                      key={item.id}
                      type="button"
                      className="flex w-full items-center justify-between gap-3 rounded-md px-2 py-2 text-left text-sm hover:bg-muted"
                      onClick={() => {
                        setFilters((prev) => ({
                          ...prev,
                          player: optionText(item.username, item.site_player_id, `ID ${item.id}`),
                          playerId: item.id,
                        }));
                        setSearch(emptySearch);
                      }}
                    >
                      <span className="min-w-0 truncate font-medium">
                        {optionText(item.username, item.nickname, item.site_player_id)}
                      </span>
                      <span className="shrink-0 text-xs text-muted-foreground">ID {item.id}</span>
                    </button>
                  ))
                : null}
              {!search.loading && kind === "operator"
                ? search.operators.map((item) => (
                    <button
                      key={item.id}
                      type="button"
                      className="flex w-full items-center justify-between gap-3 rounded-md px-2 py-2 text-left text-sm hover:bg-muted"
                      onClick={() => {
                        setFilters((prev) => ({
                          ...prev,
                          operator: optionText(item.username, item.nickname, `ID ${item.id}`),
                          operatorId: item.id,
                        }));
                        setSearch(emptySearch);
                      }}
                    >
                      <span className="min-w-0 truncate font-medium">
                        {optionText(item.username, item.nickname)}
                      </span>
                      <span className="shrink-0 text-xs text-muted-foreground">ID {item.id}</span>
                    </button>
                  ))
                : null}
            </div>
          </PopoverContent>
        </Popover>
      </div>
    );
  };

  const renderField = (field: FieldKey) => {
    if (field === "period") {
      return (
        <AdminDateRangeField
          key={field}
          id="report-date-range"
          label={t("fields.period")}
          from={filters.dateFrom}
          to={filters.dateTo}
          onRangeChange={({ from, to }) => {
            setFilters((prev) => ({ ...prev, dateFrom: from, dateTo: to }));
          }}
        />
      );
    }
    if (field === "drawNo") {
      return <div key={field}>{renderSearchPicker("draw")}</div>;
    }
    if (field === "player") {
      return <div key={field}>{renderSearchPicker("player")}</div>;
    }
    if (field === "operator") {
      return <div key={field}>{renderSearchPicker("operator")}</div>;
    }
    if (field === "play") {
      return (
        <div key={field} className="min-w-[10rem] flex-1">
          <Label className="sr-only" htmlFor="report-play">
            {t("fields.play")}
          </Label>
          <Select
            modal={false}
            value={filters.play || "__none__"}
            onValueChange={(value) => updateFilter("play", value === "__none__" ? "" : String(value))}
          >
            <SelectTrigger id="report-play" className="h-8 w-full">
              <SelectValue>
                {filters.play
                  ? (playOptions.find((item) => item.code === filters.play)?.label ?? filters.play)
                  : t("filterAll")}
              </SelectValue>
            </SelectTrigger>
            <SelectContent align="start" sideOffset={6}>
              <SelectItem value="__none__">{t("filterAll")}</SelectItem>
              {playOptions.map((item) => (
                <SelectItem key={item.code} value={item.code}>
                  {item.label}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
        </div>
      );
    }
    return (
      <div key={field} className="min-w-[8rem] flex-1">
        <Label className="sr-only" htmlFor={`report-${field}`}>
          {t(`fields.${field}`)}
        </Label>
        <Input
          id={`report-${field}`}
          className="h-8"
          value={filters.number}
          onChange={(e) => updateFilter("number", e.target.value)}
          placeholder={t(`placeholders.${field}`)}
        />
      </div>
    );
  };

  const stats = headlineStats(result, selectedReport.key);
  const shortcutHref = CATEGORY_SHORTCUT_HREF[activeCategory];

  if (visibleReports.length === 0) {
    return <AdminNoResourceState message={t("empty")} />;
  }

  return (
    <div className="flex w-full flex-col gap-4">
      <AdminSubnav aria-label={t("categories.all")}>
        {categoriesWithReports.map((category) => (
          <AdminSubnavLink
            key={category}
            href={`/admin/reports/${category}`}
            active={activeCategory === category}
          >
            {t(`categories.${category}`)}
          </AdminSubnavLink>
        ))}
      </AdminSubnav>

      <div className="flex flex-wrap items-center gap-2">
        <Select
          value={selectedReport.key}
          onValueChange={(value) => {
            if (value) {
              setSelectedKey(value as ReportKey);
            }
          }}
        >
          <SelectTrigger className="h-9 w-full min-w-[12rem] max-w-md">
            <SelectValue>{t(`items.${selectedReport.key}.title`)}</SelectValue>
          </SelectTrigger>
          <SelectContent>
            {categoryReports.map((report) => (
              <SelectItem key={report.key} value={report.key}>
                {t(`items.${report.key}.title`)}
              </SelectItem>
            ))}
          </SelectContent>
        </Select>
        {shortcutHref ? (
          <Link
            href={shortcutHref}
            className="inline-flex h-9 items-center gap-1 rounded-md px-2.5 text-sm text-muted-foreground transition-colors hover:text-foreground"
          >
            {t(`shortcuts.${activeCategory}`)}
            <ArrowUpRight className="size-3.5" />
          </Link>
        ) : null}
        {activeCategory === "profit" ? (
          <span className="text-xs text-muted-foreground">{t("profitScopeHint")}</span>
        ) : null}
      </div>

      <div className="rounded-lg border border-border/60 p-3">
        <div className="flex flex-wrap items-end gap-2">
          {selectedReport.fields.map(renderField)}
          <div className="flex flex-wrap items-center gap-1.5 sm:ml-auto">
            <Button type="button" variant="ghost" size="sm" className="h-8" onClick={resetFilters}>
              {t("reset")}
            </Button>
            <Button
              type="button"
              size="sm"
              className="h-8"
              disabled={!canQuerySelected || !selectedReport.connected || loading}
              onClick={() => {
                setPage(1);
                void queryReport();
              }}
            >
              <Database className="size-3.5" data-icon="inline-start" />
              {loading ? t("querying") : t("query")}
            </Button>
            <Button
              type="button"
              variant="outline"
              size="sm"
              className="h-8"
              disabled={!canExportReports || exporting !== null}
              onClick={() => void exportReport("csv")}
            >
              <FileDown className="size-3.5" data-icon="inline-start" />
              {t("formats.csv")}
            </Button>
            <Button
              type="button"
              variant="outline"
              size="sm"
              className="h-8"
              disabled={!canExportReports || exporting !== null}
              onClick={() => void exportReport("excel")}
            >
              <FileSpreadsheet className="size-3.5" data-icon="inline-start" />
              {t("formats.excel")}
            </Button>
          </div>
        </div>
      </div>

      {stats.length > 0 ? (
        <div className="flex flex-wrap gap-2">
          {stats.map((item) => (
            <div
              key={item.label}
              className={cn(
                "inline-flex items-baseline gap-2 rounded-md border px-3 py-1.5 text-sm",
                item.tone === "good"
                  ? "border-emerald-200/80 bg-emerald-50/50"
                  : item.tone === "bad"
                    ? "border-red-200/80 bg-red-50/50"
                    : item.tone === "warn"
                      ? "border-amber-200/80 bg-amber-50/50"
                      : "border-border/60 bg-muted/30",
              )}
            >
              <span className="text-muted-foreground">{item.label}</span>
              <span className="font-semibold tabular-nums">{item.value}</span>
            </div>
          ))}
        </div>
      ) : null}

      <div className="rounded-lg border border-border/60">
        <ReportPreviewTable
          report={selectedReport}
          result={result}
          loading={loading}
          error={error}
          drawNoLabel={filters.drawNo}
          displayCurrency={displayCurrency}
        />
        {result?.meta ? (
          <div className="border-t border-border/60 px-3 py-2">
            <AdminListPaginationFooter
              selectId="reports-preview-per-page"
              total={result.meta.total}
              page={result.meta.page}
              lastPage={result.meta.lastPage}
              perPage={result.meta.perPage}
              loading={loading}
              onPerPageChange={(next) => {
                setPerPage(next);
                setPage(1);
              }}
              onPageChange={setPage}
            />
          </div>
        ) : null}
      </div>
    </div>
  );
}