import { useCallback, useMemo, useState } from 'react';
import { useNavigate, useParams } from 'react-router-dom';
import { useQuery } from '@tanstack/react-query';
import { layoutApi } from '../../api/endpoints';
import { hallAssignApi, type Hall } from '../hallassign/hallAssignApi';
import { ApiRequestError } from '../../api/client';
import { Button } from '../../components/ui/Button';
import { Skeleton } from '../../components/ui/States';
import { FloorplanCanvas, type CanvasLayer } from './FloorplanCanvas';
import { AutoLayoutDialog } from './AutoLayoutDialog';
import { ValidationPanel } from './ValidationPanel';
import { sampleLayout, emptyLayout } from './sampleLayout';
import { hallFloorplanUrl, hallFloorRegion, hallDwgUrl, hallDwgRegion } from './hallFloorplan';
import type { AutoLayoutOption, ComplianceReport, LayoutDto } from '../../api/types';
import './editor.css';

type RightTab = 'props' | 'validation';

export function BoothLayoutEditorPage() {
  const { eventId = '', hallId = '' } = useParams();
  const navigate = useNavigate();

  // 전시장(홀) 선택 실 운영(소유자 지시 2026-07-14) — 홀 마스터 전체를 드롭다운으로 제공.
  const hallsQuery = useQuery<Hall[]>({
    queryKey: ['halls'],
    queryFn: hallAssignApi.halls,
    staleTime: 10 * 60 * 1000,
  });
  const hallGroups = useMemo(() => {
    const groups = new Map<number, Hall[]>();
    for (const h of hallsQuery.data ?? []) {
      const list = groups.get(h.exhibitionCenter) ?? [];
      list.push(h);
      groups.set(h.exhibitionCenter, list);
    }
    return [...groups.entries()].sort(([a], [b]) => a - b);
  }, [hallsQuery.data]);

  const [layers, setLayers] = useState<CanvasLayer>({
    trench: true,
    structure: true,
    violations: true,
  });
  const [selectedBoothId, setSelectedBoothId] = useState<string | null>(null);
  const [zoom, setZoom] = useState(1);
  // 평면도 언더레이 소스 — DWG(CAD 렌더) / JPG(크롤 도면) 탭 구분(소유자 지시 2026-07-14).
  const [drawingSrc, setDrawingSrc] = useState<'jpg' | 'dwg'>('jpg');
  const dwgAvailable = hallDwgUrl(hallId) != null;
  const drawingTab = drawingSrc === 'dwg' && dwgAvailable ? 'dwg' : 'jpg';
  const [rightTab, setRightTab] = useState<RightTab>('validation');
  const [autoOpen, setAutoOpen] = useState(false);
  const [report, setReport] = useState<ComplianceReport | null>(null);
  const [validating, setValidating] = useState(false);

  // 배치 조회 (M2 GET layout) — 501이면 degraded 샘플로 캔버스 시연.
  const layoutQuery = useQuery<{ layout: LayoutDto; degraded: boolean }>({
    queryKey: ['layout', eventId, hallId],
    queryFn: async () => {
      try {
        const layout = await layoutApi.get(eventId, hallId);
        return { layout, degraded: false };
      } catch (err) {
        if (err instanceof ApiRequestError && err.code === 'NOT_IMPLEMENTED') {
          return { layout: sampleLayout(eventId, hallId), degraded: true };
        }
        // 아직 저장된 배치안이 없는 홀(404) — 에러가 아니라 "AI 자동배치로 시작" 빈 캔버스 상태.
        if (err instanceof ApiRequestError && err.code === 'NOT_FOUND') {
          return { layout: emptyLayout(eventId, hallId), degraded: false };
        }
        throw err;
      }
    },
  });

  const layout = layoutQuery.data?.layout;
  const degraded = layoutQuery.data?.degraded ?? false;
  const selectedBooth = useMemo(
    () => layout?.booths.find((b) => b.boothId === selectedBoothId) ?? null,
    [layout, selectedBoothId],
  );

  const runValidate = useCallback(async () => {
    setValidating(true);
    try {
      const r = await layoutApi.validate(eventId, hallId, layout?.version);
      setReport(r);
      setRightTab('validation');
    } catch (err) {
      if (err instanceof ApiRequestError && err.code === 'NOT_IMPLEMENTED') {
        // degraded: 요약 카운트만이라도 노출
        setReport(null);
      }
    } finally {
      setValidating(false);
    }
  }, [eventId, hallId, layout?.version]);

  function applyAutoOption(_option: AutoLayoutOption, appliedHallId: string) {
    // 다이얼로그가 apply-option으로 서버 저장을 마친 뒤 호출된다(2026-07-14 실배선).
    setAutoOpen(false);
    if (appliedHallId && appliedHallId !== hallId) {
      navigate(`/events/${eventId}/halls/${appliedHallId}/layout`);
    } else {
      void layoutQuery.refetch();
    }
  }

  const summary = layout?.summary;

  return (
    <div className="kx-editor">
      {/* 상단 툴바 */}
      <header className="kx-editor__toolbar">
        <div className="kx-editor__toolbar-left">
          <select
            className="kx-select kx-editor__hall-select"
            aria-label="전시장 홀 선택"
            value={hallId}
            onChange={(e) => navigate(`/events/${eventId}/halls/${e.target.value}/layout`)}
          >
            {!hallsQuery.data?.some((h) => h.id === hallId) && (
              <option value={hallId}>{hallId || '홀 선택'}</option>
            )}
            {hallGroups.map(([center, halls]) => (
              <optgroup key={center} label={`제${center}전시장`}>
                {halls.map((h) => (
                  <option key={h.id} value={h.id}>
                    {h.label}
                  </option>
                ))}
              </optgroup>
            ))}
          </select>
          <h2 className="kx-editor__hall">{layout?.name ?? '배치안'}</h2>
          <span className="kx-editor__version">
            v{layout?.version ?? '—'}
            <span className="kx-editor__saved">저장됨</span>
          </span>
          {degraded && (
            <span className="kx-editor__degraded" title="백엔드 매퍼 준비 중 — 샘플 데이터 표시">
              데이터 준비 중 (샘플)
            </span>
          )}
        </div>
        <div className="kx-editor__toolbar-right">
          <Button variant="secondary" leadingIcon="🖼" onClick={() => setAutoOpen(true)}>
            홀 전경 생성
          </Button>
          <Button variant="secondary" leadingIcon="✓" onClick={runValidate} disabled={validating}>
            {validating ? '검증 중…' : '규정 검증 실행'}
          </Button>
          <Button variant="ai" leadingIcon="✦" onClick={() => setAutoOpen(true)}>
            AI 자동배치
          </Button>
        </div>
      </header>

      <div className="kx-editor__workspace">
        {/* 좌측 도구 패널 */}
        <aside className="kx-editor__left" aria-label="도구">
          <section className="kx-tool-group">
            <h3>부스 팔레트</h3>
            <div className="kx-palette">
              <PaletteItem label="기본 3×3m" w={24} h={24} />
              <PaletteItem label="프리미엄 6×3m" w={40} h={24} />
              <PaletteItem label="아일랜드 (자유형)" full />
            </div>
          </section>
          <section className="kx-tool-group">
            <h3>부대 시설</h3>
            <div className="kx-facility">
              <button>무대</button>
              <button>라운지</button>
              <button>주출입구</button>
            </div>
          </section>
          <section className="kx-tool-group">
            <h3>도면</h3>
            <div className="kx-drawing-tabs" role="tablist" aria-label="평면도 종류">
              <button
                role="tab"
                aria-selected={drawingTab === 'jpg'}
                className={drawingTab === 'jpg' ? 'is-active' : ''}
                onClick={() => setDrawingSrc('jpg')}
              >
                JPG
              </button>
              <button
                role="tab"
                aria-selected={drawingTab === 'dwg'}
                className={drawingTab === 'dwg' ? 'is-active' : ''}
                disabled={!dwgAvailable}
                title={dwgAvailable ? 'CAD(DWG) 실측 렌더 도면' : '이 홀은 CAD 렌더 준비 중'}
                onClick={() => setDrawingSrc('dwg')}
              >
                DWG
              </button>
            </div>
          </section>
          <section className="kx-tool-group">
            <h3>레이어</h3>
            <LayerToggle
              label="트렌치 그리드"
              on={layers.trench}
              onToggle={() => setLayers((l) => ({ ...l, trench: !l.trench }))}
            />
            <LayerToggle
              label="기둥·비상구"
              on={layers.structure}
              onToggle={() => setLayers((l) => ({ ...l, structure: !l.structure }))}
            />
            <LayerToggle
              label="위반 오버레이"
              on={layers.violations}
              onToggle={() => setLayers((l) => ({ ...l, violations: !l.violations }))}
            />
          </section>
        </aside>

        {/* 중앙 캔버스 */}
        <section className="kx-editor__canvas-wrap">
          <div className="kx-editor__canvas-stage">
            {layoutQuery.isLoading ? (
              <div className="kx-editor__canvas-loading">
                <Skeleton height={480} radius={8} />
              </div>
            ) : layoutQuery.isError ? (
              <div className="kx-editor__canvas-error" role="alert">
                <p>도면을 불러오지 못했습니다.</p>
                <Button variant="secondary" onClick={() => layoutQuery.refetch()}>
                  다시 시도
                </Button>
              </div>
            ) : layout && layout.booths.length === 0 ? (
              <div className="kx-editor__canvas-empty">
                <p>조건을 입력하고 AI 자동배치로 시작하세요.</p>
                <Button variant="ai" leadingIcon="✦" onClick={() => setAutoOpen(true)}>
                  AI 자동배치
                </Button>
              </div>
            ) : (
              layout && (
                <FloorplanCanvas
                  hallDims={
                    layout.hall?.dimsM && layout.hall.dimsM.length >= 2
                      ? [layout.hall.dimsM[0], layout.hall.dimsM[1]]
                      : [126, 90]
                  }
                  booths={layout.booths}
                  layers={layers}
                  selectedBoothId={selectedBoothId}
                  onSelectBooth={setSelectedBoothId}
                  zoom={zoom}
                  onZoomChange={setZoom}
                  floorplanUrl={drawingTab === 'dwg' ? hallDwgUrl(hallId) : hallFloorplanUrl(hallId)}
                  floorRegion={drawingTab === 'dwg' ? hallDwgRegion(hallId) : hallFloorRegion(hallId)}
                  pillars={layout.hall?.pillars}
                  obstacles={layout.hall?.obstacles}
                  trenches={layout.hall?.trenches}
                />
              )
            )}
          </div>

          {/* 하단 상태 바 */}
          <div className="kx-editor__statusbar">
            <div className="kx-editor__stats tnum">
              {summary && (
                <>
                  <span>부스 {summary.boothCount} / {summary.targetBoothCount}</span>
                  <span className="kx-dot" />
                  <span>판매면적 {summary.salesAreaM2.toLocaleString()}㎡</span>
                </>
              )}
            </div>
            <div className="kx-editor__zoom">
              <button aria-label="축소" onClick={() => setZoom((z) => Math.max(0.5, z - 0.1))}>
                −
              </button>
              <span className="tnum">{Math.round(zoom * 100)}%</span>
              <button aria-label="확대" onClick={() => setZoom((z) => Math.min(2, z + 0.1))}>
                +
              </button>
            </div>
          </div>
        </section>

        {/* 우측 속성/검증 패널 */}
        <aside className="kx-editor__right" aria-label="속성 및 검증">
          <div className="kx-editor__tabs" role="tablist">
            <button
              role="tab"
              aria-selected={rightTab === 'props'}
              className={rightTab === 'props' ? 'is-active' : ''}
              onClick={() => setRightTab('props')}
            >
              속성
            </button>
            <button
              role="tab"
              aria-selected={rightTab === 'validation'}
              className={rightTab === 'validation' ? 'is-active' : ''}
              onClick={() => setRightTab('validation')}
            >
              검증{summary ? ` (${summary.violationBlock + summary.violationWarn})` : ''}
            </button>
          </div>

          {rightTab === 'props' ? (
            <div className="kx-props">
              {selectedBooth ? (
                <dl className="kx-props__list">
                  <PropRow k="부스번호" v={selectedBooth.boothNo} />
                  <PropRow k="타입" v={selectedBooth.type} />
                  <PropRow k="크기" v={`${selectedBooth.sizeM[0]}×${selectedBooth.sizeM[1]}m`} />
                  <PropRow k="높이" v={`${selectedBooth.heightM}m`} />
                  <PropRow k="바닥하중" v={`${selectedBooth.floorLoadTPerM2} t/㎡`} />
                  <PropRow k="배정 업체" v={selectedBooth.assignedCompanyName ?? '미배정'} />
                </dl>
              ) : (
                <p className="kx-props__empty">부스를 선택하면 속성이 표시됩니다.</p>
              )}
            </div>
          ) : (
            <ValidationPanel
              report={report}
              summary={summary}
              degraded={degraded}
            />
          )}
        </aside>
      </div>

      {autoOpen && (
        <AutoLayoutDialog
          eventId={eventId}
          hallId={hallId}
          onClose={() => setAutoOpen(false)}
          onApply={applyAutoOption}
        />
      )}
    </div>
  );
}

function PaletteItem({ label, w, h, full }: { label: string; w?: number; h?: number; full?: boolean }) {
  return (
    <div className={`kx-palette__item ${full ? 'is-full' : ''}`}>
      <span className="kx-palette__swatch" style={full ? undefined : { width: w, height: h }} />
      <span className="kx-palette__label">{label}</span>
    </div>
  );
}

function LayerToggle({ label, on, onToggle }: { label: string; on: boolean; onToggle: () => void }) {
  return (
    <label className="kx-layer">
      <span>{label}</span>
      <button
        type="button"
        role="switch"
        aria-checked={on}
        aria-label={label}
        className={`kx-switch ${on ? 'is-on' : ''}`}
        onClick={onToggle}
      >
        <span className="kx-switch__knob" />
      </button>
    </label>
  );
}

function PropRow({ k, v }: { k: string; v: string }) {
  return (
    <div className="kx-props__row">
      <dt>{k}</dt>
      <dd className="tnum">{v}</dd>
    </div>
  );
}
