// src/features/admin-earnings/AdminEarnings.tsx
// Admin: read-only vendor earnings report grouped by vendor + month-year.

'use client';

import { useCallback, useMemo } from 'react';
import { useT, useLocale } from '@/lib/i18n/react';
import { interpolate } from '@/lib/i18n/interpolate';
import { usePaginatedQuery } from '@/lib/hooks/usePaginatedQuery';
import { useAdminTableState } from '@/lib/hooks/useAdminTableState';
import { AdminListPage } from '@/components/ui/domain/admin/AdminListPage';
import {
  AdminTable,
  AdminTableToolbar,
  useAdminTableLayout,
  type ColumnDef,
} from '@/components/ui/domain/admin';
import { AdminFilterBar } from '@/components/ui/domain/admin/AdminFilterBar';
import { Pagination } from '@/components/ui/primitives/Pagination';
import { buildCsv, buildJson, downloadBlob } from '@/lib/admin/export';
import { formatAgorotLocale } from '@/lib/money';

const TABLE_ID = '/admin/earnings';
const FILTER_KEYS = ['from', 'to', 'vendorId'];

function formatMonthYear(iso: string, locale: string): string {
  const [yearStr, monthStr] = iso.split('-');
  const year = Number(yearStr);
  const month = Number(monthStr);
  if (!year || !month) return iso;
  return new Intl.DateTimeFormat(locale === 'he' ? 'he-IL' : 'en-US', {
    month: 'long',
    year: 'numeric',
    timeZone: 'UTC',
  }).format(new Date(Date.UTC(year, month - 1, 1)));
}

export interface EarningsRow {
  vendorId: string;
  vendorBusinessName: string;
  monthYearMonth: string;
  purchaseCount: number;
  grossAgorot: number;
  vendorAmountAgorot: number;
  platformFeeAgorot: number;
  refundedAgorot: number;
}

export interface AdminEarningsProps {
  initialRows: EarningsRow[];
  initialTotal: number;
  initialPage?: number;
  /** Overview page uses settlement-aware subtitle; detail page uses payment-split copy. */
  pageVariant?: 'overview' | 'detail';
}

export function AdminEarnings({
  initialRows,
  initialTotal,
  initialPage,
  pageVariant = 'overview',
}: AdminEarningsProps) {
  const t = useT('admin_earnings');
  const { locale } = useLocale();

  const { sortBy, sortDir, applySort, clearSort, queryParams } = useAdminTableState({
    filterKeys: FILTER_KEYS,
  });

  const {
    data,
    total,
    totalPages,
    page,
    isLoading,
    isInitialLoading,
    isRefetching,
    error,
    setPage,
  } = usePaginatedQuery<EarningsRow>({
    endpoint: '/api/admin/earnings',
    params: queryParams,
    limit: 50,
    initialData: initialRows,
    initialTotal,
    initialPage,
    dataKey: 'rows',
  });

  const columns: ColumnDef<EarningsRow>[] = useMemo(
    () => [
      { key: 'vendorBusinessName', label: t('col_vendor'), sortable: true, sortType: 'string' },
      {
        key: 'monthYearMonth',
        label: t('col_month'),
        align: 'center',
        sortable: true,
        sortType: 'date',
        headerTooltip: t('tooltip_col_month'),
        render: (r) => formatMonthYear(r.monthYearMonth, locale),
        exportValue: (r) => r.monthYearMonth,
      },
      {
        key: 'purchaseCount',
        label: t('col_purchases'),
        align: 'end',
        sortable: true,
        sortType: 'number',
        headerTooltip: t('tooltip_col_purchases'),
      },
      {
        key: 'grossAgorot',
        label: t('col_gross'),
        align: 'end',
        sortable: true,
        sortType: 'number',
        headerTooltip: t('tooltip_col_gross'),
        render: (r) => formatAgorotLocale(r.grossAgorot, locale),
        exportValue: (r) => r.grossAgorot,
      },
      {
        key: 'vendorAmountAgorot',
        label: t('col_vendor_amount'),
        align: 'end',
        sortable: true,
        sortType: 'number',
        headerTooltip: t('tooltip_col_vendor_amount'),
        render: (r) => formatAgorotLocale(r.vendorAmountAgorot, locale),
        exportValue: (r) => r.vendorAmountAgorot,
      },
      {
        key: 'platformFeeAgorot',
        label: t('col_platform_fee'),
        align: 'end',
        sortable: true,
        sortType: 'number',
        headerTooltip: t('tooltip_col_platform_fee'),
        render: (r) => formatAgorotLocale(r.platformFeeAgorot, locale),
        exportValue: (r) => r.platformFeeAgorot,
      },
      {
        key: 'refundedAgorot',
        label: t('col_refunded'),
        align: 'end',
        sortable: true,
        sortType: 'number',
        headerTooltip: t('tooltip_col_refunded'),
        render: (r) => formatAgorotLocale(r.refundedAgorot, locale),
        exportValue: (r) => r.refundedAgorot,
      },
    ],
    [t, locale],
  );

  const layout = useAdminTableLayout(TABLE_ID, columns);

  const rowsForTable = useMemo(
    () => data.map((r) => ({ ...r, id: `${r.vendorId}__${r.monthYearMonth}` })),
    [data],
  );

  function monthPurchasesHref(row: EarningsRow): string {
    const [yearStr, monthStr] = row.monthYearMonth.split('-');
    const year = Number(yearStr);
    const month = Number(monthStr);
    if (!year || !month) {
      return `/admin/purchases/orders?vendorId=${encodeURIComponent(row.vendorId)}`;
    }
    const lastDay = new Date(Date.UTC(year, month, 0)).getUTCDate();
    const from = `${row.monthYearMonth}-01`;
    const to = `${row.monthYearMonth}-${String(lastDay).padStart(2, '0')}`;
    const qs = new URLSearchParams({
      vendorId: row.vendorId,
      from,
      to,
    });
    return `/admin/purchases/orders?${qs.toString()}`;
  }

  const exportColumns = layout.visibleColumns;

  const handleExportPageCsv = useCallback(() => {
    downloadBlob(
      `multideal-earnings-page-${new Date().toISOString().slice(0, 10)}.csv`,
      'text/csv;charset=utf-8',
      buildCsv(exportColumns, data),
    );
  }, [data, exportColumns]);

  const handleExportAllCsv = useCallback(async () => {
    const qs = new URLSearchParams({ ...queryParams, export: 'csv' });
    const res = await fetch(`/api/admin/earnings?${qs.toString()}`);
    if (!res.ok) return;
    const blob = await res.blob();
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = `multideal-earnings-${new Date().toISOString().slice(0, 10)}.csv`;
    a.click();
    URL.revokeObjectURL(url);
  }, [queryParams]);

  const handleExportPageJson = useCallback(() => {
    downloadBlob(
      `multideal-earnings-${new Date().toISOString().slice(0, 10)}.json`,
      'application/json',
      buildJson(exportColumns, data),
    );
  }, [data, exportColumns]);

  const handlePrint = useCallback(() => {
    window.print();
  }, []);

  const rangeLabel =
    total > 0
      ? interpolate(t('showing_range'), {
          from: (page - 1) * 50 + 1,
          to: Math.min(page * 50, total),
          total,
        })
      : null;

  const subtitleKey = pageVariant === 'detail' ? 'subtitle_detail' : 'subtitle';

  return (
    <AdminListPage
      subtitle={t(subtitleKey)}
      status={error ? 'error' : isInitialLoading ? 'loading' : 'idle'}
      busy={isRefetching}
      onRetry={() => setPage(page)}
      filterBar={
        <div className="flex flex-col gap-2">
          <AdminFilterBar
            searchKey="search"
            searchPlaceholder={t('search_placeholder')}
            dateRange={{ fromKey: 'from', toKey: 'to' }}
          />
          <p className="text-text-secondary px-1 text-xs">{t('date_range_helper')}</p>
        </div>
      }
      primaryAction={
        <AdminTableToolbar
          layout={layout}
          columns={columns}
          total={total}
          page={page}
          limit={50}
          isLoading={isLoading}
          rangeLabel={rangeLabel}
          onExportPageCsv={handleExportPageCsv}
          onExportAllCsv={handleExportAllCsv}
          onExportPageJson={handleExportPageJson}
          onPrint={handlePrint}
        />
      }
      table={
        <AdminTable<EarningsRow>
          tableId={TABLE_ID}
          layout={layout}
          columnControls
          columns={columns}
          rows={rowsForTable}
          loading={isLoading}
          rowHref={pageVariant === 'detail' ? (r) => monthPurchasesHref(r) : undefined}
          mode="server"
          sortBy={sortBy}
          sortDir={sortDir}
          emptyTitle={t('empty_title')}
          emptyDesc={t('empty_desc')}
          onSortChange={(nextSortBy, nextSortDir) => {
            if (!nextSortBy || !nextSortDir) clearSort();
            else applySort(nextSortBy, nextSortDir);
          }}
          stickyHeader
        />
      }
      pagination={
        totalPages > 1 ? (
          <Pagination page={page} totalPages={totalPages} onPageChange={setPage} />
        ) : undefined
      }
    />
  );
}
