import { useMemo, useState } from 'react';
import { useParams } from 'react-router-dom';
import { useQuery } from '@tanstack/react-query';
import { ApiRequestError } from '../../api/client';
import { renderApi } from '../../api/endpoints';
import { AiImage } from '../../components/ui/AiImage';
import { CompareSlider } from '../../components/ui/CompareSlider';
import { AiLabel } from '../../components/ui/Badge';
import { EmptyState, ErrorState, Skeleton } from '../../components/ui/States';
import type { RenderJobDto } from '../../api/types';
import { sampleGallery } from './sampleGallery';
import { AFTER_PLACEHOLDER, BEFORE_EMPTY_HALL } from '../design/placeholders';
import './gallery.css';

/*
 * SCR-12 시각화 갤러리 (M5). Stitch visualization_gallery 이식.
 * - 샷 필터 칩(S1~S7) + 마소너리 그리드(워터마크 상시·생성중/실패 상태) + 라이트박스.
 * - render-jobs 목록 501 → degraded 샘플 시연. 상단 고지 바 상시.
 */

const SHOT_FILTERS = [
  { key: '', label: '전체' },
  { key: 'S1', label: 'S1 정면' },
  { key: 'S2', label: 'S2 야간' },
  { key: 'S3', label: 'S3 통로' },
  { key: 'S4', label: 'S4 내부' },
  { key: 'S5', label: 'S5 비교' },
  { key: 'S6', label: 'S6 배선' },
  { key: 'S7', label: 'S7 홀 전경' },
] as const;

const GALLERY_NOTICE =
  'AI 생성 이미지는 계약·심사 서류에 사용할 수 없습니다 — 시공 기준은 도면입니다';

export function VisualizationGalleryPage() {
  const { eventId = '', boothId = '' } = useParams();
  const [shot, setShot] = useState<string>('');
  const [lightbox, setLightbox] = useState<RenderJobDto | null>(null);

  const query = useQuery<{ jobs: RenderJobDto[]; degraded: boolean }>({
    queryKey: ['render-jobs', eventId, boothId],
    queryFn: async () => {
      try {
        const jobs = await renderApi.list(eventId, boothId);
        return { jobs, degraded: false };
      } catch (err) {
        if (err instanceof ApiRequestError && err.code === 'NOT_IMPLEMENTED') {
          return { jobs: sampleGallery(boothId), degraded: true };
        }
        throw err;
      }
    },
  });

  const jobs = query.data?.jobs ?? [];
  const degraded = query.data?.degraded ?? false;
  const filtered = useMemo(
    () => (shot ? jobs.filter((j) => j.shotPreset === shot) : jobs),
    [jobs, shot],
  );

  return (
    <div className="kx-gallery">
      {/* 상단 고정 고지 바 */}
      <div className="kx-gallery__notice" role="note">
        {GALLERY_NOTICE}
      </div>

      <header className="kx-gallery__head">
        <div className="kx-gallery__scope">
          <h2>시각화 갤러리</h2>
          <span className="kx-gallery__scope-sub">부스 {boothId || 'A-102'}</span>
          {degraded && <span className="kx-gallery__degraded">데이터 준비 중 (샘플)</span>}
        </div>
        <div className="kx-gallery__filters" role="tablist" aria-label="샷 필터">
          {SHOT_FILTERS.map((f) => (
            <button
              key={f.key || 'all'}
              role="tab"
              aria-selected={shot === f.key}
              className={`kx-gallery__chip ${shot === f.key ? 'is-active' : ''}`}
              onClick={() => setShot(f.key)}
            >
              {f.label}
            </button>
          ))}
        </div>
      </header>

      {query.isLoading ? (
        <div className="kx-gallery__grid">
          {Array.from({ length: 6 }, (_, i) => (
            <Skeleton key={i} height={200} radius={8} />
          ))}
        </div>
      ) : query.isError ? (
        <ErrorState onRetry={() => query.refetch()} />
      ) : filtered.length === 0 ? (
        <EmptyState
          title="아직 생성된 이미지가 없습니다"
          description="설계 스튜디오에서 예상 사진을 생성하세요."
        />
      ) : (
        <div className="kx-gallery__grid">
          {filtered.map((job) => (
            <button
              key={job.jobId}
              className="kx-gallery__card"
              onClick={() => setLightbox(job)}
              aria-label={`${job.shotPreset} 상세 보기`}
            >
              <AiImage
                imageUrl={job.imageUrl}
                status={job.status}
                watermarkText={job.watermarkText}
                notice={job.notice}
                shotLabel={job.shotPreset}
                versionTag="설계 v2"
                alt={`${job.shotPreset} 예상 이미지`}
              />
              <div className="kx-gallery__meta tnum">
                <span>{new Date(job.createdAt).toLocaleDateString('ko-KR')}</span>
                <span className={`kx-gallery__status is-${job.status.toLowerCase()}`}>
                  {STATUS_LABEL[job.status]}
                </span>
              </div>
            </button>
          ))}
        </div>
      )}

      {/* 라이트박스 */}
      {lightbox && (
        <div className="kx-modal" role="dialog" aria-modal="true" aria-label="이미지 상세">
          <div className="kx-modal__backdrop" onClick={() => setLightbox(null)} />
          <div className="kx-lightbox">
            <button
              className="kx-lightbox__close"
              onClick={() => setLightbox(null)}
              aria-label="닫기"
            >
              ✕
            </button>
            <div className="kx-lightbox__stage">
              {lightbox.shotPreset === 'S5' ? (
                <CompareSlider
                  beforeSrc={BEFORE_EMPTY_HALL}
                  afterSrc={lightbox.imageUrl ?? AFTER_PLACEHOLDER}
                  afterOverlay={
                    <>
                      <div className="kx-studio__wm" aria-hidden="true">
                        {lightbox.watermarkText}
                      </div>
                      <span className="kx-studio__after-ai">
                        <AiLabel>AI 생성</AiLabel>
                      </span>
                    </>
                  }
                />
              ) : (
                <AiImage
                  imageUrl={lightbox.imageUrl}
                  status={lightbox.status}
                  watermarkText={lightbox.watermarkText}
                  notice={lightbox.notice}
                  shotLabel={lightbox.shotPreset}
                  alt={`${lightbox.shotPreset} 원본`}
                />
              )}
            </div>
            <div className="kx-lightbox__meta">
              <dl className="kx-lightbox__dl mono">
                <div>
                  <dt>생성일</dt>
                  <dd>{new Date(lightbox.createdAt).toLocaleString('ko-KR')}</dd>
                </div>
                <div>
                  <dt>모델</dt>
                  <dd>{lightbox.modelVersion ?? '—'}</dd>
                </div>
                <div>
                  <dt>스키마 해시</dt>
                  <dd>{lightbox.schemaHash ?? '—'}</dd>
                </div>
              </dl>
              <p className="kx-lightbox__notice">{lightbox.notice}</p>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

const STATUS_LABEL: Record<RenderJobDto['status'], string> = {
  QUEUED: '대기',
  RUNNING: '생성 중',
  DONE: '완료',
  FAILED: '실패',
};
