import { useState, useCallback, useRef, useEffect } from 'react';
import {
  fetchAerialMedia,
  downloadAerialMedia,
  getAerialMediaViewUrl,
  uploadAerialMedia,
} from '../services/aerialApi';
import type { AerialMediaItem } from '../services/aerialApi';
import { navigateToTab } from '@common/hooks/useSubMenu';

// ── Helpers ──

function formatDtm(dtm: string | null): string {
  if (!dtm) return '—';
  const d = new Date(dtm);
  return d.toISOString().slice(0, 16).replace('T', ' ');
}

const equipIcon = (t: string) => (t === 'drone' ? '🛸' : t === 'plane' ? '✈' : '🛰');

const equipTagCls = () => 'text-fg';

const mediaTagCls = () => 'text-fg';

const FilterBtn = ({
  label,
  active,
  onClick,
}: {
  label: string;
  active: boolean;
  onClick: () => void;
}) => (
  <button
    onClick={onClick}
    className={`px-2.5 py-1 text-caption font-semibold rounded font-korean transition-colors ${
      active
        ? 'bg-[rgba(6,182,212,0.15)] text-color-accent border border-[rgba(6,182,212,0.3)]'
        : 'border border-stroke text-fg-sub hover:bg-bg-surface-hover'
    }`}
  >
    {label}
  </button>
);

// ── Component ──

export function MediaManagement() {
  const [mediaItems, setMediaItems] = useState<AerialMediaItem[]>([]);
  const [loading, setLoading] = useState(true);
  const [selectedIds, setSelectedIds] = useState<Set<number>>(new Set());
  const [equipFilter, setEquipFilter] = useState<string>('all');
  const [typeFilter, setTypeFilter] = useState<Set<string>>(new Set());
  const [searchTerm, setSearchTerm] = useState('');
  const [sortBy, setSortBy] = useState('latest');
  const [showUpload, setShowUpload] = useState(false);
  const [downloadingId, setDownloadingId] = useState<number | null>(null);
  const [bulkDownloading, setBulkDownloading] = useState(false);
  const [downloadResult, setDownloadResult] = useState<{ total: number; success: number } | null>(
    null,
  );
  const [previewItem, setPreviewItem] = useState<AerialMediaItem | null>(null);
  const modalRef = useRef<HTMLDivElement>(null);
  const previewRef = useRef<HTMLDivElement>(null);
  const fileInputRef = useRef<HTMLInputElement>(null);
  const [uploadFile, setUploadFile] = useState<File | null>(null);
  const [uploading, setUploading] = useState(false);
  const [dragOver, setDragOver] = useState(false);
  // const [uploadEquip, setUploadEquip] = useState('drone');
  // const [uploadEquipNm, setUploadEquipNm] = useState('드론 (DJI M300 RTK)');
  // const [uploadMemo, setUploadMemo] = useState('');

  const loadData = useCallback(async () => {
    setLoading(true);
    try {
      const items = await fetchAerialMedia();
      setMediaItems(items);
    } catch (err) {
      console.error('[aerial] 미디어 목록 조회 실패:', err);
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => {
    loadData();
  }, [loadData]);

  useEffect(() => {
    const handler = (e: MouseEvent) => {
      if (modalRef.current && !modalRef.current.contains(e.target as Node)) {
        setShowUpload(false);
      }
    };
    if (showUpload) document.addEventListener('mousedown', handler);
    return () => document.removeEventListener('mousedown', handler);
  }, [showUpload]);

  useEffect(() => {
    if (!previewItem) return;
    const onKey = (e: KeyboardEvent) => {
      if (e.key === 'Escape') setPreviewItem(null);
    };
    document.addEventListener('keydown', onKey);
    return () => document.removeEventListener('keydown', onKey);
  }, [previewItem]);

  const filtered = mediaItems.filter((f) => {
    if (equipFilter !== 'all' && f.equipTpCd !== equipFilter) return false;
    if (typeFilter.size > 0) {
      const isPhoto = f.mediaTpCd !== '영상';
      const isVideo = f.mediaTpCd === '영상';
      if (typeFilter.has('photo') && !isPhoto) return false;
      if (typeFilter.has('video') && !isVideo) return false;
    }
    if (searchTerm && !f.fileNm.toLowerCase().includes(searchTerm.toLowerCase())) return false;
    return true;
  });

  const sorted = [...filtered].sort((a, b) => {
    if (sortBy === 'name') return a.fileNm.localeCompare(b.fileNm);
    if (sortBy === 'size') return parseFloat(b.fileSz ?? '0') - parseFloat(a.fileSz ?? '0');
    return (b.takngDtm ?? '').localeCompare(a.takngDtm ?? '');
  });

  const toggleId = (id: number) => {
    setSelectedIds((prev) => {
      const next = new Set(prev);
      if (next.has(id)) {
        next.delete(id);
      } else {
        next.add(id);
      }
      return next;
    });
  };

  const toggleAll = () => {
    if (selectedIds.size === sorted.length) {
      setSelectedIds(new Set());
    } else {
      setSelectedIds(new Set(sorted.map((f) => f.aerialMediaSn)));
    }
  };

  const toggleTypeFilter = (t: string) => {
    setTypeFilter((prev) => {
      const next = new Set(prev);
      if (next.has(t)) {
        next.delete(t);
      } else {
        next.add(t);
      }
      return next;
    });
  };

  const handleBulkDownload = async () => {
    if (bulkDownloading || selectedIds.size === 0) return;
    setBulkDownloading(true);
    let success = 0;
    const total = selectedIds.size;
    for (const sn of selectedIds) {
      const item = mediaItems.find((f) => f.aerialMediaSn === sn);
      if (!item) continue;
      try {
        await downloadAerialMedia(sn, item.orgnlNm ?? item.fileNm);
        success++;
      } catch {
        // 실패 건 스킵
      }
    }
    setBulkDownloading(false);
    setDownloadResult({ total, success });
  };

  const handleDownload = async (e: React.MouseEvent, item: AerialMediaItem) => {
    e.stopPropagation();
    if (downloadingId !== null) return;
    setDownloadingId(item.aerialMediaSn);
    try {
      await downloadAerialMedia(item.aerialMediaSn, item.orgnlNm ?? item.fileNm);
    } catch {
      alert('다운로드 실패: 이미지를 찾을 수 없습니다.');
    } finally {
      setDownloadingId(null);
    }
  };

  const handleUploadSubmit = async () => {
    if (!uploadFile || uploading) return;
    setUploading(true);
    try {
      await uploadAerialMedia(uploadFile, {
        // equipTpCd: uploadEquip,
        // equipNm: uploadEquipNm,
        // memo: uploadMemo,
      });
      setShowUpload(false);
      setUploadFile(null);
      // setUploadMemo('');
      await loadData();
    } catch {
      alert('업로드 실패: 다시 시도해주세요.');
    } finally {
      setUploading(false);
    }
  };

  const handleFileDrop = (e: React.DragEvent) => {
    e.preventDefault();
    setDragOver(false);
    const file = e.dataTransfer.files[0];
    if (file) setUploadFile(file);
  };

  const handleFileSelect = (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (file) setUploadFile(file);
  };

  const droneCount = mediaItems.filter((f) => f.equipTpCd === 'drone').length;
  const planeCount = mediaItems.filter((f) => f.equipTpCd === 'plane').length;
  const satCount = mediaItems.filter((f) => f.equipTpCd === 'satellite').length;

  return (
    <div className="flex flex-col h-full">
      {/* Filters */}
      <div className="flex items-center justify-between mb-4">
        <div className="flex gap-1.5 items-center">
          <span className="text-label-2 text-fg-disabled font-korean">촬영 장비:</span>
          <FilterBtn
            label="전체"
            active={equipFilter === 'all'}
            onClick={() => setEquipFilter('all')}
          />
          <FilterBtn
            label="🛸 드론"
            active={equipFilter === 'drone'}
            onClick={() => setEquipFilter('drone')}
          />
          <FilterBtn
            label="✈ 유인항공기"
            active={equipFilter === 'plane'}
            onClick={() => setEquipFilter('plane')}
          />
          <FilterBtn
            label="🛰 위성"
            active={equipFilter === 'satellite'}
            onClick={() => setEquipFilter('satellite')}
          />
          <span className="w-px h-4 bg-border mx-1" />
          <span className="text-label-2 text-fg-disabled font-korean">유형:</span>
          <FilterBtn
            label="📷 사진"
            active={typeFilter.has('photo')}
            onClick={() => toggleTypeFilter('photo')}
          />
          <FilterBtn
            label="🎬 영상"
            active={typeFilter.has('video')}
            onClick={() => toggleTypeFilter('video')}
          />
        </div>
        <div className="flex gap-2 items-center">
          <input
            type="text"
            placeholder="파일명 검색..."
            value={searchTerm}
            onChange={(e) => setSearchTerm(e.target.value)}
            className="px-3 py-1.5 bg-bg-base border border-stroke rounded-sm text-fg font-korean text-label-2 outline-none w-40 focus:border-color-accent"
          />
          <select
            value={sortBy}
            onChange={(e) => setSortBy(e.target.value)}
            className="prd-i py-1.5 w-auto"
          >
            <option value="latest">최신순</option>
            <option value="name">이름순</option>
            <option value="size">크기순</option>
          </select>
          <button
            onClick={() => setShowUpload(true)}
            className="px-3 py-1.5 text-label-2 font-semibold rounded bg-[rgba(6,182,212,0.08)] text-color-accent border border-[rgba(6,182,212,0.3)] hover:bg-[rgba(6,182,212,0.15)] transition-colors font-korean"
          >
            + 이미지 등록
          </button>
        </div>
      </div>

      {/* Summary Stats */}
      <div className="flex gap-2.5 mb-4">
        {[
          {
            icon: '📸',
            value: loading ? '…' : String(mediaItems.length),
            label: '총 파일',
            color: 'text-fg',
          },
          {
            icon: '🛸',
            value: loading ? '…' : String(droneCount),
            label: '드론',
            color: 'text-fg',
          },
          {
            icon: '✈',
            value: loading ? '…' : String(planeCount),
            label: '유인항공기',
            color: 'text-fg',
          },
          { icon: '🛰', value: loading ? '…' : String(satCount), label: '위성', color: 'text-fg' },
          { icon: '💾', value: '—', label: '총 용량', color: 'text-fg' },
        ].map((s, i) => (
          <div
            key={i}
            className="flex-1 flex items-center gap-2.5 px-4 py-3 border border-stroke rounded-sm"
          >
            <span className="text-xl">{s.icon}</span>
            <div>
              <div className={`text-base font-bold font-mono ${s.color}`}>{s.value}</div>
              <div className="text-caption text-fg-disabled font-korean">{s.label}</div>
            </div>
          </div>
        ))}
      </div>

      {/* File Table */}
      <div className="flex-1 border border-stroke rounded-md overflow-hidden flex flex-col">
        <div className="overflow-auto flex-1 scrollbar-thin">
          <table className="w-full text-left" style={{ tableLayout: 'fixed' }}>
            <colgroup>
              <col style={{ width: 36 }} />
              <col style={{ width: 36 }} />
              <col style={{ width: 120 }} />
              <col style={{ width: 130 }} />
              <col />
              <col style={{ width: 95 }} />
              <col style={{ width: 85 }} />
              <col style={{ width: 145 }} />
              <col style={{ width: 85 }} />
              <col style={{ width: 95 }} />
              <col style={{ width: 60 }} />
            </colgroup>
            <thead>
              <tr className="border-b border-stroke bg-bg-elevated">
                <th className="px-2 py-2.5 text-center">
                  <input
                    type="checkbox"
                    checked={selectedIds.size === sorted.length && sorted.length > 0}
                    onChange={toggleAll}
                    className="accent-primary-blue"
                  />
                </th>
                <th className="px-1 py-2.5" />
                <th className="px-2 py-2.5 text-caption font-semibold text-fg-disabled font-korean whitespace-nowrap">
                  사고명
                </th>
                <th className="px-2 py-2.5 text-caption font-semibold text-fg-disabled font-korean whitespace-nowrap">
                  위치
                </th>
                <th className="px-2 py-2.5 text-caption font-semibold text-fg-disabled font-korean">
                  파일명
                </th>
                <th className="px-2 py-2.5 text-caption font-semibold text-fg-disabled font-korean">
                  장비
                </th>
                <th className="px-2 py-2.5 text-caption font-semibold text-fg-disabled font-korean">
                  유형
                </th>
                <th className="px-2 py-2.5 text-caption font-semibold text-fg-disabled font-korean whitespace-nowrap">
                  촬영일시
                </th>
                <th className="px-2 py-2.5 text-caption font-semibold text-fg-disabled font-korean whitespace-nowrap">
                  용량
                </th>
                <th className="px-2 py-2.5 text-caption font-semibold text-fg-disabled font-korean whitespace-nowrap">
                  해상도
                </th>
                <th className="px-2 py-2.5 text-caption font-semibold text-fg-disabled text-center">
                  다운로드
                </th>
              </tr>
            </thead>
            <tbody>
              {loading ? (
                <tr>
                  <td
                    colSpan={11}
                    className="px-4 py-8 text-center text-label-2 text-fg-disabled font-korean"
                  >
                    불러오는 중...
                  </td>
                </tr>
              ) : (
                sorted.map((f) => {
                  const isPhoto = f.mediaTpCd !== '영상';
                  return (
                    <tr
                      key={f.aerialMediaSn}
                      className={`border-b border-stroke transition-colors hover:bg-[rgba(255,255,255,0.02)] ${
                        selectedIds.has(f.aerialMediaSn) ? 'bg-[rgba(6,182,212,0.06)]' : ''
                      }`}
                    >
                      <td
                        className="px-2 py-2 text-center cursor-pointer"
                        onClick={() => toggleId(f.aerialMediaSn)}
                      >
                        <input
                          type="checkbox"
                          checked={selectedIds.has(f.aerialMediaSn)}
                          onChange={() => toggleId(f.aerialMediaSn)}
                          onClick={(e) => e.stopPropagation()}
                          className="accent-primary-blue"
                        />
                      </td>
                      <td className="px-1 py-2 text-base">{equipIcon(f.equipTpCd)}</td>
                      <td className="px-2 py-2 text-caption font-semibold text-fg font-korean truncate">
                        {f.acdntSn != null ? String(f.acdntSn) : '—'}
                      </td>
                      <td className="px-2 py-2 text-caption text-fg font-mono truncate">
                        {f.locDc ?? '—'}
                      </td>
                      <td className="px-2 py-2 text-label-2 text-fg font-korean truncate">
                        {f.fileNm}
                      </td>
                      <td className="px-2 py-2">
                        <span className={`text-caption font-korean ${equipTagCls()}`}>
                          {f.equipNm}
                        </span>
                      </td>
                      <td className="px-2 py-2">
                        {isPhoto ? (
                          <button
                            type="button"
                            onClick={() => setPreviewItem(f)}
                            className={`text-caption font-semibold font-korean hover:underline cursor-pointer ${mediaTagCls()}`}
                          >
                            📷 {f.mediaTpCd}
                          </button>
                        ) : (
                          <span
                            className={`text-caption font-semibold font-korean ${mediaTagCls()}`}
                          >
                            🎬 {f.mediaTpCd}
                          </span>
                        )}
                      </td>
                      <td className="px-2 py-2 text-label-2 font-mono">{formatDtm(f.takngDtm)}</td>
                      <td className="px-2 py-2 text-label-2 font-mono">{f.fileSz ?? '—'}</td>
                      <td className="px-2 py-2 text-label-2 font-mono">{f.resolution ?? '—'}</td>
                      <td className="px-2 py-2 text-center">
                        <button
                          onClick={(e) => handleDownload(e, f)}
                          disabled={downloadingId === f.aerialMediaSn}
                          className="px-2 py-1 text-caption disabled:opacity-50"
                        >
                          {downloadingId === f.aerialMediaSn ? '⏳' : '📥'}
                        </button>
                      </td>
                    </tr>
                  );
                })
              )}
            </tbody>
          </table>
        </div>
      </div>

      {/* Bottom Actions */}
      <div className="flex justify-between items-center mt-4 pt-3.5 border-t border-stroke">
        <div className="text-label-2 text-fg-disabled font-korean">
          선택된 파일: <span className="text-color-accent font-semibold">{selectedIds.size}</span>건
        </div>
        <div className="flex gap-2">
          <button
            onClick={toggleAll}
            className="px-3 py-1.5 text-label-2 font-semibold rounded bg-bg-card border border-stroke text-fg-sub hover:bg-bg-surface-hover transition-colors font-korean"
          >
            전체선택
          </button>
          <button
            onClick={handleBulkDownload}
            disabled={bulkDownloading || selectedIds.size === 0}
            className="px-3 py-1.5 text-label-2 font-semibold rounded bg-[rgba(6,182,212,0.08)] text-color-accent border border-[rgba(6,182,212,0.3)] hover:bg-[rgba(6,182,212,0.15)] transition-colors font-korean disabled:opacity-50"
          >
            {bulkDownloading ? '⏳ 다운로드 중...' : '선택 다운로드'}
          </button>
          <button
            onClick={() => navigateToTab('prediction', 'analysis')}
            className="px-3 py-1.5 text-label-2 font-semibold rounded bg-[rgba(6,182,212,0.08)] text-color-accent border border-[rgba(6,182,212,0.3)] hover:bg-[rgba(6,182,212,0.15)] transition-colors font-korean"
          >
            유출유확산예측으로 →
          </button>
        </div>
      </div>

      {/* 선택 다운로드 결과 팝업 */}
      {downloadResult && (
        <div className="fixed inset-0 z-[300] bg-black/60 backdrop-blur-sm flex items-center justify-center">
          <div className="bg-bg-surface border border-stroke rounded-md p-6 w-72 text-center">
            <div className="text-2xl mb-3">📥</div>
            <div className="text-body-2 font-bold font-korean mb-3">다운로드 완료</div>
            <div className="text-title-4 font-korean text-fg-sub mb-1">
              총 <span className="text-color-accent font-bold">{downloadResult.total}</span>건 선택
            </div>
            <div className="text-title-4 font-korean text-fg-sub mb-4">
              <span className="text-color-success font-bold">{downloadResult.success}</span>건
              다운로드 성공
              {downloadResult.total - downloadResult.success > 0 && (
                <>
                  {' '}
                  /{' '}
                  <span className="text-color-danger font-bold">
                    {downloadResult.total - downloadResult.success}
                  </span>
                  건 실패
                </>
              )}
            </div>
            <button
              onClick={() => setDownloadResult(null)}
              className="px-6 py-2 text-body-2 font-semibold rounded bg-[rgba(6,182,212,0.15)] text-color-accent border border-[rgba(6,182,212,0.3)] hover:bg-[rgba(6,182,212,0.25)] transition-colors font-korean"
            >
              확인
            </button>
          </div>
        </div>
      )}

      {/* Upload Modal */}
      {showUpload && (
        <div className="fixed inset-0 z-[200] bg-black/60 backdrop-blur-sm flex items-center justify-center">
          <div
            ref={modalRef}
            className="bg-bg-surface border border-stroke rounded-md w-[480px] max-h-[80vh] overflow-y-auto p-6"
          >
            <div className="flex justify-between items-center mb-4">
              <span className="text-base font-bold font-korean">영상·사진 업로드</span>
              <button
                onClick={() => {
                  setShowUpload(false);
                  setUploadFile(null);
                }}
                className="text-fg-disabled text-lg hover:text-fg"
              >
                ✕
              </button>
            </div>
            <div
              onDragOver={(e) => {
                e.preventDefault();
                setDragOver(true);
              }}
              onDragLeave={() => setDragOver(false)}
              onDrop={handleFileDrop}
              onClick={() => fileInputRef.current?.click()}
              className={`border-2 border-dashed rounded-md py-8 px-4 text-center mb-4 cursor-pointer transition-colors ${
                dragOver
                  ? 'border-color-accent bg-[rgba(6,182,212,0.06)]'
                  : uploadFile
                    ? 'border-[rgba(6,182,212,0.3)] bg-[rgba(6,182,212,0.04)]'
                    : 'border-stroke-light hover:border-[rgba(6,182,212,0.4)]'
              }`}
            >
              <input
                ref={fileInputRef}
                type="file"
                accept=".jpg,.jpeg,.png,.tif,.tiff,.mp4,.mov"
                onChange={handleFileSelect}
                className="hidden"
              />
              {uploadFile ? (
                <>
                  <div className="text-3xl mb-2">✅</div>
                  <div className="text-title-4 font-semibold mb-1 font-korean truncate px-4">
                    {uploadFile.name}
                  </div>
                  <div className="text-label-2 text-fg-disabled font-korean">
                    {(uploadFile.size / (1024 * 1024)).toFixed(2)} MB · 클릭하여 변경
                  </div>
                </>
              ) : (
                <>
                  <div className="text-3xl mb-2 opacity-50">📁</div>
                  <div className="text-title-4 font-semibold mb-1 font-korean">
                    파일을 드래그하거나 클릭하여 업로드
                  </div>
                  <div className="text-label-2 text-fg-disabled font-korean">
                    JPG, TIFF, GeoTIFF, MP4, MOV 지원 · 최대 2GB
                  </div>
                </>
              )}
            </div>
            {/* <div className="mb-3">
              <label className="block text-caption font-semibold mb-1.5 text-fg-sub font-korean">
                촬영 장비
              </label>
              <select
                className="prd-i w-full"
                value={uploadEquipNm}
                onChange={(e) => {
                  setUploadEquipNm(e.target.value);
                  const v = e.target.value;
                  if (v.startsWith('드론')) setUploadEquip('drone');
                  else if (v.startsWith('유인')) setUploadEquip('plane');
                  else if (v.startsWith('위성')) setUploadEquip('satellite');
                  else setUploadEquip('drone');
                }}
              >
                <option>드론 (DJI M300 RTK)</option>
                <option>드론 (DJI Mavic 3E)</option>
                <option>유인항공기 (CN-235)</option>
                <option>유인항공기 (헬기 B-512)</option>
                <option>위성 (Sentinel-1)</option>
                <option>위성 (다목적위성5호)</option>
                <option>기타</option>
              </select>
            </div>
            <div className="mb-3">
              <label className="block text-caption font-semibold mb-1.5 text-fg-sub font-korean">
                연관 사고
              </label>
              <select className="prd-i w-full">
                <option>여수항 유류유출 (2026-01-18)</option>
                <option>통영 해역 기름오염 (2026-01-18)</option>
                <option>군산항 인근 오염 (2026-01-18)</option>
              </select>
            </div>
            <div className="mb-4">
              <label className="block text-caption font-semibold mb-1.5 text-fg-sub font-korean">
                메모
              </label>
              <textarea
                className="prd-i w-full h-[60px] resize-y"
                placeholder="촬영 조건, 비고 등..."
                value={uploadMemo}
                onChange={(e) => setUploadMemo(e.target.value)}
              />
            </div> */}
            <button
              onClick={handleUploadSubmit}
              disabled={!uploadFile || uploading}
              className="w-full py-3 rounded-sm text-body-2 font-bold font-korean cursor-pointer hover:brightness-125 transition-all disabled:opacity-50 disabled:cursor-not-allowed"
              style={{
                background: 'rgba(6,182,212,0.15)',
                border: '1px solid rgba(6,182,212,0.3)',
                color: 'var(--color-accent)',
              }}
            >
              {uploading ? '업로드 중...' : '업로드 실행'}
            </button>
          </div>
        </div>
      )}

      {/* Image Preview Modal */}
      {previewItem && (
        <div
          className="fixed inset-0 z-[250] bg-black/70 backdrop-blur-sm flex items-center justify-center"
          onClick={() => setPreviewItem(null)}
        >
          <div
            ref={previewRef}
            onClick={(e) => e.stopPropagation()}
            className="bg-bg-surface border border-stroke rounded-md w-[720px] max-w-[90vw] max-h-[85vh] flex flex-col overflow-hidden"
          >
            <div className="flex justify-between items-center px-4 py-2.5 border-b border-stroke">
              <div className="flex flex-col min-w-0">
                <span className="text-label-1 font-bold font-korean text-fg truncate">
                  {previewItem.fileNm}
                </span>
                <span className="text-caption text-fg-disabled font-mono">
                  {formatDtm(previewItem.takngDtm)} · {previewItem.equipNm}
                </span>
              </div>
              <button
                onClick={() => setPreviewItem(null)}
                className="text-fg-disabled text-lg hover:text-fg ml-3"
              >
                ✕
              </button>
            </div>
            <div className="flex-1 flex items-center justify-center overflow-hidden bg-black/30 relative min-h-[320px]">
              <img
                src={getAerialMediaViewUrl(previewItem.aerialMediaSn)}
                alt={previewItem.orgnlNm ?? previewItem.fileNm}
                style={{ width: '100%', height: '100%', objectFit: 'contain' }}
                onError={(e) => {
                  (e.target as HTMLImageElement).style.display = 'none';
                  (e.target as HTMLImageElement).nextElementSibling?.classList.remove('hidden');
                }}
              />
              <div className="hidden flex-col items-center gap-2">
                <div className="text-[48px] text-fg-disabled">📷</div>
                <div className="text-label-1 text-fg-disabled font-korean">
                  이미지를 불러올 수 없습니다
                </div>
              </div>
            </div>
            <div className="flex justify-end gap-2 px-4 py-2.5 border-t border-stroke">
              <button
                onClick={(e) => handleDownload(e, previewItem)}
                disabled={downloadingId === previewItem.aerialMediaSn}
                className="px-3 py-1.5 text-label-2 font-semibold rounded bg-[rgba(6,182,212,0.08)] text-color-accent border border-[rgba(6,182,212,0.3)] hover:bg-[rgba(6,182,212,0.15)] transition-colors font-korean disabled:opacity-50"
              >
                {downloadingId === previewItem.aerialMediaSn ? '⏳ 다운로드 중...' : '📥 다운로드'}
              </button>
              <button
                onClick={() => setPreviewItem(null)}
                className="px-3 py-1.5 text-label-2 font-semibold rounded bg-bg-card border border-stroke text-fg-sub hover:bg-bg-surface-hover transition-colors font-korean"
              >
                닫기
              </button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}
