import { useMemo } from 'react';
import { useQuery } from '@tanstack/react-query';
import {
  Area,
  AreaChart,
  CartesianGrid,
  Cell,
  Pie,
  PieChart,
  ResponsiveContainer,
  Tooltip,
  XAxis,
  YAxis,
} from 'recharts';
import { AiLabel } from '../../components/ui/Badge';
import { Button } from '../../components/ui/Button';
import { EmptyState, ErrorState, Skeleton } from '../../components/ui/States';
import { KxDataTable, type KxColumn } from '../../components/KxDataTable';
import { IconDocument, IconDownload, IconSpark, IconTag, IconTrendUp, IconUsers } from '../../components/ui/icons';
import { ApiRequestError } from '../../api/client';
import { useResolvedEventId } from '../../hooks/useResolvedEventId';
import { CHART } from '../chartColors';
import {
  CHECKIN_LABEL,
  REG_FORMS,
  REG_TREND,
  REG_TYPES,
  REG_TYPE_LABEL,
  REGISTRANTS,
  type CheckinState,
  type RegVisitorType,
} from './sampleVisitor';
import { visitorApi, type VisitorSummaryDto, type VisitorListItemDto } from './visitorApi';
import './visitor.css';

/*
 * SCR-30 관람객 등록 관리 대시보드 (M10·M11). Stitch scr_30_visitor_reg_dashboard 이식.
 * 정상 경로: GET /api/events/{eventId}/visitors/summary + /visitors (실 집계·마스킹 목록).
 * 폴백: NETWORK/NOT_FOUND/NOT_IMPLEMENTED 시에만 sampleVisitor 로 강등("오프라인 — 샘플" 표기).
 * ★ 보안 불변: 관람객 이름·연락처·이메일은 서버 마스킹 필드만 소비(원문 미노출, N2/R10).
 */
export function VisitorRegistrationDashboardPage() {
  const eventId = useResolvedEventId();

  const summaryQ = useQuery({
    queryKey: ['visitor-summary', eventId],
    queryFn: () => visitorApi.summary(eventId as string),
    enabled: !!eventId,
    retry: false,
  });
  const listQ = useQuery({
    queryKey: ['visitor-list', eventId],
    queryFn: () => visitorApi.visitors(eventId as string, 0, 20),
    enabled: !!eventId,
    retry: false,
  });

  const degraded = isDegradable(summaryQ.error) || isDegradable(listQ.error);
  const summary: VisitorSummaryDto | null = summaryQ.data ?? (degraded ? SAMPLE_SUMMARY : null);
  const rows: VisitorListItemDto[] =
    listQ.data?.items ?? (degraded ? SAMPLE_ROWS : []);
  const hardError = (summaryQ.isError && !degraded) || (listQ.isError && !degraded);

  const columns = useMemo<KxColumn<VisitorListItemDto>[]>(
    () => [
      { key: 'name', header: '이름', value: (r) => r.nameMasked,
        render: (r) => (
          <span className="kx-vis__person">
            <span className="kx-vis__avatar" aria-hidden="true">{initialOf(r.nameMasked)}</span>
            {r.nameMasked}
          </span>
        ) },
      { key: 'type', header: '유형', value: (r) => typeLabelOf(r.type), render: (r) => <TypePill type={r.type} /> },
      { key: 'company', header: '소속', value: (r) => r.company ?? '', render: (r) => r.company ?? '-' },
      { key: 'registeredAt', header: '등록일', value: (r) => r.registeredAt ?? '',
        render: (r) => <span className="tnum">{r.registeredAt ?? '-'}</span> },
      { key: 'checkin', header: '체크인', value: (r) => checkinLabelOf(r.checkin), render: (r) => <CheckinPill state={r.checkin} /> },
      { key: 'badge', header: '배지', value: (r) => (r.badgeIssued ? '발급' : '미발급'),
        render: (r) => (r.badgeIssued ? (
          <span className="kx-vis__badge-issued" title="배지 발급 완료">
            <QrGlyph size={16} /> 발급
          </span>
        ) : (
          <span className="kx-vis__badge-none">미발급</span>
        )) },
    ],
    [],
  );

  return (
    <div className="kx-vis">
      <header className="kx-vis__head">
        <div>
          <h1 className="kx-vis__title">관람객 데이터 관리</h1>
          <p className="kx-vis__subtitle">사전등록 · 체크인 · 배지 발급 현황</p>
        </div>
        <div className="kx-vis__head-actions">
          {degraded && (
            <span className="kx-vis__degraded" title="집계 API 미연결 — 시연 데이터">오프라인 — 샘플</span>
          )}
          <Button variant="secondary" leadingIcon={<IconDownload size={16} />}>
            엑셀 다운로드
          </Button>
        </div>
      </header>

      {!eventId && (
        <EmptyState title="행사를 선택해 주세요" description="관람객 데이터를 조회할 행사가 지정되지 않았습니다." />
      )}

      {eventId && summaryQ.isLoading && !degraded && <VisSkeleton />}

      {hardError && (
        <ErrorState message="관람객 집계를 불러오지 못했습니다." onRetry={() => { summaryQ.refetch(); listQ.refetch(); }} />
      )}

      {summary && (
        <>
          {/* KPI 밴드 */}
          <section className="kx-vis__kpis" aria-label="관람객 핵심 지표">
            {summary.kpis.map((k) => (
              <div key={k.label} className={`kx-kpi ${k.ai ? 'kx-kpi--ai' : ''}`}>
                <span className="kx-kpi__label">
                  {k.label}
                  {k.ai && (
                    <span className="kx-kpi__ai" aria-hidden="true">
                      <IconSpark size={12} />
                    </span>
                  )}
                </span>
                <strong className="kx-kpi__value tnum">{k.value}</strong>
                {k.delta && (
                  <span className={`kx-delta kx-delta--${k.trend === 'down' ? 'down' : 'up'}`}>
                    {k.trend === 'down' ? '▼' : '▲'} {k.delta}
                  </span>
                )}
                {k.sub && <span className="kx-kpi__sub">{k.sub}</span>}
              </div>
            ))}
          </section>

          {/* 추이(2/3) + 폼·배지(1/3) */}
          <div className="kx-vis__split">
            <section className="kx-card kx-vis__trend" aria-label="등록·체크인 추이">
              <div className="kx-card__head">
                <h2><IconTrendUp className="kx-title-ic" size={18} />등록 · 체크인 추이</h2>
                <ul className="kx-vis__legend" aria-hidden="true">
                  <li>
                    <span className="kx-dot" style={{ background: CHART.primary600 }} /> 사전등록
                  </li>
                  <li>
                    <span className="kx-dot" style={{ background: CHART.slate }} /> 체크인
                  </li>
                </ul>
              </div>
              <p className="kx-card__hint">누적 사전등록·체크인 인원입니다.</p>
              <div className="kx-vis__chart">
                <ResponsiveContainer width="100%" height={300}>
                  <AreaChart data={summary.trend} margin={{ top: 8, right: 12, bottom: 0, left: -8 }}>
                    <defs>
                      <linearGradient id="gPreReg" x1="0" y1="0" x2="0" y2="1">
                        <stop offset="0%" stopColor={CHART.primary600} stopOpacity={0.35} />
                        <stop offset="100%" stopColor={CHART.primary600} stopOpacity={0.02} />
                      </linearGradient>
                      <linearGradient id="gCheckIn" x1="0" y1="0" x2="0" y2="1">
                        <stop offset="0%" stopColor={CHART.slate} stopOpacity={0.25} />
                        <stop offset="100%" stopColor={CHART.slate} stopOpacity={0.02} />
                      </linearGradient>
                    </defs>
                    <CartesianGrid stroke={CHART.neutral200} strokeDasharray="3 3" vertical={false} />
                    <XAxis dataKey="label" tick={{ fontSize: 12, fill: CHART.slate }} tickLine={false} axisLine={{ stroke: CHART.neutral200 }} />
                    <YAxis tick={{ fontSize: 12, fill: CHART.slate }} tickLine={false} axisLine={false} width={48} tickFormatter={(v) => (v as number >= 1000 ? `${Math.round((v as number) / 1000)}천` : String(v))} />
                    <Tooltip
                      contentStyle={TOOLTIP_STYLE}
                      formatter={(value, name) => [`${(value as number).toLocaleString()}명`, name]}
                    />
                    <Area type="monotone" dataKey="preReg" name="사전등록" stroke={CHART.primary600} fill="url(#gPreReg)" strokeWidth={2} />
                    <Area type="monotone" dataKey="checkIn" name="체크인" stroke={CHART.slate} fill="url(#gCheckIn)" strokeWidth={2} />
                  </AreaChart>
                </ResponsiveContainer>
              </div>

              <div className="kx-vis__donut-row">
                <div className="kx-vis__donut">
                  <ResponsiveContainer width="100%" height={140}>
                    <PieChart>
                      <Pie data={summary.types} dataKey="value" nameKey="name" cx="50%" cy="50%" innerRadius={38} outerRadius={58} paddingAngle={2} strokeWidth={0}>
                        {summary.types.map((s) => (
                          <Cell key={s.name} fill={s.color} />
                        ))}
                      </Pie>
                      <Tooltip contentStyle={TOOLTIP_STYLE} formatter={(value, name) => [`${value}%`, name]} />
                    </PieChart>
                  </ResponsiveContainer>
                </div>
                <div className="kx-vis__donut-legend">
                  <p className="kx-vis__donut-title">등록 유형 분포</p>
                  <ul>
                    {summary.types.map((s) => (
                      <li key={s.name}>
                        <span className="kx-dot" style={{ background: s.color }} />
                        {s.name}
                        <strong className="tnum">{s.value}%</strong>
                      </li>
                    ))}
                  </ul>
                </div>
              </div>
            </section>

            <aside className="kx-vis__aside">
              <section className="kx-card" aria-label="등록 폼 관리">
                <div className="kx-card__head">
                  <h2><IconDocument className="kx-title-ic" size={18} />등록 폼 관리</h2>
                </div>
                <ul className="kx-vis__forms">
                  {summary.forms.map((f) => (
                    <li key={f.id} className="kx-vis__form">
                      <span className="kx-vis__form-name">
                        <span className={`kx-dot ${f.active ? 'is-on' : 'is-off'}`} />
                        {f.name}
                      </span>
                      <span className="kx-vis__form-count tnum">{f.count.toLocaleString()}명</span>
                      <span className={`kx-vis__form-state ${f.active ? 'is-on' : ''}`}>
                        {f.active ? '활성' : '비활성'}
                      </span>
                    </li>
                  ))}
                </ul>
                <Button variant="ai" block leadingIcon={<IconSpark size={16} />}>
                  AI 폼빌더 시작
                </Button>
                <p className="kx-vis__ai-note">
                  <AiLabel>AI 폼빌더</AiLabel> 세그먼트 성향에 맞춘 등록 문항을 자동 제안합니다.
                </p>
              </section>

              <section className="kx-card" aria-label="배지 템플릿">
                <div className="kx-card__head">
                  <h2><IconTag className="kx-title-ic" size={18} />배지 템플릿</h2>
                </div>
                <div className="kx-vis__badge-preview">
                  <div className="kx-badgecard">
                    <div className="kx-badgecard__top">KINTEX VISITOR</div>
                    <div className="kx-badgecard__qr" aria-hidden="true">
                      <QrGlyph />
                    </div>
                    <p className="kx-badgecard__name">김 **</p>
                    <p className="kx-badgecard__org">Samsung Electronics</p>
                    <div className="kx-badgecard__foot">
                      <span className="kx-badgecard__tag">BUYER</span>
                      <span className="kx-badgecard__no tnum">2026-V01</span>
                    </div>
                  </div>
                </div>
                <p className="kx-vis__ai-note">배지 미리보기는 마스킹 표기 템플릿입니다(실 데이터 아님).</p>
                <Button variant="secondary" block>배지 편집</Button>
              </section>
            </aside>
          </div>

          {/* 등록자 명단 */}
          <section className="kx-card kx-vis__table-card" aria-label="전체 신청자 명단">
            <div className="kx-card__head">
              <h2><IconUsers className="kx-title-ic" size={18} />전체 신청자 명단</h2>
              <span className="kx-vis__pii-note">개인정보 보호 · 이름 마스킹 표기</span>
            </div>
            <KxDataTable
              columns={columns}
              rows={rows}
              rowKey={(r) => r.id}
              searchPlaceholder="이름·소속 검색"
              csvFileName={`visitors_${eventId}`}
              ariaLabel="전체 신청자 명단"
              emptyTitle="등록자가 없습니다"
              emptyDescription="사전등록이 접수되면 이 곳에 표시됩니다."
            />
          </section>
        </>
      )}
    </div>
  );
}

function VisSkeleton() {
  return (
    <div style={{ display: 'grid', gap: 16 }}>
      <Skeleton height={92} radius={12} />
      <Skeleton height={360} radius={12} />
      <Skeleton height={260} radius={12} />
    </div>
  );
}

const TOOLTIP_STYLE = {
  fontSize: 12,
  borderRadius: 8,
  border: '1px solid #E4E7EC',
  boxShadow: '0 4px 12px rgba(16,24,40,0.1)',
} as const;

/** 마스킹 이름 첫 글자(아바타). */
function initialOf(nameMasked: string): string {
  return nameMasked ? nameMasked.charAt(0) : '?';
}

const KNOWN_TYPES: RegVisitorType[] = ['visitor', 'buyer', 'vip'];
/** 유형 코드 → 표시 라벨(검색·CSV·정렬 값). */
function typeLabelOf(type: string): string {
  const t = (KNOWN_TYPES as string[]).includes(type) ? (type as RegVisitorType) : 'visitor';
  return REG_TYPE_LABEL[t];
}
function TypePill({ type }: { type: string }) {
  const t = (KNOWN_TYPES as string[]).includes(type) ? (type as RegVisitorType) : 'visitor';
  return <span className={`kx-vis__type is-${t}`}>{REG_TYPE_LABEL[t]}</span>;
}

const KNOWN_CHECKIN: CheckinState[] = ['done', 'waiting', 'cancelled'];
/** 체크인 코드 → 표시 라벨(검색·CSV·정렬 값). */
function checkinLabelOf(state: string): string {
  const s = (KNOWN_CHECKIN as string[]).includes(state) ? (state as CheckinState) : 'waiting';
  return CHECKIN_LABEL[s];
}
function CheckinPill({ state }: { state: string }) {
  const s = (KNOWN_CHECKIN as string[]).includes(state) ? (state as CheckinState) : 'waiting';
  return (
    <span className={`kx-vis__checkin is-${s}`}>
      <span className="kx-dot" /> {CHECKIN_LABEL[s]}
    </span>
  );
}

/** 폴백 요약(오프라인 강등 시) — sampleVisitor 파생. */
const SAMPLE_SUMMARY: VisitorSummaryDto = {
  kpis: [
    { label: '사전등록', value: '12,480' },
    { label: '체크인', value: '8,210', sub: '진행률 65.7%' },
    { label: '노쇼/취소', value: '1,540', trend: 'down', sub: '12%' },
    { label: '바이어 비중', value: '34%', sub: '목표 30%' },
    { label: '리드 생성', value: '2,140', ai: true, sub: 'AI 스코어링 대상' },
  ],
  trend: REG_TREND.map((p) => ({ label: p.label, preReg: p.preReg, checkIn: p.checkIn })),
  types: REG_TYPES.map((t) => ({ name: t.name, value: t.value, color: t.color })),
  forms: REG_FORMS.map((f) => ({ id: f.id, name: f.name, active: f.active, count: f.count })),
};

/** 폴백 등록자 목록(오프라인 강등 시). */
const SAMPLE_ROWS: VisitorListItemDto[] = REGISTRANTS.map((r) => ({
  id: r.id,
  nameMasked: r.nameMasked,
  type: r.type,
  company: r.company,
  registeredAt: r.registeredAt,
  checkin: r.checkin,
  badgeIssued: r.badgeIssued,
}));

function isDegradable(error: unknown): boolean {
  return (
    error instanceof ApiRequestError &&
    (error.code === 'NETWORK' || error.code === 'NOT_FOUND' || error.code === 'NOT_IMPLEMENTED')
  );
}

/** QR 코드 글리프 (선 SVG, 장식용). */
function QrGlyph({ size = 40 }: { size?: number }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
      <path d="M3 3h7v7H3V3zm2 2v3h3V5H5zm-2 9h7v7H3v-7zm2 2v3h3v-3H5zM14 3h7v7h-7V3zm2 2v3h3V5h-3zM14 14h3v3h-3v-3zm4 0h3v3h-3v-3zm-4 4h3v3h-3v-3zm4 0h3v3h-3v-3z" />
    </svg>
  );
}
