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

import '../../../core/contracts/library.dart';
import '../../../providers/di_providers.dart';
import '../../../providers/session_provider.dart';
import '../../../shared/utils/cross_server_search_key.dart';
import 'media_info_section.dart';
import 'multi_source_section.dart';


class SourceSelectionSection extends ConsumerWidget {


  final CrossServerSearchReq? req;


  final List<EmbyRawMediaSource> localSources;


  final int selectedSourceIdx;


  final CrossServerSourceCard? selectedCrossServerCard;


  final String? currentServerName;


  final String? excludedServerIdOverride;


  final EmbyRawItem? localMediaInfoItem;


  final void Function(EmbyRawMediaSource src, int index) onLocalSourceTap;


  final void Function(CrossServerSourceCard card) onCrossServerSourceTap;


  final String title;


  final bool showLoadingWhenEmpty;
  final bool externalLoading;
  final String loadingText;


  final Widget? leading;

  const SourceSelectionSection({
    super.key,
    required this.req,
    required this.localSources,
    required this.selectedSourceIdx,
    required this.selectedCrossServerCard,
    required this.onLocalSourceTap,
    required this.onCrossServerSourceTap,
    this.currentServerName,
    this.excludedServerIdOverride,
    this.localMediaInfoItem,
    this.title = '多源聚合',
    this.showLoadingWhenEmpty = false,
    this.externalLoading = false,
    this.loadingText = '正在查找可用版本…',
    this.leading,
  });

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final searchReq = req;
    final card = selectedCrossServerCard;

    final currentLocalSourceId =
        card == null && selectedSourceIdx < localSources.length
        ? localSources[selectedSourceIdx].Id
        : null;
    final selectedCrossServerKey = card != null
        ? '${card.serverId}|${card.mediaSourceId}'
        : null;

    final EmbyRawMediaSource? mediaSource =
        card?.mediaSource ??
        (selectedSourceIdx < localSources.length
            ? localSources[selectedSourceIdx]
            : null);
    final EmbyRawItem? mediaItem = card?.item ?? localMediaInfoItem;
    final multiSourceVisibility = searchReq == null
        ? _MultiSourceVisibility.hidden
        : _multiSourceVisibility(ref, searchReq);
    final mediaInfo =
        mediaSource != null &&
            mediaItem != null &&
            MediaInfoSection.hasVisibleContent(
              item: mediaItem,
              selectedSource: mediaSource,
            )
        ? MediaInfoSection(
            item: mediaItem,
            selectedSource: mediaSource,
            embedded: true,
          )
        : null;
    final bool hasContent =
        multiSourceVisibility != _MultiSourceVisibility.hidden ||
        mediaInfo != null;
    if (!hasContent) return const SizedBox.shrink();

    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        if (leading != null) ...[leading!, const SizedBox(height: 16)],
        if (searchReq != null)
          MultiSourceSection(
            req: searchReq,
            embedded: true,
            localSources: localSources,
            currentLocalSourceId: currentLocalSourceId,
            currentServerName: currentServerName,
            excludedServerIdOverride: excludedServerIdOverride,
            selectedCrossServerKey: selectedCrossServerKey,
            title: title,
            showLoadingWhenEmpty: showLoadingWhenEmpty,
            externalLoading: externalLoading,
            loadingText: loadingText,
            onLocalSourceTap: onLocalSourceTap,
            onSourceTap: (serverId, itemId, {mediaSourceId, card}) async {
              if (card != null) onCrossServerSourceTap(card);
            },
          ),
        if (mediaInfo != null) mediaInfo,
      ],
    );
  }

  _MultiSourceVisibility _multiSourceVisibility(
    WidgetRef ref,
    CrossServerSearchReq searchReq,
  ) {
    final session = ref.watch(activeSessionProvider);
    if (session == null) return _MultiSourceVisibility.hidden;

    final key = (
      activeServerId: session.serverId,
      anchorType: searchReq.anchorType,
      providerIdQuery: encodeProviderIdsForKey(searchReq.providerIds),
      seriesProviderIdQuery: encodeProviderIdsForKey(
        searchReq.seriesProviderIds ?? const {},
      ),
      parentIndexNumber: searchReq.parentIndexNumber ?? -1,
      indexNumber: searchReq.indexNumber ?? -1,
      itemName: searchReq.itemName,
      excludedServerId: excludedServerIdOverride ?? session.serverId,
    );
    final asyncResult = ref.watch(crossServerSearchDataProvider(key));
    final remoteCards = asyncResult.maybeWhen(
      data: (list) => list,
      orElse: () => asyncResult.value ?? const <CrossServerSourceCard>[],
    );
    if (localSources.isNotEmpty || remoteCards.isNotEmpty) {
      return _MultiSourceVisibility.content;
    }

    final loading = externalLoading || asyncResult.isLoading;
    if (showLoadingWhenEmpty && loading) return _MultiSourceVisibility.loading;

    return _MultiSourceVisibility.hidden;
  }
}

enum _MultiSourceVisibility { hidden, loading, content }
