import 'dart:async';

import 'package:didvan/models/enums.dart';
import 'package:didvan/models/overview_data.dart';
import 'package:didvan/models/requests/studio.dart';
import 'package:didvan/models/studio_details_data.dart';
import 'package:didvan/providers/core_provider.dart';
import 'package:didvan/services/media/media.dart';
import 'package:didvan/services/network/request.dart';
import 'package:didvan/services/network/request_helper.dart';

class StudioDetailsState extends CoreProvier {
  late StudioDetailsData studio;
  StudioDetailsData? nextStudio;
  StudioDetailsData? prevStudio;
  late int initialIndex;
  late StudioRequestArgs args;
  StudioRequestArgs? podcastArgs;
  final List<int> relatedQueue = [];
  bool _positionListenerActivated = false;

  int _selectedDetailsIndex = 0;
  Timer? timer;
  int timerValue = 10;
  bool stopOnPodcastEnds = false;

  int get selectedDetailsIndex => _selectedDetailsIndex;
  set selectedDetailsIndex(int value) {
    _selectedDetailsIndex = value;
    if (value == 2) {
      getRelatedContents();
    }
    notifyListeners();
  }

  Future<void> getStudioDetails(
    int id, {
    StudioRequestArgs? args,
    bool? isForward,
    bool forceFetch = false,
  }) async {
    if (args != null) {
      this.args = args;
    }
    if (this.args.type == 'podcast') {
      podcastArgs = this.args;
    }
    if (MediaService.currentPodcast?.id == id &&
        this.args.type == 'podcast' &&
        !forceFetch) {
      return;
    }
    _selectedDetailsIndex = 0;
    if (isForward != null) {
      if (isForward) {
        prevStudio = studio;
        studio = nextStudio!;
        nextStudio = null;
      } else {
        nextStudio = studio;
        studio = prevStudio!;
        prevStudio = null;
      }
      notifyListeners();
      _handlePodcastPlayback(studio);
    }
    if (isForward == null) {
      if (this.args.type == 'podcast') {
        MediaService.audioPlayerTag = 'podcast';
      }
      appState = AppState.busy;
    }
    final service = RequestService(RequestHelper.studioDetails(id, this.args));
    await service.httpGet();
    nextStudio = null;
    prevStudio = null;
    if (stopOnPodcastEnds) {
      timerValue = 10;
    }
    stopOnPodcastEnds = false;
    if (service.isSuccess) {
      final result = service.result;
      studio = StudioDetailsData.fromJson(result['studio']);
      if (result['nextStudio'].isNotEmpty && this.args.page != 0) {
        nextStudio = StudioDetailsData.fromJson(result['nextStudio']);
      }
      if (result['prevStudio'].isNotEmpty && this.args.page != 0) {
        prevStudio = StudioDetailsData.fromJson(result['prevStudio']);
      }
      if (isForward == null && !forceFetch) {
        await _handlePodcastPlayback(studio);
      }
      appState = AppState.idle;
      return;
    }
    if (isForward == null) {
      appState = AppState.failed;
    }
  }

  Future<void> _handlePodcastPlayback(StudioDetailsData studio) async {
    if (args.type == 'podcast') {
      MediaService.currentPodcast = studio;
      MediaService.podcastPlaylistArgs = args;
      await MediaService.handleAudioPlayback(
        audioSource: studio.media,
        id: studio.id,
        isVoiceMessage: false,
      );
      if (nextStudio != null && !_positionListenerActivated) {
        _positionListenerActivated = true;
        MediaService.audioPlayer.positionStream.listen((event) {
          if (MediaService.audioPlayerTag?.contains('message') == true) {
            return;
          }
          final duration = MediaService.audioPlayer.duration ??
              Duration(seconds: studio.duration);
          if (event.compareTo(duration) > 0 && nextStudio != null) {
            if (stopOnPodcastEnds) {
              MediaService.resetAudioPlayer();
              return;
            }
            getStudioDetails(nextStudio!.id, isForward: true);
          }
        });
      }
    }
  }

  Future<void> getRelatedContents() async {
    if (studio.relatedContents.isNotEmpty) return;
    relatedQueue.add(studio.id);
    final service = RequestService(RequestHelper.tag(
      ids: studio.tags.map((tag) => tag.id).toList(),
      itemId: studio.id,
      type: args.type,
    ));
    await service.httpGet();
    if (service.isSuccess) {
      final relateds = service.result['contents'];
      for (var i = 0; i < relateds.length; i++) {
        studio.relatedContents.add(OverviewData.fromJson(relateds[i]));
      }
      notifyListeners();
    }
  }

  void onCommentsChanged(int count) {
    studio.comments = count;
    notifyListeners();
  }
}
