import React, { useState, useCallback, useRef } from 'react';
import useTravelData from './useTravelData';
import MiniMap, { getRegionAccent } from './MiniMap';
import AlbumCard from './AlbumCard';
import AlbumDetail from './AlbumDetail';
import './Travel.css';

/* ─────────────────────────────────────────────
   Travel — main page component
───────────────────────────────────────────── */
const Travel = () => {
    const {
        regions,
        albums,
        loadingAlbums,
        selectedRegion,
        setSelectedRegion,
        photos,
        photoSummary,
        loading,
        loadingMore,
        error,
        hasNext,
        loadAlbumPhotos,
        loadMorePhotos,
        reloadAlbumPhotos,
        getFilteredAlbums,
        refreshAlbums,
    } = useTravelData();

    /* ── Local state ──────────────────────────── */
    const [selectedAlbum, setSelectedAlbum] = useState(null);
    const [albumSourceRect, setAlbumSourceRect] = useState(null);
    const [syncing, setSyncing] = useState(false);
    const [syncResult, setSyncResult] = useState(null);
    const syncTimerRef = useRef(null);

    /* ── Computed ──────────────────────────────── */
    const regionAccent = getRegionAccent(selectedRegion || '');
    const filteredAlbums = getFilteredAlbums(selectedRegion);

    /* ── Handlers ─────────────────────────────── */
    const handleSelectRegion = useCallback(
        (regionId) => {
            setSelectedRegion(regionId);
        },
        [setSelectedRegion],
    );

    const handleClearRegion = useCallback(() => {
        setSelectedRegion(null);
    }, [setSelectedRegion]);

    const handleOpenAlbum = useCallback(
        (album, rect) => {
            setSelectedAlbum(album);
            setAlbumSourceRect(rect || null);
            loadAlbumPhotos(album.region, album.name);
        },
        [loadAlbumPhotos],
    );

    const handleCloseAlbum = useCallback(() => {
        setSelectedAlbum(null);
        setAlbumSourceRect(null);
    }, []);

    const handleLoadMore = useCallback(() => {
        if (!selectedAlbum) return;
        loadMorePhotos(selectedAlbum.region, selectedAlbum.name);
    }, [selectedAlbum, loadMorePhotos]);

    const handleReload = useCallback(() => {
        if (!selectedAlbum) return;
        return reloadAlbumPhotos(selectedAlbum.region, selectedAlbum.name);
    }, [selectedAlbum, reloadAlbumPhotos]);

    const handleSync = useCallback(async () => {
        if (syncing) return;
        setSyncing(true);
        setSyncResult(null);
        try {
            const res = await fetch('/api/travel/sync', { method: 'POST' });
            if (!res.ok) throw new Error(`${res.status}`);
            const data = await res.json();
            setSyncResult(data);
            if (syncTimerRef.current) clearTimeout(syncTimerRef.current);
            syncTimerRef.current = setTimeout(() => setSyncResult(null), 8000);
        } catch (e) {
            setSyncResult({ error: e.message });
            if (syncTimerRef.current) clearTimeout(syncTimerRef.current);
            syncTimerRef.current = setTimeout(() => setSyncResult(null), 5000);
        } finally {
            setSyncing(false);
        }
    }, [syncing]);

    /* ── Render ────────────────────────────────── */
    return (
        <div className="travel" style={{ '--region-accent': regionAccent }}>
            {/* ═══════════════════════════════════════
                HEADER — editorial masthead
            ═══════════════════════════════════════ */}
            <header className="tv-header">
                <div className="tv-header__masthead">
                    <div className="tv-header__meta">
                        <span className="tv-header__issue">Visual Diary</span>
                        <span className="tv-header__divider" aria-hidden>·</span>
                        <span className="tv-header__tagline">여행 포토 아카이브</span>
                    </div>
                    <h1 className="tv-header__title">
                        <span className="tv-header__title-main">Travel</span>
                        <span className="tv-header__title-italic">Archive</span>
                    </h1>
                    <p className="tv-header__desc">
                        여행에서 포착한 색, 빛, 장면들을 필름처럼 현상합니다.
                        지도에서 지역을 선택하면 해당 앨범이 펼쳐집니다.
                    </p>
                    <button
                        className={`tv-sync-btn${syncing ? ' is-syncing' : ''}`}
                        onClick={handleSync}
                        disabled={syncing}
                        title="사진 폴더 동기화"
                    >
                        <svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden>
                            <path d="M1.5 8a6.5 6.5 0 0 1 11.25-4.43" stroke="currentColor" strokeWidth="1.3" strokeLinecap="round"/>
                            <path d="M14.5 8a6.5 6.5 0 0 1-11.25 4.43" stroke="currentColor" strokeWidth="1.3" strokeLinecap="round"/>
                            <path d="M12 1.5v2.5h-2.5" stroke="currentColor" strokeWidth="1.3" strokeLinecap="round" strokeLinejoin="round"/>
                            <path d="M4 14.5v-2.5h2.5" stroke="currentColor" strokeWidth="1.3" strokeLinecap="round" strokeLinejoin="round"/>
                        </svg>
                        {syncing ? '동기화 중…' : '동기화'}
                    </button>
                    {syncResult && (
                        <div className={`tv-sync-toast${syncResult.error ? ' is-error' : ''}`}>
                            {syncResult.error
                                ? `동기화 실패: ${syncResult.error}`
                                : `+${syncResult.added} 추가 / ${syncResult.removed} 삭제 / 썸네일 ${syncResult.thumbs_generated}개${syncResult.discovered ? ` / 신규 폴더 ${syncResult.discovered}개 발견` : ''} (${syncResult.duration_sec}s)`
                            }
                        </div>
                    )}
                </div>

                {selectedRegion ? (
                    <div className="tv-header__active-region" style={{ '--accent': regionAccent }}>
                        <div className="tv-header__region-indicator" />
                        <div>
                            <p className="tv-header__region-label">Currently viewing</p>
                            <p className="tv-header__region-name">{selectedRegion}</p>
                        </div>
                    </div>
                ) : (
                    <div className="tv-header__hint">
                        <div className="tv-header__hint-icon" aria-hidden>
                            <svg width="32" height="32" viewBox="0 0 32 32" fill="none">
                                <circle cx="16" cy="16" r="14" stroke="currentColor" strokeWidth="1" strokeDasharray="3 3"/>
                                <path d="M16 8v8l5 3" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"/>
                            </svg>
                        </div>
                        <p className="tv-header__hint-text">지도에서 지역을 선택하세요</p>
                    </div>
                )}
            </header>

            {/* ═══════════════════════════════════════
                MAP — collapsible mini-map
            ═══════════════════════════════════════ */}
            <MiniMap
                geojson={regions}
                selectedRegionId={selectedRegion}
                onSelectRegion={handleSelectRegion}
                onClearRegion={handleClearRegion}
            />

            {/* ═══════════════════════════════════════
                ALBUM CARDS
            ═══════════════════════════════════════ */}
            <section className="tv-albums">
                {loadingAlbums && filteredAlbums.length === 0 && (
                    <div className="tv-state">
                        <div className="tv-state__loader">
                            <span /><span /><span />
                        </div>
                        <p>Loading albums…</p>
                    </div>
                )}

                {!loadingAlbums && filteredAlbums.length === 0 && (
                    <p className="tv-state tv-state--empty">
                        {selectedRegion
                            ? '이 지역에는 아직 앨범이 없습니다.'
                            : '지도에서 지역을 선택하거나 전체 앨범을 둘러보세요.'}
                    </p>
                )}

                {filteredAlbums.length > 0 && (
                    <div className="tv-albums__grid">
                        {filteredAlbums.map((album) => (
                            <AlbumCard
                                key={album.id}
                                album={album}
                                onClick={handleOpenAlbum}
                            />
                        ))}
                    </div>
                )}
            </section>

            {/* ═══════════════════════════════════════
                ALBUM DETAIL OVERLAY
            ═══════════════════════════════════════ */}
            {selectedAlbum && (
                <AlbumDetail
                    album={selectedAlbum}
                    sourceRect={albumSourceRect}
                    photos={photos}
                    photoSummary={photoSummary}
                    loading={loading}
                    loadingMore={loadingMore}
                    hasNext={hasNext}
                    error={error}
                    onClose={handleCloseAlbum}
                    onLoadMore={handleLoadMore}
                    onReload={handleReload}
                    onCoverChange={refreshAlbums}
                />
            )}
        </div>
    );
};

export default Travel;
