/// 앨범 컨셉포토 갤러리 화면
library;

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 '../../core/constants.dart';
import '../../models/album.dart';
import '../../services/albums_service.dart';
import '../../services/download_service.dart';

class AlbumGalleryView extends StatefulWidget {
  final String albumName;

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

  @override
  State<AlbumGalleryView> createState() => _AlbumGalleryViewState();
}

class _AlbumGalleryViewState extends State<AlbumGalleryView> {
  late Future<Album> _albumFuture;
  bool _initialAnimationDone = false;

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

  @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),
                  const Text(
                    '사진을 불러오는데 실패했습니다',
                    style: TextStyle(color: AppColors.textSecondary),
                  ),
                  const SizedBox(height: 16),
                  TextButton(
                    onPressed: () {
                      setState(() {
                        _albumFuture = getAlbumByName(widget.albumName);
                      });
                    },
                    child: const Text('다시 시도'),
                  ),
                ],
              ),
            );
          }

          if (!snapshot.hasData) {
            return Center(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  const Icon(LucideIcons.image, 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 photos = _flattenPhotosWithConcept(album);

          // 초기 애니메이션이 끝났는지 표시
          if (!_initialAnimationDone) {
            WidgetsBinding.instance.addPostFrameCallback((_) {
              Future.delayed(const Duration(milliseconds: 600), () {
                if (mounted) {
                  setState(() => _initialAnimationDone = true);
                }
              });
            });
          }

          return CustomScrollView(
            physics: const ClampingScrollPhysics(),
            slivers: [

              // 앨범 헤더 카드
              SliverToBoxAdapter(
                child: _AlbumHeaderCard(album: album, photoCount: photos.length),
              ),

              // 2열 Masonry 그리드
              SliverToBoxAdapter(
                child: _MasonryGrid(
                  photos: photos,
                  skipAnimation: _initialAnimationDone,
                ),
              ),

              // 하단 여백
              SliverToBoxAdapter(
                child: SizedBox(height: 12 + MediaQuery.of(context).padding.bottom),
              ),
            ],
          );
        },
      ),
    );
  }

  /// 컨셉 포토를 플랫하게 펼치면서 concept 정보 유지
  List<ConceptPhoto> _flattenPhotosWithConcept(Album album) {
    if (album.conceptPhotos == null) return [];

    final List<ConceptPhoto> allPhotos = [];
    album.conceptPhotos!.forEach((concept, photos) {
      for (final photo in photos) {
        // concept이 'Default'가 아닌 경우에만 concept 값 설정
        allPhotos.add(ConceptPhoto(
          id: photo.id,
          originalUrl: photo.originalUrl,
          mediumUrl: photo.mediumUrl,
          thumbUrl: photo.thumbUrl,
          width: photo.width,
          height: photo.height,
          members: photo.members,
          concept: concept != 'Default' ? concept : null,
        ));
      }
    });
    return allPhotos;
  }
}

/// 앨범 헤더 카드
class _AlbumHeaderCard extends StatelessWidget {
  final Album album;
  final int photoCount;

  const _AlbumHeaderCard({required this.album, required this.photoCount});

  @override
  Widget build(BuildContext context) {
    return Container(
      margin: const EdgeInsets.all(16),
      padding: const EdgeInsets.all(16),
      decoration: BoxDecoration(
        gradient: LinearGradient(
          colors: [
            AppColors.primary.withValues(alpha: 0.05),
            AppColors.primary.withValues(alpha: 0.1),
          ],
        ),
        borderRadius: BorderRadius.circular(16),
      ),
      child: Row(
        children: [
          // 앨범 커버
          if (album.coverThumbUrl != null)
            Container(
              width: 56,
              height: 56,
              decoration: BoxDecoration(
                borderRadius: BorderRadius.circular(12),
                boxShadow: [
                  BoxShadow(
                    color: Colors.black.withValues(alpha: 0.1),
                    blurRadius: 4,
                  ),
                ],
              ),
              child: ClipRRect(
                borderRadius: BorderRadius.circular(12),
                child: CachedNetworkImage(
                  imageUrl: album.coverThumbUrl!,
                  fit: BoxFit.cover,
                  placeholder: (context, url) => Container(color: AppColors.divider),
                  errorWidget: (context, url, error) => Container(
                    color: AppColors.divider,
                    child: const Icon(LucideIcons.disc3, color: AppColors.textTertiary),
                  ),
                ),
              ),
            ),
          const SizedBox(width: 16),
          // 앨범 정보
          Expanded(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text(
                  '컨셉 포토',
                  style: TextStyle(
                    fontSize: 12,
                    fontWeight: FontWeight.w500,
                    color: AppColors.primary,
                  ),
                ),
                const SizedBox(height: 2),
                Text(
                  album.title,
                  style: const TextStyle(
                    fontSize: 16,
                    fontWeight: FontWeight.bold,
                  ),
                  overflow: TextOverflow.ellipsis,
                ),
                const SizedBox(height: 2),
                Text(
                  '$photoCount장의 사진',
                  style: const TextStyle(
                    fontSize: 12,
                    color: AppColors.textTertiary,
                  ),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

/// 2열 Masonry 그리드
class _MasonryGrid extends StatelessWidget {
  final List<ConceptPhoto> photos;
  final bool skipAnimation;

  const _MasonryGrid({required this.photos, this.skipAnimation = false});

  @override
  Widget build(BuildContext context) {
    final columns = _distributePhotos();

    return Padding(
      padding: const EdgeInsets.symmetric(horizontal: 12),
      child: Row(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          // 왼쪽 열
          Expanded(
            child: Column(
              children: columns.leftColumn.map((item) {
                return Padding(
                  padding: const EdgeInsets.only(bottom: 8),
                  child: _PhotoItem(
                    photo: item.photo,
                    index: item.originalIndex,
                    allPhotos: photos,
                    skipAnimation: skipAnimation,
                  ),
                );
              }).toList(),
            ),
          ),
          const SizedBox(width: 8),
          // 오른쪽 열
          Expanded(
            child: Column(
              children: columns.rightColumn.map((item) {
                return Padding(
                  padding: const EdgeInsets.only(bottom: 8),
                  child: _PhotoItem(
                    photo: item.photo,
                    index: item.originalIndex,
                    allPhotos: photos,
                    skipAnimation: skipAnimation,
                  ),
                );
              }).toList(),
            ),
          ),
        ],
      ),
    );
  }

  /// 사진을 2열로 균등 분배 (높이 기반)
  ({List<_PhotoWithIndex> leftColumn, List<_PhotoWithIndex> rightColumn}) _distributePhotos() {
    final List<_PhotoWithIndex> leftColumn = [];
    final List<_PhotoWithIndex> rightColumn = [];
    double leftHeight = 0;
    double rightHeight = 0;

    for (int i = 0; i < photos.length; i++) {
      final photo = photos[i];
      final aspectRatio = photo.aspectRatio;

      // 더 짧은 열에 사진 추가
      if (leftHeight <= rightHeight) {
        leftColumn.add(_PhotoWithIndex(photo: photo, originalIndex: i));
        leftHeight += aspectRatio;
      } else {
        rightColumn.add(_PhotoWithIndex(photo: photo, originalIndex: i));
        rightHeight += aspectRatio;
      }
    }

    return (leftColumn: leftColumn, rightColumn: rightColumn);
  }
}

/// 인덱스 정보를 포함한 사진
class _PhotoWithIndex {
  final ConceptPhoto photo;
  final int originalIndex;

  _PhotoWithIndex({required this.photo, required this.originalIndex});
}

/// 개별 사진 아이템 (애니메이션 포함)
class _PhotoItem extends StatefulWidget {
  final ConceptPhoto photo;
  final int index;
  final bool skipAnimation;
  final List<ConceptPhoto> allPhotos;

  const _PhotoItem({
    required this.photo,
    required this.index,
    required this.allPhotos,
    this.skipAnimation = false,
  });

  @override
  State<_PhotoItem> createState() => _PhotoItemState();
}

class _PhotoItemState extends State<_PhotoItem>
    with SingleTickerProviderStateMixin, AutomaticKeepAliveClientMixin {
  late AnimationController _controller;
  late Animation<double> _opacityAnimation;
  late Animation<Offset> _slideAnimation;
  bool _hasAnimated = false;

  @override
  bool get wantKeepAlive => true;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      duration: const Duration(milliseconds: 400),
      vsync: this,
    );

    _opacityAnimation = Tween<double>(begin: 0.0, end: 1.0).animate(
      CurvedAnimation(parent: _controller, curve: Curves.easeOut),
    );

    _slideAnimation = Tween<Offset>(
      begin: const Offset(0, 0.1),
      end: Offset.zero,
    ).animate(
      CurvedAnimation(parent: _controller, curve: Curves.easeOut),
    );

    // skipAnimation이면 애니메이션 건너뛰고 바로 표시
    if (widget.skipAnimation) {
      _hasAnimated = true;
      _controller.value = 1.0;
    } else {
      // 순차적으로 애니메이션 시작 (최대 10개까지만 순차, 이후는 동시에)
      final delay = widget.index < 10 ? widget.index * 40 : 400;
      Future.delayed(Duration(milliseconds: delay), () {
        if (mounted && !_hasAnimated) {
          _hasAnimated = true;
          _controller.forward();
        }
      });
    }
  }

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

  @override
  Widget build(BuildContext context) {
    super.build(context);
    final imageUrl = widget.photo.thumbUrl ?? widget.photo.mediumUrl;

    return FadeTransition(
      opacity: _opacityAnimation,
      child: SlideTransition(
        position: _slideAnimation,
        child: GestureDetector(
          onTap: () {
            Navigator.push(
              context,
              PageRouteBuilder(
                opaque: false,
                pageBuilder: (context, animation, secondaryAnimation) {
                  return _ConceptPhotoViewer(
                    photos: widget.allPhotos,
                    initialIndex: widget.index,
                  );
                },
                transitionsBuilder: (context, animation, secondaryAnimation, child) {
                  return FadeTransition(opacity: animation, child: child);
                },
                transitionDuration: const Duration(milliseconds: 200),
              ),
            );
          },
          child: Container(
            decoration: BoxDecoration(
              color: AppColors.divider,
              borderRadius: BorderRadius.circular(12),
            ),
            child: ClipRRect(
              borderRadius: BorderRadius.circular(12),
              child: imageUrl != null
                  ? AspectRatio(
                      aspectRatio: widget.photo.width != null &&
                              widget.photo.height != null &&
                              widget.photo.height! > 0
                          ? widget.photo.width! / widget.photo.height!
                          : 1.0,
                      child: CachedNetworkImage(
                        imageUrl: imageUrl,
                        fit: BoxFit.cover,
                        placeholder: (context, url) => Container(color: AppColors.divider),
                        errorWidget: (context, url, error) => Container(
                          color: AppColors.divider,
                          child: const Icon(LucideIcons.imageOff, color: AppColors.textTertiary),
                        ),
                      ),
                    )
                  : const AspectRatio(
                      aspectRatio: 1.0,
                      child: Icon(LucideIcons.imageOff, color: AppColors.textTertiary),
                    ),
            ),
          ),
        ),
      ),
    );
  }
}

/// 컨셉 포토 뷰어 (라이트박스)
class _ConceptPhotoViewer extends StatefulWidget {
  final List<ConceptPhoto> photos;
  final int initialIndex;

  const _ConceptPhotoViewer({
    required this.photos,
    required this.initialIndex,
  });

  @override
  State<_ConceptPhotoViewer> createState() => _ConceptPhotoViewerState();
}

class _ConceptPhotoViewerState extends State<_ConceptPhotoViewer> {
  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> _downloadImage() async {
    final photo = widget.photos[_currentIndex];
    final imageUrl = photo.originalUrl;
    if (imageUrl == null || imageUrl.isEmpty) return;

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

  /// 사진 정보가 있는지 확인
  bool get _hasInfo {
    final photo = widget.photos[_currentIndex];
    return (photo.members != null && photo.members!.isNotEmpty) ||
        (photo.concept != null && photo.concept!.isNotEmpty);
  }

  /// Info 바텀시트 표시
  void _showInfoSheet() {
    final photo = widget.photos[_currentIndex];
    showModalBottomSheet(
      context: context,
      backgroundColor: Colors.transparent,
      builder: (context) => _InfoBottomSheet(photo: photo),
    );
  }

  @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.photos.length,
              allowImplicitScrolling: true, // 인접 페이지 미리 빌드
              onPageChanged: (index) {
                setState(() => _currentIndex = index);
              },
              backgroundDecoration: const BoxDecoration(color: Colors.black),
              builder: (context, index) {
                final photo = widget.photos[index];
                final imageUrl = photo.mediumUrl ?? photo.originalUrl;

                if (imageUrl == null || imageUrl.isEmpty) {
                  return PhotoViewGalleryPageOptions.customChild(
                    child: const Center(
                      child: Icon(
                        LucideIcons.imageOff,
                        color: Colors.white54,
                        size: 64,
                      ),
                    ),
                  );
                }

                return PhotoViewGalleryPageOptions(
                  imageProvider: CachedNetworkImageProvider(photo.originalUrl ?? imageUrl),
                  minScale: PhotoViewComputedScale.contained,
                  maxScale: PhotoViewComputedScale.covered * 3,
                  initialScale: PhotoViewComputedScale.contained,
                  heroAttributes: PhotoViewHeroAttributes(tag: 'concept_photo_$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.photos.length > 1)
                      Text(
                        '${_currentIndex + 1} / ${widget.photos.length}',
                        style: const TextStyle(
                          color: Colors.white70,
                          fontSize: 14,
                          fontFeatures: [FontFeature.tabularFigures()],
                        ),
                      ),
                    // 오른쪽: 정보 버튼 + 다운로드 버튼
                    Expanded(
                      child: Align(
                        alignment: Alignment.centerRight,
                        child: Row(
                          mainAxisSize: MainAxisSize.min,
                          children: [
                            if (_hasInfo)
                              GestureDetector(
                                onTap: _showInfoSheet,
                                child: const Padding(
                                  padding: EdgeInsets.all(4),
                                  child: Icon(
                                    LucideIcons.info,
                                    color: Colors.white70,
                                    size: 22,
                                  ),
                                ),
                              ),
                            const SizedBox(width: 8),
                            GestureDetector(
                              onTap: _downloadImage,
                              child: const Padding(
                                padding: EdgeInsets.all(4),
                                child: Icon(
                                  LucideIcons.download,
                                  color: Colors.white70,
                                  size: 22,
                                ),
                              ),
                            ),
                          ],
                        ),
                      ),
                    ),
                  ],
                ),
              ),
            ),
            // 하단 인디케이터
            if (widget.photos.length > 1)
              Positioned(
                bottom: bottomPadding + 16,
                left: 0,
                right: 0,
                child: _SlidingIndicator(
                  count: widget.photos.length,
                  currentIndex: _currentIndex,
                  onTap: (index) {
                    _pageController.animateToPage(
                      index,
                      duration: const Duration(milliseconds: 300),
                      curve: Curves.easeOut,
                    );
                  },
                ),
              ),
          ],
        ),
      ),
    );
  }
}

/// 정보 바텀시트
class _InfoBottomSheet extends StatelessWidget {
  final ConceptPhoto photo;

  const _InfoBottomSheet({required this.photo});

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

    return Container(
      decoration: const BoxDecoration(
        color: Color(0xFF18181B), // zinc-900
        borderRadius: BorderRadius.vertical(top: Radius.circular(24)),
      ),
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          // 드래그 핸들
          Container(
            margin: const EdgeInsets.only(top: 12, bottom: 8),
            width: 40,
            height: 4,
            decoration: BoxDecoration(
              color: const Color(0xFF52525B), // zinc-600
              borderRadius: BorderRadius.circular(2),
            ),
          ),
          // 내용
          Padding(
            padding: EdgeInsets.fromLTRB(20, 8, 20, 32 + bottomPadding),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                const Text(
                  '사진 정보',
                  style: TextStyle(
                    color: Colors.white,
                    fontSize: 18,
                    fontWeight: FontWeight.w600,
                  ),
                ),
                const SizedBox(height: 16),
                // 멤버
                if (photo.members != null && photo.members!.isNotEmpty)
                  _InfoRow(
                    icon: LucideIcons.users,
                    iconBackgroundColor: AppColors.primary.withValues(alpha: 0.2),
                    iconColor: AppColors.primary,
                    label: '멤버',
                    value: photo.members!,
                  ),
                // 컨셉
                if (photo.concept != null && photo.concept!.isNotEmpty) ...[
                  if (photo.members != null && photo.members!.isNotEmpty)
                    const SizedBox(height: 16),
                  _InfoRow(
                    icon: LucideIcons.tag,
                    iconBackgroundColor: Colors.white.withValues(alpha: 0.1),
                    iconColor: const Color(0xFFA1A1AA), // zinc-400
                    label: '컨셉',
                    value: photo.concept!,
                  ),
                ],
              ],
            ),
          ),
        ],
      ),
    );
  }
}

/// 정보 행 위젯
class _InfoRow extends StatelessWidget {
  final IconData icon;
  final Color iconBackgroundColor;
  final Color iconColor;
  final String label;
  final String value;

  const _InfoRow({
    required this.icon,
    required this.iconBackgroundColor,
    required this.iconColor,
    required this.label,
    required this.value,
  });

  @override
  Widget build(BuildContext context) {
    return Row(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Container(
          width: 32,
          height: 32,
          decoration: BoxDecoration(
            color: iconBackgroundColor,
            shape: BoxShape.circle,
          ),
          child: Icon(icon, size: 16, color: iconColor),
        ),
        const SizedBox(width: 12),
        Expanded(
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Text(
                label,
                style: const TextStyle(
                  color: Color(0xFFA1A1AA), // zinc-400
                  fontSize: 12,
                ),
              ),
              const SizedBox(height: 2),
              Text(
                value,
                style: const TextStyle(
                  color: Colors.white,
                  fontSize: 15,
                ),
              ),
            ],
          ),
        ),
      ],
    );
  }
}

/// 슬라이딩 인디케이터
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;

    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;
                    const inactiveDotSize = 10.0;
                    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),
                          ),
                        ),
                      ),
                    );
                  }),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}
