import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';

import '../../core/contracts/library.dart';
import '../../providers/di_providers.dart';
import '../../providers/emby_headers_provider.dart';
import '../../providers/library_overview_provider.dart';
import '../../providers/session_provider.dart';
import '../../providers/shell_backdrop_provider.dart';
import '../../shared/constants/layout_constants.dart';
import '../../shared/mappers/media_image_url.dart';
import '../../shared/utils/user_error_formatter.dart';
import '../../shared/widgets/app_loading_ring.dart';
import '../../shared/widgets/app_error_state.dart';
import '../../shared/utils/media_nav.dart';
import '../../shared/widgets/app_sliver_header.dart';
import '../../shared/widgets/empty_state.dart';
import '../../shared/widgets/media_poster_card.dart';

const _kPageSize = 20;
const _kScrollThreshold = 200.0;
const _kFields =
    'BasicSyncInfo,CommunityRating,ProductionYear,ChildCount,Container,'
    'Overview,UserDataLastPlayedDate,OfficialRating,Genres,Status,'
    'People,Studios,ProviderIds';
const _kImageTypes = 'Primary,Backdrop,Thumb,Logo';
const _kIncludeTypes = 'Series,Movie,Video,MusicVideo';
const _kCollectionIncludeTypes = 'BoxSet,Folder,Series,Movie,Video,MusicVideo';
const _kSortBy = 'DateLastContentAdded,DateCreated,SortName';

class LibraryListPage extends ConsumerStatefulWidget {
  final String libraryId;


  final String? title;


  final bool isCollection;

  const LibraryListPage({
    super.key,
    required this.libraryId,
    this.title,
    this.isCollection = false,
  });

  @override
  ConsumerState<LibraryListPage> createState() => _LibraryListPageState();
}

class _LibraryListPageState extends ConsumerState<LibraryListPage> {
  final List<EmbyRawItem> _items = [];
  int _startIndex = 0;
  bool _hasMore = true;
  bool _isFirstLoad = true;
  bool _isLoadingMore = false;
  String? _loadError;

  final _scrollController = ScrollController();

  @override
  void initState() {
    super.initState();
    _fetchPage();
    _scrollController.addListener(_onScroll);
  }

  @override
  void didUpdateWidget(LibraryListPage oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (oldWidget.libraryId != widget.libraryId) {
      _resetAndFetch();
    }
  }

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

  void _onScroll() {
    if (!_scrollController.hasClients) return;
    final remaining =
        _scrollController.position.maxScrollExtent -
        _scrollController.position.pixels;
    if (remaining <= _kScrollThreshold && _hasMore && !_isLoadingMore) {
      _fetchPage();
    }
  }

  void _resetAndFetch() {
    setState(() {
      _items.clear();
      _startIndex = 0;
      _hasMore = true;
      _isFirstLoad = true;
      _isLoadingMore = false;
      _loadError = null;
    });
    _fetchPage();
  }

  Future<void> _refresh() async {
    setState(() {
      _items.clear();
      _startIndex = 0;
      _hasMore = true;
      _isFirstLoad = true;
      _isLoadingMore = false;
      _loadError = null;
    });
    await _fetchPage();
  }

  Future<void> _fetchPage() async {
    if (_isLoadingMore || !_hasMore) return;
    setState(() {
      _isLoadingMore = true;
      _loadError = null;
    });
    try {
      final uc = await ref.read(libraryItemsUseCaseProvider.future);
      final res = await uc.execute(
        LibraryItemsReq(
          parentId: widget.libraryId,
          includeItemTypes: widget.isCollection
              ? _kCollectionIncludeTypes
              : _kIncludeTypes,
          sortBy: _kSortBy,
          sortOrder: SortOrder.descending,
          fields: _kFields,
          enableImageTypes: _kImageTypes,
          startIndex: _startIndex,
          limit: _kPageSize,
          recursive: !widget.isCollection,
        ),
      );
      if (!mounted) return;
      final fetched = res.items;
      setState(() {
        _items.addAll(fetched);
        _startIndex += fetched.length;
        _hasMore = fetched.length == _kPageSize;
        _isFirstLoad = false;
        _isLoadingMore = false;
      });
    } catch (e) {
      if (!mounted) return;
      setState(() {
        _loadError = e.toString();
        _isFirstLoad = false;
        _isLoadingMore = false;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    final session = ref.watch(activeSessionProvider);
    if (session == null) return const SizedBox.shrink();
    final imageHeaders = ref.watch(embyImageHeadersProvider).value;
    final hasBackdrop = ref.watch(
      shellBackdropProvider.select((state) => state != null),
    );
    final immersiveTextColor = hasBackdrop ? Colors.white : null;
    final libraryName =
        ref
            .watch(libraryOverviewProvider)
            .value
            ?.libraries
            .where((l) => l.Id == widget.libraryId)
            .firstOrNull
            ?.Name ??
        widget.title ??
        '';

    return Scaffold(
      backgroundColor: Colors.transparent,
      extendBodyBehindAppBar: true,
      body: RefreshIndicator(
        onRefresh: _refresh,
        child: CustomScrollView(
          controller: _scrollController,
          physics: const AlwaysScrollableScrollPhysics(
            parent: BouncingScrollPhysics(),
          ),
          slivers: [
            AppSliverHeader(
              title: libraryName,
              leading: IconButton(
                icon: const Icon(Icons.arrow_back),
                onPressed: () => context.pop(),
              ),
            ),
            ..._buildContentSlivers(
              session,
              imageHeaders,
              immersiveTextColor: immersiveTextColor,
            ),
          ],
        ),
      ),
    );
  }

  List<Widget> _buildContentSlivers(
    dynamic session,
    Map<String, String>? imageHeaders, {
    required Color? immersiveTextColor,
  }) {
    if (_isFirstLoad) {
      if (_loadError != null) {
        return [
          SliverFillRemaining(
            hasScrollBody: false,
            child: AppErrorState(
              message: formatUserError(_loadError, fallback: '媒体列表加载失败'),
              foregroundColor: immersiveTextColor,
              onRetry: _resetAndFetch,
            ),
          ),
        ];
      }
      return const [
        SliverFillRemaining(
          hasScrollBody: false,
          child: Center(child: AppLoadingRing()),
        ),
      ];
    }

    if (_items.isEmpty && !_isLoadingMore && _loadError != null) {
      return [
        SliverFillRemaining(
          hasScrollBody: false,
          child: AppErrorState(
            message: formatUserError(_loadError, fallback: '媒体列表加载失败'),
            foregroundColor: immersiveTextColor,
            onRetry: _resetAndFetch,
          ),
        ),
      ];
    }

    if (_items.isEmpty && !_isLoadingMore) {
      return [
        SliverFillRemaining(
          hasScrollBody: false,
          child: EmptyState(
            icon: Icons.inbox_outlined,
            title: '暂无媒体内容',
            foregroundColor: immersiveTextColor,
          ),
        ),
      ];
    }

    return [
      SliverPadding(
        padding: const EdgeInsets.fromLTRB(16, 0, 16, 16),
        sliver: SliverGrid(
          delegate: SliverChildBuilderDelegate(
            (_, i) => MediaPosterCard(
              item: _items[i],
              width: double.infinity,
              textColor: immersiveTextColor,
              imageUrl: EmbyImageUrl.primary(
                baseUrl: session.serverUrl,
                token: session.token,
                item: _items[i],
                maxHeight: 360,
              ),
              preloadImageUrl: EmbyImageUrl.detailBanner(
                baseUrl: session.serverUrl,
                token: session.token,
                item: _items[i],
              ),
              imageHeaders: imageHeaders,
              onTap: () => goMediaDetail(context, _items[i]),
            ),
            childCount: _items.length,
          ),
          gridDelegate: mediaGridDelegate,
        ),
      ),
      SliverToBoxAdapter(
        child: _buildFooter(immersiveTextColor: immersiveTextColor),
      ),
    ];
  }

  Widget _buildFooter({required Color? immersiveTextColor}) {
    if (_isLoadingMore) {
      return const Padding(
        padding: EdgeInsets.symmetric(vertical: 24),
        child: Center(child: AppLoadingRing()),
      );
    }
    if (!_hasMore && _items.isNotEmpty) {
      return Padding(
        padding: const EdgeInsets.symmetric(vertical: 24),
        child: Center(
          child: Text(
            '没有更多了',
            style: Theme.of(context).textTheme.bodySmall?.copyWith(
              color: immersiveTextColor?.withValues(alpha: 0.55),
            ),
          ),
        ),
      );
    }
    return const SizedBox.shrink();
  }
}
