/// 앨범 상세 화면
library;

import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:go_router/go_router.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:lucide_icons/lucide_icons.dart';
import 'package:photo_view/photo_view.dart';
import 'package:photo_view/photo_view_gallery.dart';
import 'package:modal_bottom_sheet/modal_bottom_sheet.dart';
import 'package:video_player/video_player.dart';
import 'package:chewie/chewie.dart';
import '../../core/constants.dart';
import '../../models/album.dart';
import '../../services/albums_service.dart';
import '../../services/download_service.dart';

class AlbumDetailView extends StatefulWidget {
  final String albumName;

  const AlbumDetailView({super.key, required this.albumName});

  @override
  State<AlbumDetailView> createState() => _AlbumDetailViewState();
}

class _AlbumDetailViewState extends State<AlbumDetailView> {
  late Future<Album> _albumFuture;
  bool _showAllTracks = false;

  @override
  void initState() {
    super.initState();
    _albumFuture = getAlbumByName(widget.albumName);
  }

  String _formatDate(String? date) {
    if (date == null || date.length < 10) return '';
    return '${date.substring(0, 4)}.${date.substring(5, 7)}.${date.substring(8, 10)}';
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: AppColors.background,
      appBar: AppBar(
        backgroundColor: Colors.white,
        foregroundColor: AppColors.textPrimary,
        elevation: 0,
        scrolledUnderElevation: 0,
        leading: IconButton(
          icon: const Icon(LucideIcons.arrowLeft),
          onPressed: () => context.pop(),
        ),
        title: const Text('앨범', style: TextStyle(fontSize: 18, fontWeight: FontWeight.w600)),
      ),
      body: FutureBuilder<Album>(
        future: _albumFuture,
        builder: (context, snapshot) {
          if (snapshot.connectionState == ConnectionState.waiting) {
            return const Center(
              child: CircularProgressIndicator(color: AppColors.primary),
            );
          }

          if (snapshot.hasError) {
            return Center(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  const Icon(LucideIcons.alertCircle, size: 48, color: AppColors.textTertiary),
                  const SizedBox(height: 16),
                  Text(
                    '앨범을 불러오는데 실패했습니다',
                    style: const TextStyle(color: AppColors.textSecondary),
                  ),
                  const SizedBox(height: 8),
                  Padding(
                    padding: const EdgeInsets.symmetric(horizontal: 32),
                    child: Text(
                      snapshot.error.toString(),
                      style: const TextStyle(fontSize: 12, color: AppColors.textTertiary),
                      textAlign: TextAlign.center,
                    ),
                  ),
                  const SizedBox(height: 16),
                  Row(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                      TextButton(
                        onPressed: () {
                          setState(() {
                            _albumFuture = getAlbumByName(widget.albumName);
                          });
                        },
                        child: const Text('다시 시도'),
                      ),
                      TextButton(
                        onPressed: () => context.pop(),
                        child: const Text('뒤로 가기'),
                      ),
                    ],
                  ),
                ],
              ),
            );
          }

          if (!snapshot.hasData) {
            return Center(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  const Icon(LucideIcons.disc3, size: 48, color: AppColors.textTertiary),
                  const SizedBox(height: 16),
                  const Text('앨범을 찾을 수 없습니다'),
                  const SizedBox(height: 16),
                  TextButton(
                    onPressed: () => context.pop(),
                    child: const Text('뒤로 가기'),
                  ),
                ],
              ),
            );
          }

          final album = snapshot.data!;
          final allPhotos = album.allConceptPhotos;
          final displayTracks = _showAllTracks
              ? album.tracks
              : album.tracks?.take(5).toList();

          return CustomScrollView(
            physics: const ClampingScrollPhysics(),
            slivers: [
              // 히어로 섹션
              SliverToBoxAdapter(
                child: _HeroSection(album: album, formatDate: _formatDate),
              ),

              // 티저 이미지
              if (album.teasers != null && album.teasers!.isNotEmpty)
                SliverToBoxAdapter(
                  child: _TeaserSection(teasers: album.teasers!),
                ),

              // 수록곡
              if (album.tracks != null && album.tracks!.isNotEmpty)
                SliverToBoxAdapter(
                  child: _TracksSection(
                    album: album,
                    albumName: widget.albumName,
                    displayTracks: displayTracks,
                    showAllTracks: _showAllTracks,
                    onToggle: () => setState(() => _showAllTracks = !_showAllTracks),
                  ),
                ),

              // 컨셉 포토
              if (allPhotos.isNotEmpty)
                SliverToBoxAdapter(
                  child: _ConceptPhotosSection(
                    photos: allPhotos,
                    albumName: widget.albumName,
                  ),
                ),

              // 하단 여백 (컨셉 포토가 없을 때만)
              if (allPhotos.isEmpty)
                SliverToBoxAdapter(
                  child: SizedBox(height: 16 + MediaQuery.of(context).padding.bottom),
                ),
            ],
          );
        },
      ),
    );
  }
}

/// 히어로 섹션
class _HeroSection extends StatelessWidget {
  final Album album;
  final String Function(String?) formatDate;

  const _HeroSection({required this.album, required this.formatDate});

  @override
  Widget build(BuildContext context) {
    return ClipRect(
      child: Stack(
        clipBehavior: Clip.hardEdge,
        children: [
          // 배경 블러 이미지
          if (album.coverMediumUrl != null)
            Positioned.fill(
              child: ImageFiltered(
                imageFilter: ImageFilter.blur(sigmaX: 30, sigmaY: 30),
                child: Opacity(
                  opacity: 0.3,
                  child: CachedNetworkImage(
                    imageUrl: album.coverMediumUrl!,
                    fit: BoxFit.cover,
                  ),
                ),
              ),
            ),
          // 그라데이션 오버레이
          Positioned.fill(
            child: Container(
              decoration: BoxDecoration(
                gradient: LinearGradient(
                  begin: Alignment.topCenter,
                  end: Alignment.bottomCenter,
                  colors: [
                    Colors.white.withValues(alpha: 0.6),
                    Colors.white.withValues(alpha: 0.8),
                    AppColors.background,
                  ],
                ),
              ),
            ),
          ),
          // 콘텐츠
          Padding(
          padding: const EdgeInsets.fromLTRB(20, 16, 20, 20),
          child: Column(
            children: [
              // 앨범 커버
              Container(
                width: 176,
                height: 176,
                decoration: BoxDecoration(
                  borderRadius: BorderRadius.circular(16),
                  boxShadow: [
                    BoxShadow(
                      color: Colors.black.withValues(alpha: 0.2),
                      blurRadius: 20,
                      offset: const Offset(0, 8),
                    ),
                  ],
                ),
                child: ClipRRect(
                  borderRadius: BorderRadius.circular(16),
                  child: album.coverMediumUrl != null
                      ? CachedNetworkImage(
                          imageUrl: album.coverMediumUrl!,
                          fit: BoxFit.cover,
                          placeholder: (context, url) => Container(
                            color: AppColors.divider,
                          ),
                          errorWidget: (context, url, error) => Container(
                            color: AppColors.divider,
                            child: const Icon(
                              LucideIcons.disc3,
                              size: 64,
                              color: AppColors.textTertiary,
                            ),
                          ),
                        )
                      : Container(
                          color: AppColors.divider,
                          child: const Icon(
                            LucideIcons.disc3,
                            size: 64,
                            color: AppColors.textTertiary,
                          ),
                        ),
                ),
              ),
              const SizedBox(height: 16),
              // 앨범 타입 뱃지
              Container(
                padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 4),
                decoration: BoxDecoration(
                  color: AppColors.primary.withValues(alpha: 0.1),
                  borderRadius: BorderRadius.circular(20),
                ),
                child: Text(
                  album.albumType ?? '',
                  style: const TextStyle(
                    fontSize: 12,
                    fontWeight: FontWeight.w500,
                    color: AppColors.primary,
                  ),
                ),
              ),
              const SizedBox(height: 8),
              // 앨범 제목
              Text(
                album.title,
                style: const TextStyle(
                  fontSize: 24,
                  fontWeight: FontWeight.bold,
                  color: AppColors.textPrimary,
                ),
                textAlign: TextAlign.center,
              ),
              const SizedBox(height: 12),
              // 메타 정보
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  _MetaItem(
                    icon: LucideIcons.calendar,
                    text: formatDate(album.releaseDate),
                  ),
                  const SizedBox(width: 16),
                  _MetaItem(
                    icon: LucideIcons.music2,
                    text: '${album.tracks?.length ?? 0}곡',
                  ),
                  const SizedBox(width: 16),
                  _MetaItem(
                    icon: LucideIcons.clock,
                    text: album.totalDuration,
                  ),
                ],
              ),
              // 앨범 소개 버튼
              if (album.description != null && album.description!.isNotEmpty) ...[
                const SizedBox(height: 12),
                GestureDetector(
                  onTap: () => _showDescriptionModal(context, album.description!),
                  child: Container(
                    padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
                    decoration: BoxDecoration(
                      color: Colors.white.withValues(alpha: 0.8),
                      borderRadius: BorderRadius.circular(20),
                      boxShadow: [
                        BoxShadow(
                          color: Colors.black.withValues(alpha: 0.05),
                          blurRadius: 4,
                        ),
                      ],
                    ),
                    child: const Row(
                      mainAxisSize: MainAxisSize.min,
                      children: [
                        Icon(LucideIcons.fileText, size: 14, color: AppColors.textSecondary),
                        SizedBox(width: 4),
                        Text(
                          '앨범 소개',
                          style: TextStyle(
                            fontSize: 12,
                            color: AppColors.textSecondary,
                          ),
                        ),
                      ],
                    ),
                  ),
                ),
              ],
            ],
          ),
        ),
        ],
      ),
    );
  }

  void _showDescriptionModal(BuildContext context, String description) {
    showBarModalBottomSheet(
      context: context,
      backgroundColor: Colors.white,
      shape: const RoundedRectangleBorder(
        borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
      ),
      builder: (context) => _DescriptionContent(description: description),
    );
  }
}

/// 메타 정보 아이템
class _MetaItem extends StatelessWidget {
  final IconData icon;
  final String text;

  const _MetaItem({required this.icon, required this.text});

  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisSize: MainAxisSize.min,
      children: [
        Icon(icon, size: 14, color: AppColors.textSecondary),
        const SizedBox(width: 4),
        Text(
          text,
          style: const TextStyle(
            fontSize: 13,
            color: AppColors.textSecondary,
          ),
        ),
      ],
    );
  }
}

/// 티저 이미지 섹션
class _TeaserSection extends StatelessWidget {
  final List<Teaser> teasers;

  const _TeaserSection({required this.teasers});

  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: const BoxDecoration(
        color: AppColors.background,
        border: Border(
          bottom: BorderSide(color: AppColors.divider),
        ),
      ),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          const Padding(
            padding: EdgeInsets.fromLTRB(16, 16, 16, 12),
            child: Text(
              '티저 이미지',
              style: TextStyle(
                fontSize: 14,
                fontWeight: FontWeight.w600,
              ),
            ),
          ),
          SizedBox(
            height: 96,
            child: ListView.builder(
              scrollDirection: Axis.horizontal,
              padding: const EdgeInsets.symmetric(horizontal: 16),
              clipBehavior: Clip.none,
              itemCount: teasers.length,
              itemBuilder: (context, index) {
                final teaser = teasers[index];
                return Padding(
                  padding: EdgeInsets.only(right: index < teasers.length - 1 ? 12 : 0),
                  child: GestureDetector(
                    onTap: () => _showImageViewer(context, teasers, index),
                    child: _TeaserThumbnail(teaser: teaser),
                  ),
                );
              },
            ),
          ),
          const SizedBox(height: 16),
        ],
      ),
    );
  }

  void _showImageViewer(BuildContext context, List<Teaser> teasers, int initialIndex) {
    Navigator.of(context).push(
      PageRouteBuilder(
        opaque: false,
        pageBuilder: (context, animation, secondaryAnimation) {
          return _TeaserViewer(
            teasers: teasers,
            initialIndex: initialIndex,
          );
        },
        transitionsBuilder: (context, animation, secondaryAnimation, child) {
          return FadeTransition(opacity: animation, child: child);
        },
      ),
    );
  }
}

/// 티저 썸네일
class _TeaserThumbnail extends StatelessWidget {
  final Teaser teaser;

  const _TeaserThumbnail({required this.teaser});

  @override
  Widget build(BuildContext context) {
    final isVideo = teaser.mediaType == 'video';
    final imageUrl = teaser.thumbUrl ?? teaser.originalUrl;

    return Container(
      width: 96,
      height: 96,
      decoration: BoxDecoration(
        color: AppColors.divider,
        borderRadius: BorderRadius.circular(16),
      ),
      child: ClipRRect(
        borderRadius: BorderRadius.circular(16),
        child: Stack(
          fit: StackFit.expand,
          children: [
            // 썸네일 이미지
            if (imageUrl != null)
              CachedNetworkImage(
                imageUrl: imageUrl,
                fit: BoxFit.cover,
                placeholder: (context, url) => Container(color: AppColors.divider),
                errorWidget: (context, url, error) => _buildPlaceholder(),
              )
            else
              _buildPlaceholder(),
            // 동영상 재생 버튼 오버레이
            if (isVideo)
              Container(
                color: Colors.black.withValues(alpha: 0.3),
                child: const Center(
                  child: CircleAvatar(
                    radius: 16,
                    backgroundColor: Colors.white,
                    child: Icon(
                      LucideIcons.play,
                      size: 18,
                      color: AppColors.textPrimary,
                    ),
                  ),
                ),
              ),
          ],
        ),
      ),
    );
  }

  Widget _buildPlaceholder() {
    return Container(
      color: AppColors.divider,
      child: const Center(
        child: Icon(
          LucideIcons.video,
          size: 32,
          color: AppColors.textTertiary,
        ),
      ),
    );
  }
}

/// 수록곡 섹션
class _TracksSection extends StatelessWidget {
  final Album album;
  final String albumName;
  final List<Track>? displayTracks;
  final bool showAllTracks;
  final VoidCallback onToggle;

  const _TracksSection({
    required this.album,
    required this.albumName,
    required this.displayTracks,
    required this.showAllTracks,
    required this.onToggle,
  });

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: const EdgeInsets.all(16),
      decoration: const BoxDecoration(
        color: AppColors.background,
        border: Border(
          bottom: BorderSide(color: AppColors.divider),
        ),
      ),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          const Text(
            '수록곡',
            style: TextStyle(
              fontSize: 14,
              fontWeight: FontWeight.w600,
            ),
          ),
          const SizedBox(height: 12),
          ...?displayTracks?.map((track) => _TrackItem(
                track: track,
                albumName: albumName,
              )),
          if (album.tracks != null && album.tracks!.length > 5)
            GestureDetector(
              onTap: onToggle,
              child: Padding(
                padding: const EdgeInsets.only(top: 8),
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    Text(
                      showAllTracks
                          ? '접기'
                          : '${album.tracks!.length - 5}곡 더보기',
                      style: const TextStyle(
                        fontSize: 14,
                        color: AppColors.textSecondary,
                      ),
                    ),
                    Icon(
                      showAllTracks ? LucideIcons.chevronUp : LucideIcons.chevronDown,
                      size: 18,
                      color: AppColors.textSecondary,
                    ),
                  ],
                ),
              ),
            ),
        ],
      ),
    );
  }
}

/// 트랙 아이템
class _TrackItem extends StatelessWidget {
  final Track track;
  final String albumName;

  const _TrackItem({required this.track, required this.albumName});

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () {
        final encodedTrackTitle = Uri.encodeComponent(track.title);
        context.push('/album/$albumName/track/$encodedTrackTitle');
      },
      behavior: HitTestBehavior.opaque,
      child: Padding(
        padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 12),
        child: Row(
          children: [
            // 트랙 번호
            SizedBox(
              width: 24,
              child: Text(
                track.trackNumber.toString().padLeft(2, '0'),
                style: const TextStyle(
                  fontSize: 14,
                  color: AppColors.textTertiary,
                  fontFeatures: [FontFeature.tabularFigures()],
                ),
              ),
            ),
            const SizedBox(width: 12),
            // 트랙 제목
            Expanded(
              child: Row(
                children: [
                  Flexible(
                    child: Text(
                      track.title,
                      style: TextStyle(
                        fontSize: 14,
                        fontWeight: FontWeight.w500,
                        color: track.isTitleTrack == 1
                            ? AppColors.primary
                            : AppColors.textPrimary,
                      ),
                      overflow: TextOverflow.ellipsis,
                    ),
                  ),
                  if (track.isTitleTrack == 1) ...[
                    const SizedBox(width: 8),
                    Container(
                      padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
                      decoration: BoxDecoration(
                        color: AppColors.primary,
                        borderRadius: BorderRadius.circular(4),
                      ),
                      child: const Text(
                        'TITLE',
                        style: TextStyle(
                          fontSize: 10,
                          fontWeight: FontWeight.bold,
                          color: Colors.white,
                        ),
                      ),
                    ),
                  ],
                ],
              ),
            ),
            const SizedBox(width: 8),
            // 재생 시간
            Text(
              track.duration ?? '-',
              style: const TextStyle(
                fontSize: 12,
                color: AppColors.textTertiary,
                fontFeatures: [FontFeature.tabularFigures()],
              ),
            ),
            // 화살표 아이콘
            const SizedBox(width: 8),
            const Icon(
              LucideIcons.chevronRight,
              size: 16,
              color: AppColors.textTertiary,
            ),
          ],
        ),
      ),
    );
  }
}

/// 컨셉 포토 섹션
class _ConceptPhotosSection extends StatelessWidget {
  final List<ConceptPhoto> photos;
  final String albumName;

  const _ConceptPhotosSection({required this.photos, required this.albumName});

  @override
  Widget build(BuildContext context) {
    final bottomPadding = MediaQuery.of(context).padding.bottom;

    return Container(
      color: AppColors.background,
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          const Padding(
            padding: EdgeInsets.fromLTRB(16, 16, 16, 12),
            child: Text(
              '컨셉 포토',
              style: TextStyle(
                fontSize: 14,
                fontWeight: FontWeight.w600,
              ),
            ),
          ),
          GridView.builder(
            shrinkWrap: true,
            physics: const NeverScrollableScrollPhysics(),
            padding: const EdgeInsets.symmetric(horizontal: 16),
            clipBehavior: Clip.none,
            gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
              crossAxisCount: 3,
              crossAxisSpacing: 8,
              mainAxisSpacing: 8,
            ),
            itemCount: photos.length > 6 ? 6 : photos.length,
            itemBuilder: (context, index) {
              final photo = photos[index];
              return GestureDetector(
                onTap: () => _showImageViewer(context, photo),
                child: Container(
                  decoration: BoxDecoration(
                    color: AppColors.divider,
                    borderRadius: BorderRadius.circular(12),
                  ),
                  child: ClipRRect(
                    borderRadius: BorderRadius.circular(12),
                    child: photo.thumbUrl != null || photo.mediumUrl != null
                        ? CachedNetworkImage(
                            imageUrl: photo.thumbUrl ?? photo.mediumUrl!,
                            fit: BoxFit.cover,
                            placeholder: (context, url) => Container(
                              color: AppColors.divider,
                            ),
                            errorWidget: (context, url, error) => const SizedBox(),
                          )
                        : const SizedBox(),
                  ),
                ),
              );
            },
          ),
          // 전체보기 버튼
          if (photos.length > 6)
            Padding(
              padding: EdgeInsets.fromLTRB(16, 12, 16, 16 + bottomPadding),
              child: SizedBox(
                width: double.infinity,
                child: ElevatedButton(
                  onPressed: () {
                    context.push('/album/$albumName/gallery');
                  },
                  style: ElevatedButton.styleFrom(
                    backgroundColor: AppColors.primary.withValues(alpha: 0.05),
                    foregroundColor: AppColors.primary,
                    elevation: 0,
                    padding: const EdgeInsets.symmetric(vertical: 12),
                    shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.circular(12),
                    ),
                  ),
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                      Text('전체 ${photos.length}장 보기'),
                      const SizedBox(width: 4),
                      const Icon(LucideIcons.chevronRight, size: 18),
                    ],
                  ),
                ),
              ),
            ),
          // 전체보기 버튼이 없을 때의 하단 여백
          if (photos.length <= 6)
            SizedBox(height: 16 + bottomPadding),
        ],
      ),
    );
  }

  void _showImageViewer(BuildContext context, ConceptPhoto photo) {
    Navigator.of(context).push(
      PageRouteBuilder(
        opaque: false,
        pageBuilder: (context, animation, secondaryAnimation) {
          return _SingleImageViewer(
            imageUrl: photo.originalUrl ?? '',
          );
        },
        transitionsBuilder: (context, animation, secondaryAnimation, child) {
          return FadeTransition(opacity: animation, child: child);
        },
      ),
    );
  }
}

/// 티저 뷰어 (이미지 + 동영상 지원)
class _TeaserViewer extends StatefulWidget {
  final List<Teaser> teasers;
  final int initialIndex;

  const _TeaserViewer({
    required this.teasers,
    required this.initialIndex,
  });

  @override
  State<_TeaserViewer> createState() => _TeaserViewerState();
}

class _TeaserViewerState extends State<_TeaserViewer> {
  late PageController _pageController;
  late int _currentIndex;

  @override
  void initState() {
    super.initState();
    _currentIndex = widget.initialIndex;
    _pageController = PageController(initialPage: widget.initialIndex);
  }

  @override
  void dispose() {
    _pageController.dispose();
    super.dispose();
  }

  /// 다운로드 (이미지 또는 동영상)
  Future<void> _download() async {
    final teaser = widget.teasers[_currentIndex];
    final isVideo = teaser.mediaType == 'video';
    final url = isVideo ? (teaser.videoUrl ?? teaser.originalUrl) : teaser.originalUrl;
    if (url == null || url.isEmpty) return;

    final taskId = await downloadImage(url);
    if (taskId != null && mounted) {
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(
          content: Text('다운로드를 시작합니다'),
          duration: Duration(seconds: 2),
        ),
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    final bottomPadding = MediaQuery.of(context).padding.bottom;
    final topPadding = MediaQuery.of(context).padding.top;

    return AnnotatedRegion<SystemUiOverlayStyle>(
      value: SystemUiOverlayStyle.light,
      child: Scaffold(
        backgroundColor: Colors.black,
        body: Stack(
          children: [
            // 갤러리
            PhotoViewGallery.builder(
              pageController: _pageController,
              itemCount: widget.teasers.length,
              allowImplicitScrolling: true,
              onPageChanged: (index) {
                setState(() => _currentIndex = index);
              },
              backgroundDecoration: const BoxDecoration(color: Colors.black),
              builder: (context, index) {
                final teaser = widget.teasers[index];
                final isVideoItem = teaser.mediaType == 'video';

                // 동영상인 경우 Chewie 플레이어로 재생
                if (isVideoItem) {
                  return PhotoViewGalleryPageOptions.customChild(
                    child: _VideoTeaserPage(teaser: teaser),
                  );
                }

                // 이미지인 경우
                final imageUrl = teaser.thumbUrl ?? teaser.originalUrl;
                if (imageUrl == null || imageUrl.isEmpty) {
                  return PhotoViewGalleryPageOptions.customChild(
                    child: const Center(
                      child: Icon(
                        LucideIcons.imageOff,
                        color: Colors.white54,
                        size: 64,
                      ),
                    ),
                  );
                }

                // 이미지인 경우 PhotoView 사용
                return PhotoViewGalleryPageOptions(
                  imageProvider: CachedNetworkImageProvider(teaser.originalUrl ?? imageUrl),
                  minScale: PhotoViewComputedScale.contained,
                  maxScale: PhotoViewComputedScale.covered * 3,
                  initialScale: PhotoViewComputedScale.contained,
                  heroAttributes: PhotoViewHeroAttributes(tag: 'teaser_$index'),
                );
              },
              loadingBuilder: (context, event) => const Center(
                child: CircularProgressIndicator(
                  color: Colors.white54,
                  strokeWidth: 2,
                ),
              ),
            ),
            // 상단 헤더
            Positioned(
              top: topPadding + 8,
              left: 0,
              right: 0,
              child: Padding(
                padding: const EdgeInsets.symmetric(horizontal: 16),
                child: Row(
                  children: [
                    // 왼쪽: 닫기 버튼
                    Expanded(
                      child: Align(
                        alignment: Alignment.centerLeft,
                        child: GestureDetector(
                          onTap: () => Navigator.pop(context),
                          child: const Padding(
                            padding: EdgeInsets.all(4),
                            child: Icon(LucideIcons.x, color: Colors.white70, size: 24),
                          ),
                        ),
                      ),
                    ),
                    // 가운데: 페이지 번호
                    if (widget.teasers.length > 1)
                      Text(
                        '${_currentIndex + 1} / ${widget.teasers.length}',
                        style: const TextStyle(
                          color: Colors.white70,
                          fontSize: 14,
                          fontFeatures: [FontFeature.tabularFigures()],
                        ),
                      ),
                    // 오른쪽: 다운로드 버튼
                    Expanded(
                      child: Align(
                        alignment: Alignment.centerRight,
                        child: GestureDetector(
                          onTap: _download,
                          child: const Padding(
                            padding: EdgeInsets.all(4),
                            child: Icon(
                              LucideIcons.download,
                              color: Colors.white70,
                              size: 22,
                            ),
                          ),
                        ),
                      ),
                    ),
                  ],
                ),
              ),
            ),
            // 하단 인디케이터
            if (widget.teasers.length > 1)
              Positioned(
                bottom: bottomPadding + 16,
                left: 0,
                right: 0,
                child: _SlidingIndicator(
                  count: widget.teasers.length,
                  currentIndex: _currentIndex,
                  onTap: (index) {
                    _pageController.animateToPage(
                      index,
                      duration: const Duration(milliseconds: 300),
                      curve: Curves.easeOut,
                    );
                  },
                ),
              ),
          ],
        ),
      ),
    );
  }
}

/// 동영상 티저 페이지 (Chewie로 내부 재생)
class _VideoTeaserPage extends StatefulWidget {
  final Teaser teaser;

  const _VideoTeaserPage({required this.teaser});

  @override
  State<_VideoTeaserPage> createState() => _VideoTeaserPageState();
}

class _VideoTeaserPageState extends State<_VideoTeaserPage> {
  VideoPlayerController? _videoController;
  ChewieController? _chewieController;
  bool _isInitialized = false;
  bool _hasError = false;

  @override
  void initState() {
    super.initState();
    _initializePlayer();
  }

  Future<void> _initializePlayer() async {
    final videoUrl = widget.teaser.videoUrl ?? widget.teaser.originalUrl;
    if (videoUrl == null) {
      setState(() => _hasError = true);
      return;
    }

    try {
      final videoController = VideoPlayerController.networkUrl(
        Uri.parse(videoUrl),
      );
      _videoController = videoController;

      await videoController.initialize();

      final chewieController = ChewieController(
        videoPlayerController: videoController,
        autoPlay: false,
        looping: false,
        showControls: true,
        allowFullScreen: false,
        allowMuting: true,
        showOptions: false,
        placeholder: Container(color: Colors.black),
        errorBuilder: (context, errorMessage) => Center(
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              const Icon(LucideIcons.alertCircle, color: Colors.white54, size: 48),
              const SizedBox(height: 8),
              Text(
                '동영상을 재생할 수 없습니다',
                style: const TextStyle(color: Colors.white54),
              ),
            ],
          ),
        ),
      );
      _chewieController = chewieController;

      if (mounted) {
        setState(() => _isInitialized = true);
      }
    } catch (e) {
      if (mounted) {
        setState(() => _hasError = true);
      }
    }
  }

  @override
  void dispose() {
    _chewieController?.dispose();
    _videoController?.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    if (_hasError) {
      return const Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            Icon(LucideIcons.alertCircle, color: Colors.white54, size: 48),
            SizedBox(height: 8),
            Text(
              '동영상을 불러올 수 없습니다',
              style: TextStyle(color: Colors.white54),
            ),
          ],
        ),
      );
    }

    if (!_isInitialized || _chewieController == null) {
      return const Center(
        child: CircularProgressIndicator(
          color: Colors.white54,
          strokeWidth: 2,
        ),
      );
    }

    return Center(
      child: AspectRatio(
        aspectRatio: _videoController!.value.aspectRatio,
        child: Chewie(controller: _chewieController!),
      ),
    );
  }
}

/// 컨셉 포토용 이미지 뷰어 (단일 이미지, 스와이프 없음)
class _SingleImageViewer extends StatelessWidget {
  final String imageUrl;

  const _SingleImageViewer({required this.imageUrl});

  /// 이미지 다운로드 (시스템 다운로드 매니저 사용)
  Future<void> _downloadImage(BuildContext context) async {
    if (imageUrl.isEmpty) return;

    final taskId = await downloadImage(imageUrl);
    if (taskId != null && context.mounted) {
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(
          content: Text('다운로드를 시작합니다'),
          duration: Duration(seconds: 2),
        ),
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    final topPadding = MediaQuery.of(context).padding.top;

    return AnnotatedRegion<SystemUiOverlayStyle>(
      value: SystemUiOverlayStyle.light,
      child: Scaffold(
        backgroundColor: Colors.black,
        body: Stack(
          children: [
            // 이미지 (핀치줌 - 전체 화면으로 확대 가능)
            imageUrl.isNotEmpty
                ? PhotoView(
                    imageProvider: CachedNetworkImageProvider(imageUrl),
                    minScale: PhotoViewComputedScale.contained,
                    maxScale: PhotoViewComputedScale.covered * 3,
                    initialScale: PhotoViewComputedScale.contained,
                    backgroundDecoration: const BoxDecoration(color: Colors.black),
                    loadingBuilder: (context, event) => const Center(
                      child: CircularProgressIndicator(
                        color: Colors.white54,
                        strokeWidth: 2,
                      ),
                    ),
                    errorBuilder: (context, error, stackTrace) => const Center(
                      child: Icon(
                        LucideIcons.imageOff,
                        color: Colors.white54,
                        size: 64,
                      ),
                    ),
                  )
                : const Center(
                    child: Icon(
                      LucideIcons.imageOff,
                      color: Colors.white54,
                      size: 64,
                    ),
                  ),
            // 상단 헤더
            Positioned(
              top: topPadding + 8,
              left: 0,
              right: 0,
              child: Padding(
                padding: const EdgeInsets.symmetric(horizontal: 16),
                child: Row(
                  children: [
                    // 왼쪽: 닫기 버튼
                    Expanded(
                      child: Align(
                        alignment: Alignment.centerLeft,
                        child: GestureDetector(
                          onTap: () => Navigator.pop(context),
                          child: const Padding(
                            padding: EdgeInsets.all(4),
                            child: Icon(LucideIcons.x, color: Colors.white70, size: 24),
                          ),
                        ),
                      ),
                    ),
                    // 오른쪽: 다운로드 버튼
                    Expanded(
                      child: Align(
                        alignment: Alignment.centerRight,
                        child: GestureDetector(
                          onTap: () => _downloadImage(context),
                          child: const Padding(
                            padding: EdgeInsets.all(4),
                            child: Icon(LucideIcons.download, color: Colors.white70, size: 22),
                          ),
                        ),
                      ),
                    ),
                  ],
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

/// 슬라이딩 인디케이터
class _SlidingIndicator extends StatelessWidget {
  final int count;
  final int currentIndex;
  final Function(int) onTap;

  const _SlidingIndicator({
    required this.count,
    required this.currentIndex,
    required this.onTap,
  });

  @override
  Widget build(BuildContext context) {
    const double width = 120;
    const double dotSpacing = 18;
    const double activeDotSize = 12;
    const double inactiveDotSize = 10;

    final double halfWidth = width / 2;
    final double translateX = -(currentIndex * dotSpacing) + halfWidth - (activeDotSize / 2);

    return Center(
      child: SizedBox(
        width: width,
        height: 20,
        child: ShaderMask(
          shaderCallback: (Rect bounds) {
            return const LinearGradient(
              colors: [
                Colors.transparent,
                Colors.white,
                Colors.white,
                Colors.transparent,
              ],
              stops: [0.0, 0.15, 0.85, 1.0],
            ).createShader(bounds);
          },
          blendMode: BlendMode.dstIn,
          child: Stack(
            children: [
              // 슬라이딩 점들
              AnimatedPositioned(
                duration: const Duration(milliseconds: 300),
                curve: Curves.easeOutCubic,
                left: translateX,
                top: 0,
                bottom: 0,
                child: Row(
                  mainAxisSize: MainAxisSize.min,
                  children: List.generate(count, (index) {
                    final isActive = index == currentIndex;
                    return GestureDetector(
                      onTap: () => onTap(index),
                      child: Container(
                        width: dotSpacing,
                        alignment: Alignment.center,
                        child: AnimatedContainer(
                          duration: const Duration(milliseconds: 300),
                          width: isActive ? activeDotSize : inactiveDotSize,
                          height: isActive ? activeDotSize : inactiveDotSize,
                          decoration: BoxDecoration(
                            shape: BoxShape.circle,
                            color: isActive
                                ? Colors.white
                                : Colors.white.withValues(alpha: 0.4),
                          ),
                        ),
                      ),
                    );
                  }),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

/// 앨범 소개 내용
class _DescriptionContent extends StatelessWidget {
  final String description;

  const _DescriptionContent({required this.description});

  @override
  Widget build(BuildContext context) {
    final bottomPadding = MediaQuery.of(context).padding.bottom;

    return Column(
      mainAxisSize: MainAxisSize.min,
      children: [
        // 헤더 (고정)
        Padding(
          padding: const EdgeInsets.fromLTRB(20, 16, 12, 12),
          child: Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              const Text(
                '앨범 소개',
                style: TextStyle(
                  fontSize: 18,
                  fontWeight: FontWeight.bold,
                ),
              ),
              GestureDetector(
                onTap: () => Navigator.pop(context),
                child: const Padding(
                  padding: EdgeInsets.all(8),
                  child: Icon(LucideIcons.x, size: 22),
                ),
              ),
            ],
          ),
        ),
        // 구분선
        Container(
          height: 0.5,
          color: AppColors.divider,
        ),
        // 내용 (스크롤)
        Flexible(
          child: SingleChildScrollView(
            controller: ModalScrollController.of(context),
            padding: EdgeInsets.fromLTRB(20, 20, 20, 20 + bottomPadding),
            child: Text(
              description,
              style: const TextStyle(
                fontSize: 14,
                height: 1.8,
                color: AppColors.textSecondary,
              ),
              textAlign: TextAlign.justify,
            ),
          ),
        ),
      ],
    );
  }
}
