/*
 * SCR-A8 규정 룰셋 버전 관리 (M18). Stitch scr_a8 이식.
 * 데이터 원천: 실 API(읽기 전용) — GET /api/admin/rulesets(요약 목록) · GET /api/admin/rulesets/{name}(규칙 전문).
 * 백엔드는 룰셋을 classpath 리소스(resources/rulesets/*.json)로 버전 관리하며 편집 엔드포인트는 없다(규정 개정=리소스 교체).
 */
import { useEffect, useMemo, useState } from 'react';
import { useQuery } from '@tanstack/react-query';
import { useTranslation } from 'react-i18next';
import type { TFunction } from 'i18next';
import { EmptyState, ErrorState, Skeleton } from '../../components/ui/States';
import { KxDataTable, type KxColumn } from '../../components/KxDataTable';
import { rulesetApi, type RulesetRule } from './adminModulesApi';
import './admin-modules.css';

export function RulesetVersionsPage() {
  const { t } = useTranslation();
  const listQ = useQuery({
    queryKey: ['admin-rulesets'],
    queryFn: () => rulesetApi.list(),
    retry: false,
  });

  const versions = listQ.data ?? [];
  const [selected, setSelected] = useState<string | null>(null);

  // 목록 로드 시 최초 파일 자동 선택(사용자 선택이 우선).
  useEffect(() => {
    if (!selected && versions.length > 0) {
      setSelected(versions[0].name);
    }
  }, [versions, selected]);

  const activeName = selected ?? versions[0]?.name ?? null;
  const current = versions.find((v) => v.name === activeName) ?? null;

  const detailQ = useQuery({
    queryKey: ['admin-ruleset', activeName],
    queryFn: () => rulesetApi.detail(activeName as string),
    enabled: !!activeName,
    retry: false,
  });

  const rules: RulesetRule[] = detailQ.data?.rules ?? [];

  const ruleColumns = useMemo<KxColumn<RulesetRule>[]>(
    () => [
      { key: 'name', header: t('ruleset.colRuleName'), value: (r) => `${r.label ?? r.code} ${r.code}`,
        render: (r) => (
          <>
            <span className="kx-adm-rulename">{r.label ?? r.code}</span>
            <span className="kx-adm-rulecode">{r.code}</span>
          </>
        ) },
      { key: 'value', header: t('ruleset.colValue'), value: (r) => formatValue(t, r),
        render: (r) => <span className="kx-adm-mono">{formatValue(t, r)}</span> },
      { key: 'logic', header: t('ruleset.colLogic'), value: (r) => formatLogic(t, r),
        render: (r) => <span className="kx-adm-muted">{formatLogic(t, r)}</span> },
      { key: 'severity', header: t('ruleset.colSeverity'), value: (r) => (r.severity === 'block' ? t('ruleset.block') : t('ruleset.warn')),
        render: (r) => (
          <span className={`kx-adm-pill kx-adm-pill--${r.severity === 'block' ? 'error' : 'warn'}`}>
            {r.severity === 'block' ? t('ruleset.block') : t('ruleset.warn')}
          </span>
        ) },
    ],
    [t],
  );

  return (
    <div className="kx-page kx-adm">
      <header className="kx-adm__head">
        <div>
          <h1 className="kx-adm__title">{t('ruleset.title')}</h1>
          <p className="kx-adm__subtitle">{t('ruleset.subtitle')}</p>
        </div>
      </header>

      <div className="kx-adm-sample-banner" role="status">
        <span className="kx-bi__degraded">{t('ruleset.readonly')}</span>
        {t('ruleset.readonlyNote')}
      </div>

      {listQ.isLoading && <RulesetSkeleton />}
      {listQ.isError && (
        <ErrorState message={t('ruleset.listError')} onRetry={() => listQ.refetch()} />
      )}

      {!listQ.isLoading && !listQ.isError && versions.length === 0 && (
        <EmptyState title={t('ruleset.noRulesets')} />
      )}

      {versions.length > 0 && (
        <div className="kx-adm-ruleset">
          {/* 좌: 버전 히스토리 */}
          <aside className="kx-adm-ruleset__versions" aria-label={t('ruleset.versionHistory')}>
            <div className="kx-adm-ruleset__vhead">
              <h2>{t('ruleset.versionHistory')}</h2>
            </div>
            <ul className="kx-adm-vlist">
              {versions.map((v) => (
                <li key={v.name}>
                  <button
                    type="button"
                    className={`kx-adm-vitem ${v.name === activeName ? 'is-active' : ''}`}
                    onClick={() => setSelected(v.name)}
                  >
                    <span className="kx-adm-vitem__top">
                      <strong>{v.version}</strong>
                      <span className="kx-adm-pill kx-adm-pill--neutral">{t('ruleset.rulesCount', { n: v.ruleCount })}</span>
                    </span>
                    <span className="kx-adm-vitem__date">
                      {v.effectiveDate ? t('ruleset.effectiveDate', { date: v.effectiveDate }) : v.name}
                    </span>
                    <ModuleDistribution dist={v.moduleDistribution} />
                  </button>
                </li>
              ))}
            </ul>
          </aside>

          {/* 우: 규칙 목록 */}
          <section className="kx-card kx-adm-ruleset__editor" aria-label={t('ruleset.ruleList')}>
            <div className="kx-adm-ruleset__ehead">
              <div>
                <h2>
                  {t('ruleset.rulesOf', { name: current?.version ?? activeName, n: rules.length })}
                </h2>
                <p className="kx-adm-muted">
                  {detailQ.data?.effectiveDate
                    ? t('ruleset.effectiveDate', { date: detailQ.data.effectiveDate })
                    : current?.name}
                </p>
              </div>
            </div>

            {detailQ.isLoading && <Skeleton height={240} radius={12} />}
            {detailQ.isError && (
              <ErrorState message={t('ruleset.detailError')} onRetry={() => detailQ.refetch()} />
            )}

            {!detailQ.isLoading && !detailQ.isError && rules.length === 0 && (
              <EmptyState
                title={t('ruleset.noRulesTitle')}
                description={t('ruleset.noRulesDesc')}
              />
            )}

            {rules.length > 0 && (
              <div className="kx-adm-rules-dt">
                <KxDataTable
                  columns={ruleColumns}
                  rows={rules}
                  rowKey={(r) => r.code}
                  csvFileName={`ruleset_${activeName ?? 'rules'}`}
                  ariaLabel={t('ruleset.ruleList')}
                />
              </div>
            )}

            {detailQ.data?.disclaimer && (
              <p className="kx-adm-disclaimer">{detailQ.data.disclaimer}</p>
            )}
          </section>
        </div>
      )}
    </div>
  );
}

function ModuleDistribution({ dist }: { dist: Record<string, number> }) {
  const entries = Object.entries(dist);
  if (entries.length === 0) return null;
  return (
    <span className="kx-adm-vitem__note">
      {entries.map(([m, n]) => `${m} ${n}`).join(' · ')}
    </span>
  );
}

/** 원문 규칙에서 표시용 수치/설정값을 유도한다(operator + threshold/min/max/unit). */
function formatValue(t: TFunction, r: RulesetRule): string {
  const unit = r.unit ?? '';
  switch (r.operator) {
    case 'lte':
      return `≤ ${fmtNum(r.threshold)}${unit}`;
    case 'gte':
      return `≥ ${fmtNum(r.threshold)}${unit}`;
    case 'eq':
      return `= ${fmtNum(r.threshold)}${unit}`;
    case 'between':
      return `${fmtNum(r.min)}–${fmtNum(r.max)}${unit}`;
    case 'isTrue':
      return t('ruleset.required');
    case 'excludesAll':
      return (r.forbidden ?? []).join(' · ');
    case 'lteHall':
      return r.hallLimits
        ? Object.entries(r.hallLimits)
            .map(([h, v]) => `${h} ${v}`)
            .join(' · ') + unit
        : t('ruleset.perHall', { unit });
    default:
      return r.threshold != null ? `${fmtNum(r.threshold)}${unit}` : '—';
  }
}

/** 원문 규칙에서 논리/요구사항 설명을 유도한다(metric·requiresDocument·note). */
function formatLogic(t: TFunction, r: RulesetRule): string {
  const parts: string[] = [];
  if (r.metric) parts.push(r.metric);
  if (r.requiresDocument) parts.push(t('ruleset.docNeeded', { doc: r.requiresDocument }));
  if (r.note) parts.push(r.note);
  return parts.length > 0 ? parts.join(' · ') : (r.group ?? '—');
}

function fmtNum(n: number | null | undefined): string {
  return n == null ? '—' : String(n);
}

function RulesetSkeleton() {
  return (
    <div aria-hidden="true" style={{ display: 'grid', gap: 16 }}>
      <Skeleton height={48} radius={12} />
      <Skeleton height={320} radius={12} />
    </div>
  );
}
