/*
 * SCR-P3 공개 인터랙티브 플로어플랜 (M12·M2) — 비로그인 공개.
 * design.md §3B. 좌: 검색/필터 + 부스 목록(비시각 대안 N1) / 우: 인터랙티브 맵 + 팝오버 + 범례.
 * 데이터: GET /api/public/events/{eventId}/floorplan (부스번호·업체명·상태·중심점).
 */
import { useEffect, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useParams } from 'react-router-dom';
import { PublicShell } from './PublicShell';
import { publicApi, type PublicFloorplan, type PublicFloorplanBooth } from './publicApi';
import { errorMessage } from './publicFormat';
import {
  IconSearch,
  IconChevronRight,
  IconClose,
  IconArrowRight,
  IconZoomIn,
  IconZoomOut,
  IconReset,
  IconTarget,
} from './publicIcons';

/** boothType 원문(assembled|independent|corner|island 등) → i18n 키. */
const TYPE_I18N: Record<string, string> = {
  assembled: 'floorplan.type.assembled',
  independent: 'floorplan.type.independent',
  corner: 'floorplan.type.corner',
  island: 'floorplan.type.island',
};

export function PublicFloorplanPage() {
  const { t } = useTranslation();
  const { eventId } = useParams<{ eventId: string }>();
  // boothType → 표시 라벨(번역). 알 수 없는 값은 원문 유지.
  const typeLabel = (bt: string | null | undefined) =>
    bt ? (TYPE_I18N[bt] ? t(TYPE_I18N[bt]) : bt) : t('floorplan.type.default');
  const [query, setQuery] = useState('');
  const [cat, setCat] = useState<string | null>(null);
  const [selected, setSelected] = useState<PublicFloorplanBooth | null>(null);
  const [scale, setScale] = useState(1);
  const [hallId, setHallId] = useState<string>('all');

  const [data, setData] = useState<PublicFloorplan | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState('');

  useEffect(() => {
    if (!eventId) return;
    let alive = true;
    setLoading(true);
    publicApi
      .getFloorplan(eventId)
      .then((d) => {
        if (alive) {
          setData(d);
          setError('');
        }
      })
      .catch((e) => alive && setError(errorMessage(e)))
      .finally(() => alive && setLoading(false));
    return () => {
      alive = false;
    };
  }, [eventId]);

  const booths = useMemo(() => data?.booths ?? [], [data]);
  const halls = data?.halls ?? [];

  // 존/유형 필터 후보 = 데이터에 존재하는 boothType 집합
  const categories = useMemo(
    () => Array.from(new Set(booths.map((b) => typeLabel(b.boothType)))).slice(0, 8),
    [booths],
  );

  const scoped = useMemo(
    () => (hallId === 'all' ? booths : booths.filter((b) => b.hallLabel === hallId)),
    [booths, hallId],
  );

  const filtered = useMemo(() => {
    return scoped.filter((b) => {
      const q = query.trim();
      const name = b.companyName ?? '';
      const code = b.boothNo ?? '';
      const matchQ = !q || name.includes(q) || code.includes(q);
      const matchC = !cat || typeLabel(b.boothType) === cat;
      return matchQ && matchC;
    });
  }, [scoped, query, cat]);

  const boothKey = (b: PublicFloorplanBooth) => `${b.hallLabel ?? ''}#${b.boothNo ?? ''}`;

  const boothClass = (b: PublicFloorplanBooth) => {
    let c = 'kxp-booth';
    if (b.status === 'reserved') c += ' kxp-booth--reserved';
    if (selected && boothKey(selected) === boothKey(b)) c += ' is-selected';
    return c;
  };

  return (
    <PublicShell active="visit" cta={t('ticket.viewPurchase')}>
      <div className="kxp-fp">
        {/* 좌측 검색/필터/목록 */}
        <aside className="kxp-fp__side" aria-label={t('floorplan.sideAria')}>
          <div className="kxp-fp__filters">
            <h2>{t('floorplan.filtersTitle')}</h2>
            <div className="kxp-fp__searchbox">
              <IconSearch width={18} height={18} />
              <input
                type="search"
                value={query}
                onChange={(e) => setQuery(e.target.value)}
                placeholder={t('floorplan.searchPh')}
                aria-label={t('floorplan.searchAria')}
              />
            </div>
            {categories.length > 0 && (
              <div>
                <p className="kxp-fp__label">{t('floorplan.typeFilter')}</p>
                <div className="kxp-fp__chips">
                  {categories.map((c) => (
                    <button
                      key={c}
                      type="button"
                      className={`kxp-fp__chip${cat === c ? ' is-active' : ''}`}
                      aria-pressed={cat === c}
                      onClick={() => setCat(cat === c ? null : c)}
                    >
                      {c}
                    </button>
                  ))}
                </div>
              </div>
            )}
            {halls.length > 0 && (
              <div>
                <p className="kxp-fp__label">{t('floorplan.hallSelect')}</p>
                <select
                  className="kxp-select"
                  aria-label={t('floorplan.hallSelect')}
                  value={hallId}
                  onChange={(e) => setHallId(e.target.value)}
                >
                  <option value="all">{t('floorplan.allHalls')}</option>
                  {halls.map((h) => (
                    <option key={h.hallId} value={h.label}>
                      {h.label}
                    </option>
                  ))}
                </select>
              </div>
            )}
          </div>

          <div className="kxp-fp__list" aria-label={t('floorplan.listAria')}>
            {loading && <p className="kxp-empty" role="status">{t('floorplan.loading')}</p>}
            {!loading && error && (
              <p className="kxp-empty" role="alert" style={{ color: 'var(--color-error)' }}>
                {error}
              </p>
            )}
            {!loading && !error && (
              <>
                <p className="kxp-fp__listhint">{t('floorplan.searchResults', { count: filtered.length })}</p>
                {filtered.length === 0 && <p className="kxp-empty">{t('floorplan.noMatch')}</p>}
                {filtered.map((b) => (
                  <button
                    key={boothKey(b)}
                    type="button"
                    className={`kxp-fp__row${
                      b.status === 'reserved' ? ' kxp-fp__row--reserved' : ''
                    }${selected && boothKey(selected) === boothKey(b) ? ' is-active' : ''}`}
                    onClick={() => setSelected(b)}
                  >
                    <span>
                      <span className="kxp-fp__row-code">{b.boothNo ?? '—'}</span>
                      <span className="kxp-fp__row-name">
                        {b.companyName ?? (b.status === 'reserved' ? t('floorplan.reservedBooth') : t('floorplan.availableBooth'))}
                      </span>
                      <span className="kxp-fp__row-cat">
                        {typeLabel(b.boothType)}
                        {b.hallLabel ? ` · ${b.hallLabel}` : ''}
                      </span>
                    </span>
                    <IconChevronRight width={18} height={18} />
                  </button>
                ))}
              </>
            )}
          </div>
        </aside>

        {/* 우측 인터랙티브 맵 */}
        <section className="kxp-fp__stage" aria-label={t('floorplan.stageAria')}>
          <div className="kxp-fp__canvaswrap">
            <div
              className="kxp-fp__canvas"
              style={{ transform: `scale(${scale})` }}
              role="group"
              aria-label={t('floorplan.boothLayoutAria')}
            >
              {scoped.map((b, i) => (
                <button
                  key={`${boothKey(b)}-${i}`}
                  type="button"
                  className={boothClass(b)}
                  onClick={() => setSelected(b)}
                  aria-label={t('floorplan.boothAria', { no: b.boothNo ?? '', name: b.companyName ?? '' })}
                >
                  {b.boothNo ?? '—'}
                  {b.status === 'reserved' && <span className="kxp-booth__badge">R</span>}
                </button>
              ))}
              {!loading && scoped.length === 0 && (
                <p className="kxp-empty" style={{ gridColumn: '1 / -1' }}>
                  {error ? t('floorplan.loadFail') : t('floorplan.noBooth')}
                </p>
              )}
            </div>
          </div>

          {/* 팝오버 */}
          {selected && (
            <div
              className="kxp-fp__pop"
              style={{ left: 24, top: 24 }}
              role="dialog"
              aria-label={t('floorplan.popInfoAria', { name: selected.companyName ?? selected.boothNo ?? t('floorplan.type.default') })}
            >
              <div className="kxp-fp__pop-head">
                <div className="kxp-fp__pop-top">
                  <span className="kxp-chip">{selected.boothNo ?? '—'}</span>
                  <button
                    type="button"
                    className="kxp-fp__pop-close"
                    aria-label={t('common.actions.close')}
                    onClick={() => setSelected(null)}
                  >
                    <IconClose width={18} height={18} />
                  </button>
                </div>
                <h5 className="kxp-fp__pop-name">
                  {selected.companyName ?? (selected.status === 'reserved' ? t('floorplan.reservedBooth') : t('floorplan.availableBooth'))}
                </h5>
                <p className="kxp-fp__pop-cat">
                  {typeLabel(selected.boothType)}
                  {selected.hallLabel ? ` · ${selected.hallLabel}` : ''}
                </p>
              </div>
              <div className="kxp-fp__pop-foot">
                <a className="kxp-fp__pop-link" href="#top">
                  {t('floorplan.popDetail')} <IconArrowRight width={14} height={14} />
                </a>
                <a className="kxp-btn kxp-btn--outline" href="#top" style={{ padding: '6px 12px', fontSize: 12 }}>
                  {t('floorplan.directions')}
                </a>
              </div>
            </div>
          )}

          {/* 줌 컨트롤 */}
          <div className="kxp-fp__zoom">
            <div className="kxp-fp__zoomgroup">
              <button
                type="button"
                className="kxp-fp__zoombtn"
                aria-label={t('floorplan.zoomIn')}
                onClick={() => setScale((s) => Math.min(2, s + 0.1))}
              >
                <IconZoomIn />
              </button>
              <button
                type="button"
                className="kxp-fp__zoombtn"
                aria-label={t('floorplan.zoomOut')}
                onClick={() => setScale((s) => Math.max(0.6, s - 0.1))}
              >
                <IconZoomOut />
              </button>
              <button
                type="button"
                className="kxp-fp__zoombtn"
                aria-label={t('floorplan.reset')}
                onClick={() => {
                  setScale(1);
                  setSelected(null);
                }}
              >
                <IconReset />
              </button>
            </div>
            <a
              className="kxp-btn kxp-btn--primary"
              href="#top"
              aria-label={t('floorplan.myLocation')}
              style={{ padding: 12 }}
            >
              <IconTarget />
            </a>
          </div>

          {/* 범례 */}
          <div className="kxp-fp__legend" aria-label={t('floorplan.legendAria')}>
            <span>
              <span className="kxp-fp__dot kxp-fp__dot--avail" /> {t('floorplan.legendAvailable')}
            </span>
            <span>
              <span className="kxp-fp__dot kxp-fp__dot--reserved" /> {t('floorplan.legendReserved')}
            </span>
            <span>
              <span className="kxp-fp__dot kxp-fp__dot--public" /> {t('floorplan.legendPublic')}
            </span>
          </div>
        </section>
      </div>
    </PublicShell>
  );
}
