// src/features/admin-deals/DealsMgmt.tsx
// Admin: deals management - paginated list with state/vendor/title filters.
// Each row links to /admin/deals/[id].

'use client';

import { useState, useEffect } from 'react';
import { getCsrfToken } from '@/lib/csrf';
import { useT, useLocale } from '@/lib/i18n/react';
import { interpolate } from '@/lib/i18n/interpolate';
import { usePaginatedQuery } from '@/lib/hooks/usePaginatedQuery';
import { AdminListPage } from '@/components/ui/domain/admin/AdminListPage';
import { AdminTable, type ColumnDef } from '@/components/ui/domain/admin/AdminTable';
import type { FilterChip } from '@/components/ui/domain/admin/AdminFilterBar';
import { Pagination } from '@/components/ui/primitives/Pagination';
import { useAdminFilters } from '@/components/ui/domain/admin/AdminFilterBar/useAdminFilters';
import { cn } from '@/lib/cn';
import { Pill } from '@/components/ui/primitives/Pill';
import { Label } from '@/components/ui/primitives/Label';
import { Button } from '@/components/ui/primitives/Button';
import { Input } from '@/components/ui/primitives/Input';
import { NumberInput } from '@/components/ui/primitives/NumberInput';
import { Row } from '@/components/ui/layout/Row';
import {
  TooltipProvider,
  Tooltip,
  TooltipTrigger,
  TooltipContent,
} from '@/components/ui/overlays/Tooltip';
import { Icon } from '@/components/ui/icons/Icon';
import { ErrorBoundary } from '@/components/ui/feedback/ErrorBoundary';
import { ErrorState } from '@/components/ui/feedback/ErrorState';
import { AdminListPageSkeleton } from '@/components/ui/feedback/Skeleton';
import { captureCaught } from '@/lib/observability';
import { formatDate } from '@/lib/format';
import { formatShekelFloat } from '@/lib/money';
import { dealState } from '@/lib/enums/deal-state';
import { QueryBoundary } from '@platform-modules/ui-primitives';

// ─── Types ────────────────────────────────────────────────────────────────────

export interface DealRow {
  id: string;
  vendorId: string;
  vendorDisplayName: string;
  title: string;
  dealState: string;
  dealType: string;
  originalPrice: string;
  discountedPrice: string;
  discountPercent: number;
  windowStart: string | null;
  windowEnd: string | null;
  createdAt: string;
}

export interface DealsMgmtProps {
  initialDeals: DealRow[];
  initialTotal: number;
  initialPage?: number;
}

// ─── Filter param keys ────────────────────────────────────────────────────────

const FILTER_KEYS = ['state'];

// ─── Deal state tone map ──────────────────────────────────────────────────────

const STATE_TONE: Record<string, 'success' | 'warning' | 'danger' | 'neutral' | 'info'> = {
  ACTIVE: 'success',
  PENDING_APPROVAL: 'warning',
  UNDER_REVIEW: 'info',
  DRAFT: 'neutral',
  PAUSED: 'neutral',
  SOLD_OUT: 'neutral',
  EXPIRED: 'neutral',
  REJECTED: 'danger',
};

const STATE_TOOLTIP_KEYS: Partial<
  Record<
    string,
    | 'state_pending_approval_tooltip'
    | 'state_under_review_tooltip'
    | 'state_paused_tooltip'
    | 'state_rejected_tooltip'
  >
> = {
  PENDING_APPROVAL: 'state_pending_approval_tooltip',
  UNDER_REVIEW: 'state_under_review_tooltip',
  PAUSED: 'state_paused_tooltip',
  REJECTED: 'state_rejected_tooltip',
};

// ─── Component ────────────────────────────────────────────────────────────────

const PAGE_LIMIT = 20;

export function DealsMgmt({ initialDeals, initialTotal, initialPage }: DealsMgmtProps) {
  const t = useT('admin_deals');
  const tAdmin = useT('admin');
  const tList = useT('admin_list');
  const { locale } = useLocale();

  // ── URL-bound filters ─────────────────────────────────────────────────────
  const { filters, setFilter } = useAdminFilters(FILTER_KEYS);

  // ── Local search inputs (not URL-bound to avoid double-encode issues) ─────
  const [vendorSearch, setVendorSearch] = useState('');
  const [titleSearch, setTitleSearch] = useState('');
  const [draftVendorSearch, setDraftVendorSearch] = useState('');
  const [draftTitleSearch, setDraftTitleSearch] = useState('');

  const params: Record<string, string> = {};
  if (filters['state']) params.state = filters['state'];
  if (vendorSearch) params.vendorSearch = vendorSearch;
  if (titleSearch) params.search = titleSearch;

  // ── Paginated data ─────────────────────────────────────────────────────────
  const { data, total, totalPages, page, isInitialLoading, isRefetching, error, setPage, refetch } =
    usePaginatedQuery<DealRow>({
      endpoint: '/api/admin/deals',
      params,
      limit: PAGE_LIMIT,
      initialData: initialDeals,
      initialTotal,
      initialPage,
      dataKey: 'deals',
    });

  // ── Deal settings panel ───────────────────────────────────────────────────
  const [minDiscount, setMinDiscount] = useState<number>(0);
  const [draftMinDiscount, setDraftMinDiscount] = useState<number>(0);
  const [hotDealThreshold, setHotDealThreshold] = useState<number>(10);
  const [draftHotDealThreshold, setDraftHotDealThreshold] = useState<number>(10);
  const [isSavingSettings, setIsSavingSettings] = useState(false);
  const [settingsSaved, setSettingsSaved] = useState(false);
  const [settingsError, setSettingsError] = useState<string | null>(null);

  useEffect(() => {
    fetch('/api/admin/deal-settings')
      .then(
        (r) =>
          r.json() as Promise<{
            ok: boolean;
            minDiscountPercent: number;
            hotDealThreshold: number;
          }>,
      )
      .then((data) => {
        if (data.ok) {
          setMinDiscount(data.minDiscountPercent);
          setDraftMinDiscount(data.minDiscountPercent);
          setHotDealThreshold(data.hotDealThreshold);
          setDraftHotDealThreshold(data.hotDealThreshold);
        }
      })
      .catch((err) => {
        captureCaught(err, { scope: 'features.admin-deals.DealsMgmt', severity: 'info' });
        /* keep default */
      });
  }, []);

  async function handleSaveSettings() {
    setIsSavingSettings(true);
    setSettingsError(null);
    try {
      const body: Record<string, number> = {};
      if (draftMinDiscount !== minDiscount) body.minDiscountPercent = draftMinDiscount;
      if (draftHotDealThreshold !== hotDealThreshold) body.hotDealThreshold = draftHotDealThreshold;
      const res = await fetch('/api/admin/deal-settings', {
        method: 'PATCH',
        headers: { 'Content-Type': 'application/json', 'x-csrf-token': getCsrfToken() },
        body: JSON.stringify(body),
      });
      if (!res.ok) {
        const resBody = (await res.json().catch((err) => {
          captureCaught(err, { scope: 'features.admin-deals.DealsMgmt', severity: 'info' });
          return {};
        })) as { error?: string };
        throw new Error(resBody.error ?? 'Save failed');
      }
      setMinDiscount(draftMinDiscount);
      setHotDealThreshold(draftHotDealThreshold);
      setSettingsSaved(true);
      setTimeout(() => setSettingsSaved(false), 3000);
    } catch (err) {
      setSettingsError(err instanceof Error ? err.message : String(err));
    } finally {
      setIsSavingSettings(false);
    }
  }

  const isSettingsDirty =
    draftMinDiscount !== minDiscount || draftHotDealThreshold !== hotDealThreshold;

  // ── State filter chips ────────────────────────────────────────────────────
  const stateChips: FilterChip[] = [
    { key: 'state', value: 'PENDING_APPROVAL', label: t('state_pending_approval') },
    { key: 'state', value: 'UNDER_REVIEW', label: t('state_under_review') },
    { key: 'state', value: 'ACTIVE', label: t('state_active') },
    { key: 'state', value: 'DRAFT', label: t('state_draft') },
    { key: 'state', value: 'PAUSED', label: t('state_paused') },
    { key: 'state', value: 'SOLD_OUT', label: t('state_sold_out') },
    { key: 'state', value: 'EXPIRED', label: t('state_expired') },
    { key: 'state', value: 'REJECTED', label: t('state_rejected') },
  ];

  // ── Column definitions ────────────────────────────────────────────────────
  function renderStatePill(state: string) {
    const label = dealState.is(state)
      ? t(`state_${dealState.metaFor(state).labelKey}` as Parameters<typeof t>[0]) || state
      : state;
    const pill = (
      <Pill tone={STATE_TONE[state] ?? 'neutral'} size="sm">
        {label}
      </Pill>
    );
    const tooltipKey = STATE_TOOLTIP_KEYS[state];
    if (!tooltipKey) return pill;
    return (
      <Tooltip>
        <TooltipTrigger asChild>
          <span className="inline-flex">{pill}</span>
        </TooltipTrigger>
        <TooltipContent side="top" className="max-w-xs text-xs">
          {t(tooltipKey)}
        </TooltipContent>
      </Tooltip>
    );
  }

  const columns: ColumnDef<DealRow>[] = [
    {
      key: 'createdAt',
      label: t('col_created'),
      headerTooltip: t('col_created_tooltip'),
      render: (r) => formatDate(r.createdAt, locale),
    },
    {
      key: 'title',
      label: t('col_title'),
      render: (r) => (
        <span className="text-text-primary font-medium" data-user-displayname>
          {r.title}
        </span>
      ),
    },
    {
      key: 'vendorDisplayName',
      label: t('col_vendor'),
      render: (r) => (
        <span className="text-text-secondary" data-user-displayname>
          {r.vendorDisplayName}
        </span>
      ),
    },
    {
      key: 'dealState',
      label: t('col_state'),
      render: (r) => renderStatePill(r.dealState),
    },
    {
      key: 'originalPrice',
      label: t('col_original_price'),
      align: 'end',
      render: (r) => (
        <span className="text-text-secondary text-sm line-through">
          {formatShekelFloat(r.originalPrice)}
        </span>
      ),
    },
    {
      key: 'discountedPrice',
      label: t('col_discounted_price'),
      align: 'end',
      render: (r) => (
        <span className="text-brand-primary-700 font-medium">
          {formatShekelFloat(r.discountedPrice)}
        </span>
      ),
    },
    {
      key: 'windowStart',
      label: t('col_window'),
      render: (r) =>
        r.windowStart ? (
          formatDate(r.windowStart, locale)
        ) : (
          <span className="text-text-secondary text-sm">—</span>
        ),
    },
  ];

  const rangeFrom = total > 0 ? (page - 1) * PAGE_LIMIT + 1 : 0;
  const rangeTo = Math.min(page * PAGE_LIMIT, total);
  const rangeLabel =
    total > 0
      ? interpolate(tList('showing_x_of_y'), { from: rangeFrom, to: rangeTo, total })
      : null;

  const dealsQuery = {
    data: isInitialLoading ? undefined : { rows: data, totalPages, page },
    isLoading: isInitialLoading,
    isPending: isInitialLoading,
    isError: Boolean(error),
    error: error ? new Error(error) : null,
    refetch,
  };

  // ── Render ────────────────────────────────────────────────────────────────
  return (
    <ErrorBoundary>
      <QueryBoundary
        query={dealsQuery}
        skeleton={<AdminListPageSkeleton filterRows={2} searchFields={2} tableCols={7} />}
        errorFallback={() => (
          <ErrorState
            title={tList('error_title')}
            action={
              <Button variant="secondary" size="sm" onClick={() => refetch()}>
                {tList('retry')}
              </Button>
            }
          />
        )}
      >
        {(resolved) => (
          <AdminListPage
            busy={isRefetching}
            filterBar={
              <>
                {/* Deal settings panel */}
                <div className="bg-surface-default rounded-2xl p-4 shadow-md">
                  <h2 className="text-text-primary mb-4 text-base font-semibold">
                    {t('settings_panel_heading')}
                  </h2>
                  <div className="grid grid-cols-1 gap-4 md:grid-cols-2">
                    {/* Min-discount setting */}
                    <Row gap="2" align="center" wrap>
                      <Label
                        htmlFor="deals-min-discount-input"
                        className="shrink-0 text-sm font-medium"
                      >
                        {tAdmin('deal_settings_min_discount_label')}
                      </Label>
                      <NumberInput
                        id="deals-min-discount-input"
                        min={1}
                        max={99}
                        value={draftMinDiscount}
                        onChange={(n) => setDraftMinDiscount(Math.min(99, Math.max(1, n)))}
                        className="w-16 shrink-0"
                      />
                      <span className="text-text-secondary shrink-0 text-sm">%</span>
                      <TooltipProvider delayDuration={150}>
                        <Tooltip>
                          <TooltipTrigger asChild>
                            <Button
                              type="button"
                              variant="ghost"
                              size="sm"
                              className="shrink-0"
                              aria-label={tAdmin('deal_settings_min_discount_help')}
                            >
                              <Icon name="Info" size="sm" />
                            </Button>
                          </TooltipTrigger>
                          <TooltipContent side="top" className="max-w-xs text-xs">
                            {tAdmin('deal_settings_min_discount_help')}
                          </TooltipContent>
                        </Tooltip>
                      </TooltipProvider>
                    </Row>

                    {/* Hot deal threshold setting */}
                    <Row gap="2" align="center" wrap>
                      <Label
                        htmlFor="deals-hot-deal-input"
                        className="shrink-0 text-sm font-medium"
                      >
                        {tAdmin('deal_settings_hot_deal_label')}
                      </Label>
                      <NumberInput
                        id="deals-hot-deal-input"
                        min={1}
                        max={9999}
                        value={draftHotDealThreshold}
                        onChange={(n) => setDraftHotDealThreshold(Math.min(9999, Math.max(1, n)))}
                        className="w-20 shrink-0"
                      />
                      <span className="text-text-secondary shrink-0 text-sm">
                        {tAdmin('deal_settings_hot_deal_suffix')}
                      </span>
                      <TooltipProvider delayDuration={150}>
                        <Tooltip>
                          <TooltipTrigger asChild>
                            <Button
                              type="button"
                              variant="ghost"
                              size="sm"
                              className="shrink-0"
                              aria-label={tAdmin('deal_settings_hot_deal_help')}
                            >
                              <Icon name="Info" size="sm" />
                            </Button>
                          </TooltipTrigger>
                          <TooltipContent side="top" className="max-w-xs text-xs">
                            {tAdmin('deal_settings_hot_deal_help')}
                          </TooltipContent>
                        </Tooltip>
                      </TooltipProvider>
                    </Row>
                  </div>

                  {/* Save row */}
                  <div className="mt-4 flex items-center justify-end gap-2">
                    <Button
                      variant="primary"
                      size="sm"
                      disabled={!isSettingsDirty || isSavingSettings}
                      onClick={handleSaveSettings}
                    >
                      {tAdmin('llm_save')}
                    </Button>
                    {settingsSaved && (
                      <span className="text-success-600 text-xs">
                        {tAdmin('deal_settings_saved')}
                      </span>
                    )}
                    {settingsError && (
                      <span className="text-danger-600 text-xs">{settingsError}</span>
                    )}
                  </div>
                </div>

                {/* State filter chips with tooltips */}
                <TooltipProvider delayDuration={150}>
                  <div
                    className={cn(
                      'flex flex-wrap items-center gap-1 rounded-lg',
                      'bg-surface-raised border-border-default border px-4 py-3',
                    )}
                    role="group"
                    aria-label={t('col_state')}
                  >
                    {stateChips.map((chip) => {
                      const isActive = filters[chip.key] === chip.value;
                      const tooltipKey = STATE_TOOLTIP_KEYS[chip.value];
                      const chipButton = (
                        <Button
                          key={`${chip.key}-${chip.value}`}
                          type="button"
                          variant="ghost"
                          size="sm"
                          onClick={() => setFilter(chip.key, isActive ? '' : chip.value)}
                          aria-pressed={isActive}
                          className={cn(
                            'inline-flex items-center rounded-full px-3 py-1',
                            'text-sm font-medium',
                            'border transition-colors',
                            'focus-visible:ring-brand-primary-500 focus-visible:ring-2 focus-visible:outline-none',
                            'shadow-none',
                            isActive
                              ? 'bg-brand-primary-600 border-brand-primary-600 text-white'
                              : 'bg-surface-base text-text-secondary border-border-default hover:bg-neutral-100',
                          )}
                        >
                          {chip.label}
                        </Button>
                      );
                      if (!tooltipKey) return chipButton;
                      return (
                        <Tooltip key={`${chip.key}-${chip.value}`}>
                          <TooltipTrigger asChild>{chipButton}</TooltipTrigger>
                          <TooltipContent side="top" className="max-w-xs text-xs">
                            {t(tooltipKey)}
                          </TooltipContent>
                        </Tooltip>
                      );
                    })}
                  </div>
                </TooltipProvider>

                {rangeLabel ? (
                  <p className="text-text-secondary text-xs" aria-live="polite">
                    {rangeLabel}
                  </p>
                ) : null}

                {/* Vendor + title search inputs — single commit action */}
                <Row gap="3" wrap align="end">
                  <div className="flex min-w-44 flex-1 flex-col gap-1">
                    <Label htmlFor="deals-vendor-search">{t('filter_vendor_search')}</Label>
                    <Input
                      id="deals-vendor-search"
                      value={draftVendorSearch}
                      onChange={(e) => setDraftVendorSearch(e.target.value)}
                      placeholder={t('filter_vendor_search_placeholder')}
                      onKeyDown={(e) => {
                        if (e.key === 'Enter') {
                          setVendorSearch(draftVendorSearch);
                          setTitleSearch(draftTitleSearch);
                          setPage(1);
                        }
                      }}
                    />
                  </div>
                  <div className="flex min-w-44 flex-1 flex-col gap-1">
                    <Label htmlFor="deals-title-search">{t('filter_title_search')}</Label>
                    <Input
                      id="deals-title-search"
                      value={draftTitleSearch}
                      onChange={(e) => setDraftTitleSearch(e.target.value)}
                      placeholder={t('filter_title_search_placeholder')}
                      onKeyDown={(e) => {
                        if (e.key === 'Enter') {
                          setVendorSearch(draftVendorSearch);
                          setTitleSearch(draftTitleSearch);
                          setPage(1);
                        }
                      }}
                    />
                  </div>
                  <Button
                    variant="secondary"
                    size="sm"
                    onClick={() => {
                      setVendorSearch(draftVendorSearch);
                      setTitleSearch(draftTitleSearch);
                      setPage(1);
                    }}
                  >
                    {t('filter_apply')}
                  </Button>
                </Row>
              </>
            }
            table={
              <AdminTable<DealRow>
                columns={columns}
                rows={resolved.rows}
                rowHref={(r) => `/admin/deals/${r.id}`}
              />
            }
            pagination={
              resolved.totalPages > 1 ? (
                <Pagination
                  page={resolved.page}
                  totalPages={resolved.totalPages}
                  onPageChange={setPage}
                />
              ) : undefined
            }
          />
        )}
      </QueryBoundary>
    </ErrorBoundary>
  );
}
