import { useMemo, useState } from 'react';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { useTranslation } from 'react-i18next';
import { ApiRequestError } from '../../api/client';
import { Button } from '../../components/ui/Button';
import { EmptyState, ErrorState, Skeleton } from '../../components/ui/States';
import { IconBlock, IconCheckCircle, IconGrid, IconSettlement } from '../../components/ui/icons';
import { useResolvedEventId } from '../../hooks/useResolvedEventId';
import { boothSalesApi } from './boothSalesApi';
import type { BoothSaleStatus, BoothSaleUnit } from './boothSalesApi';
import './boothsales.css';

/*
 * SCR /booth-sales — F005 부스 판매 인벤토리 + F006 온라인 셀프 선택·판매.
 * 기존 M2 booth 좌표를 소비하는 판매 상태 오버레이(available|held|sold|blocked)를 심플 그리드로 표시한다.
 * - 참가업체: available·본인 hold 부스만 노출 → hold(선점) → 구매 확정. 이중 hold 는 409 토스트.
 * - 주최자/홀매니저: 전 상태 + blocked 전환·판매가 override·M9 정산 청구 생성(settle) 연계.
 * ★ 금액은 서버 계산 권위 — 표시만 한다(재계산 없음).
 */

const WON = new Intl.NumberFormat('ko-KR');

const STATUS_ORDER: BoothSaleStatus[] = ['available', 'held', 'sold', 'blocked'];

function isConflict(err: unknown): boolean {
  return err instanceof ApiRequestError && err.code === 'CONFLICT';
}

export function BoothSalesPage() {
  const { t } = useTranslation();
  const eventId = useResolvedEventId();
  const qc = useQueryClient();
  const [hallFilter, setHallFilter] = useState<string>('all');
  const [toast, setToast] = useState<{ tone: 'ok' | 'err'; msg: string } | null>(null);

  const invQ = useQuery({
    queryKey: ['booth-sales', 'inventory', eventId],
    queryFn: () => boothSalesApi.inventory(eventId as string),
    enabled: !!eventId,
    retry: false,
  });

  const inv = invQ.data;
  const canManage = inv?.canManage ?? false;

  const flash = (tone: 'ok' | 'err', msg: string) => {
    setToast({ tone, msg });
    window.setTimeout(() => setToast(null), 3200);
  };
  const invalidate = () => qc.invalidateQueries({ queryKey: ['booth-sales', 'inventory', eventId] });

  const holdM = useMutation({
    mutationFn: (b: BoothSaleUnit) => boothSalesApi.hold(eventId as string, b.boothId),
    onSuccess: () => { invalidate(); flash('ok', t('boothsales.heldToast')); },
    onError: (e) => flash('err', isConflict(e) ? t('boothsales.holdConflict') : t('boothsales.actionFail')),
  });
  const purchaseM = useMutation({
    mutationFn: (b: BoothSaleUnit) => boothSalesApi.purchase(eventId as string, b.boothId),
    onSuccess: () => { invalidate(); flash('ok', t('boothsales.purchasedToast')); },
    onError: (e) => flash('err', isConflict(e) ? t('boothsales.purchaseConflict') : t('boothsales.actionFail')),
  });
  const releaseM = useMutation({
    mutationFn: (b: BoothSaleUnit) => boothSalesApi.release(eventId as string, b.boothId),
    onSuccess: () => { invalidate(); flash('ok', t('boothsales.releasedToast')); },
    onError: () => flash('err', t('boothsales.actionFail')),
  });
  const blockM = useMutation({
    mutationFn: (v: { b: BoothSaleUnit; blocked: boolean }) =>
      boothSalesApi.block(eventId as string, v.b.boothId, v.blocked),
    onSuccess: () => { invalidate(); flash('ok', t('boothsales.blockToast')); },
    onError: (e) => flash('err', isConflict(e) ? t('boothsales.blockConflict') : t('boothsales.actionFail')),
  });
  const priceM = useMutation({
    mutationFn: (v: { b: BoothSaleUnit; price: number | null }) =>
      boothSalesApi.price(eventId as string, v.b.boothId, v.price),
    onSuccess: () => { invalidate(); flash('ok', t('boothsales.priceToast')); },
    onError: () => flash('err', t('boothsales.actionFail')),
  });
  const settleM = useMutation({
    mutationFn: () => boothSalesApi.settle(eventId as string),
    onSuccess: (r) => flash('ok', t('boothsales.settleToast', { created: r.created, skipped: r.skipped })),
    onError: () => flash('err', t('boothsales.settleFail')),
  });

  const halls = useMemo(() => {
    const map = new Map<string, string>();
    (inv?.units ?? []).forEach((u) => map.set(u.hallId, u.hallLabel));
    return Array.from(map.entries()).map(([id, label]) => ({ id, label }));
  }, [inv]);

  const units = useMemo(() => {
    const list = (inv?.units ?? []).filter((u) => hallFilter === 'all' || u.hallId === hallFilter);
    return [...list].sort(
      (a, b) =>
        STATUS_ORDER.indexOf(a.status) - STATUS_ORDER.indexOf(b.status) ||
        (a.boothNo ?? '').localeCompare(b.boothNo ?? ''),
    );
  }, [inv, hallFilter]);

  const onPrice = (b: BoothSaleUnit) => {
    const raw = window.prompt(t('boothsales.pricePrompt'), String(b.unitPrice));
    if (raw === null) return;
    const trimmed = raw.trim();
    if (trimmed === '') { priceM.mutate({ b, price: null }); return; } // 빈값 = 파생가 복원
    const n = Number(trimmed.replace(/[^0-9]/g, ''));
    if (!Number.isFinite(n) || n < 0) { flash('err', t('boothsales.priceInvalid')); return; }
    priceM.mutate({ b, price: n });
  };

  if (!eventId) {
    return (
      <div className="kx-bsales">
        <div className="kx-card">
          <EmptyState title={t('boothsales.noEventTitle')} description={t('boothsales.noEventDesc')} />
        </div>
      </div>
    );
  }

  return (
    <div className="kx-bsales">
      <header className="kx-bsales__head">
        <div>
          <h1 className="kx-bsales__title">{t('boothsales.title')}</h1>
          <p className="kx-bsales__subtitle">
            {canManage ? t('boothsales.subtitleManager') : t('boothsales.subtitleExhibitor')}
          </p>
        </div>
        {canManage && (
          <Button onClick={() => settleM.mutate()} disabled={settleM.isPending}>
            <IconSettlement size={16} /> {settleM.isPending ? t('boothsales.settling') : t('boothsales.settle')}
          </Button>
        )}
      </header>

      {inv && (
        <div className="kx-bsales__summary" aria-label={t('boothsales.summaryAria')}>
          <StatChip tone="available" label={t('boothsales.stAvailable')} n={inv.available} />
          <StatChip tone="held" label={t('boothsales.stHeld')} n={inv.held} />
          <StatChip tone="sold" label={t('boothsales.stSold')} n={inv.sold} />
          {canManage && <StatChip tone="blocked" label={t('boothsales.stBlocked')} n={inv.blocked} />}
          <span className="kx-bsales__rate">
            {t('boothsales.rate', { rate: WON.format(inv.ratePerM2), ver: inv.rulesetVersion })}
          </span>
        </div>
      )}

      <div className="kx-bsales__toolbar">
        <select
          className="kx-select"
          aria-label={t('boothsales.hallFilter')}
          value={hallFilter}
          onChange={(e) => setHallFilter(e.target.value)}
        >
          <option value="all">{t('boothsales.allHalls')}</option>
          {halls.map((h) => (
            <option key={h.id} value={h.id}>{h.label}</option>
          ))}
        </select>
      </div>

      {toast && (
        <div className={`kx-bsales__toast is-${toast.tone}`} role="status">{toast.msg}</div>
      )}

      {invQ.isLoading ? (
        <div className="kx-bsales__grid" aria-busy="true">
          {Array.from({ length: 8 }).map((_, i) => (
            <div key={i} className="kx-boothcard" aria-hidden="true">
              <Skeleton height={16} width="55%" />
              <Skeleton height={28} width="70%" />
              <Skeleton height={14} width="40%" />
            </div>
          ))}
        </div>
      ) : invQ.isError ? (
        <ErrorState message={t('boothsales.loadError')} onRetry={() => invQ.refetch()} />
      ) : units.length === 0 ? (
        <div className="kx-card">
          <EmptyState
            title={t('boothsales.emptyTitle')}
            description={canManage ? t('boothsales.emptyManage') : t('boothsales.emptyExhibitor')}
          />
        </div>
      ) : (
        <div className="kx-bsales__grid">
          {units.map((b) => (
            <BoothCard
              key={b.boothId}
              b={b}
              canManage={canManage}
              busy={holdM.isPending || purchaseM.isPending || releaseM.isPending || blockM.isPending}
              onHold={() => holdM.mutate(b)}
              onPurchase={() => purchaseM.mutate(b)}
              onRelease={() => releaseM.mutate(b)}
              onBlock={(blocked) => blockM.mutate({ b, blocked })}
              onPrice={() => onPrice(b)}
            />
          ))}
        </div>
      )}
    </div>
  );
}

function StatChip({ tone, label, n }: { tone: string; label: string; n: number }) {
  return (
    <span className={`kx-bsales__stat is-${tone}`}>
      <strong className="tnum">{n}</strong> {label}
    </span>
  );
}

function BoothCard({
  b, canManage, busy, onHold, onPurchase, onRelease, onBlock, onPrice,
}: {
  b: BoothSaleUnit;
  canManage: boolean;
  busy: boolean;
  onHold: () => void;
  onPurchase: () => void;
  onRelease: () => void;
  onBlock: (blocked: boolean) => void;
  onPrice: () => void;
}) {
  const { t } = useTranslation();
  return (
    <article className={`kx-boothcard is-${b.status}`}>
      <div className="kx-boothcard__top">
        <span className="kx-boothcard__no"><IconGrid size={14} /> {b.boothNo ?? b.boothId}</span>
        <span className={`kx-boothstatus is-${b.status}`}>{t(`boothsales.status.${b.status}`)}</span>
      </div>
      <div className="kx-boothcard__price tnum">{WON.format(b.unitPrice)}<span className="kx-boothcard__won">{t('boothsales.wonUnit')}</span></div>
      <ul className="kx-boothcard__meta">
        <li>{t('boothsales.hallLabel')}: {b.hallLabel}</li>
        <li className="tnum">{t('boothsales.areaLabel')}: {b.areaM2.toLocaleString()}㎡</li>
        {b.status === 'sold' && b.soldToCompany && <li>{t('boothsales.soldTo', { c: b.soldToCompany })}</li>}
      </ul>

      <div className="kx-boothcard__actions">
        {/* 참가업체 셀프 판매 흐름 */}
        {!canManage && b.status === 'available' && (
          <Button onClick={onHold} disabled={busy}>{t('boothsales.hold')}</Button>
        )}
        {!canManage && b.status === 'held' && b.heldByMe && (
          <>
            <Button onClick={onPurchase} disabled={busy}>
              <IconCheckCircle size={14} /> {t('boothsales.purchase')}
            </Button>
            <Button variant="ghost" onClick={onRelease} disabled={busy}>{t('boothsales.release')}</Button>
          </>
        )}

        {/* 주최자 관리 흐름 */}
        {canManage && (
          <>
            <Button variant="secondary" onClick={onPrice} disabled={busy}>{t('boothsales.setPrice')}</Button>
            {b.status !== 'sold' && b.status !== 'blocked' && (
              <Button variant="ghost" onClick={() => onBlock(true)} disabled={busy}>
                <IconBlock size={14} /> {t('boothsales.block')}
              </Button>
            )}
            {b.status === 'blocked' && (
              <Button variant="ghost" onClick={() => onBlock(false)} disabled={busy}>{t('boothsales.unblock')}</Button>
            )}
          </>
        )}
      </div>
    </article>
  );
}
