import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:just_audio/just_audio.dart';
import 'package:traderscircuit/Utils/base_manager.dart';
import 'package:traderscircuit/model/ContentBytesModel/content_bytes_categories_model.dart';
import 'package:traderscircuit/model/ContentBytesModel/content_bytes_model.dart';
import 'package:traderscircuit/view_model/ContentBytesApi/content_bytes_api.dart';

import '../view/Sidemenu/ContentByte/ContentBytes.dart';

class ContentBytesController extends GetxController {
  RxBool isLoading = true.obs;
  ContentBytesCategoriesModel contentBytesCategoriesModel =
      ContentBytesCategoriesModel();
  ContentBytesModel contentBytesModel = ContentBytesModel();
  int filterId = 0;
  RxBool isApiCalling = true.obs;
  RxBool isAudioSeekBarVisible = false.obs;
  RxInt indexForAudios = 0.obs;
  RxBool titlePlaying = false.obs;
  RxList<bool>? titlePlayingList = <bool>[].obs;

  final progressNotifier = ValueNotifier<ProgressBarState>(
    ProgressBarState(
      current: Duration.zero,
      buffered: Duration.zero,
      total: Duration.zero,
    ),
  );
  final buttonNotifier = ValueNotifier<ButtonState>(ButtonState.paused);

  late AudioPlayer _audioPlayer;
  @override
  void dispose() {
    _audioPlayer.stop();
    super.dispose();
  }

  void getAudio() => _audioPlayer;

  void init(index) async {
    _audioPlayer = AudioPlayer();
    try {
      await _audioPlayer.setUrl(
          //contentBytesModel.data!.audio![index].file ??
          'https://ghantalele.com/uploads/files/data-78/38825/Besharam%20Rang_192(Ghantalele.com).mp3');
      // await _audioPlayer.setAsset(url);
    } on PlayerException catch (e) {
      print("Error code: ${e.code}");
      // iOS/macOS: maps to NSError.localizedDescription
      // Android: maps to ExoPlaybackException.getMessage()
      // Web/Linux: a generic message
      // Windows: MediaPlayerError.message
      print("Error message: ${e.message}");
    }
//Catching errors during playback (e.g. lost network connection)
    _audioPlayer.playbackEventStream.listen((event) {},
        onError: (Object e, StackTrace st) {
      if (e is PlayerException) {
        print('Error code: ${e.code}');
        print('Error message: ${e.message}');
      } else {
        print('An error occurred: $e');
      }
    });

    _audioPlayer.playerStateStream.listen((playerState) {
      final isPlaying = playerState.playing;
      final processingState = playerState.processingState;
      if (!isPlaying) {
        buttonNotifier.value = ButtonState.paused;
      } else if (processingState != ProcessingState.completed) {
        buttonNotifier.value = ButtonState.playing;
      } else {
        _playNextTrack();

        // _audioPlayer.seek(Duration.zero);
        // _audioPlayer.pause();
      }
    });

    _audioPlayer.positionStream.listen((position) {
      final oldState = progressNotifier.value;
      progressNotifier.value = ProgressBarState(
        current: position,
        buffered: oldState.buffered,
        total: oldState.total,
      );
    });

    _audioPlayer.bufferedPositionStream.listen((bufferedPosition) {
      final oldState = progressNotifier.value;
      progressNotifier.value = ProgressBarState(
        current: oldState.current,
        buffered: bufferedPosition,
        total: oldState.total,
      );
    });

    _audioPlayer.durationStream.listen((totalDuration) {
      final oldState = progressNotifier.value;
      progressNotifier.value = ProgressBarState(
        current: oldState.current,
        buffered: oldState.buffered,
        total: totalDuration ?? Duration.zero,
      );
    });
  }

  void _playNextTrack() {
    // Determine the index of the next track (you need to implement this logic)
    int nextIndex = getNextTrackIndex();

    if (nextIndex != -1) {
      // Play the next track
      updateTitlePlaying(nextIndex);
      if (isPlaying()) {
        stop();
      }
      init(nextIndex);
      play(nextIndex);
    } else {
      _audioPlayer.seek(Duration.zero);
      _audioPlayer.pause();
    }
  }

  int getNextTrackIndex() {
    if (indexForAudios.value == contentBytesModel.data!.audio!.length - 1) {
      return -1;
    } else {
      return indexForAudios.value + 1;
    }

    // You need to implement this logic based on your playlist structure
    // For example, if you have a list of tracks, return the index of the next track
    // If there is no next track, return -1
    // This logic depends on how you manage your playlist
    // Example: return currentTrackIndex + 1;
  }

  void play(index) {
    _audioPlayer.play();
    isAudioSeekBarVisible.value = false;
    isAudioSeekBarVisible.value = true;
    indexForAudios.value = index;
  }

  void pause() {
    _audioPlayer.pause();
  }

  void seek(Duration position) {
    _audioPlayer.seek(position);
  }

  void stop() {
    _audioPlayer.stop();
  }

  bool isPlaying() {
    return _audioPlayer.playing;
  }

  addTitles() {
    titlePlayingList = List<bool>.generate(
      contentBytesModel.data!.audio!.length,
      (index) => false,
    ).obs;
  }

  void updateTitlePlaying(int index) {
    // Check if the index is within valid range
    if (index >= 0 && index < titlePlayingList!.length) {
      // Set all values to false
      titlePlayingList!.assignAll(List.generate(
        titlePlayingList!.length,
        (index) => false,
      ));
      // Set the specified index to true
      titlePlayingList![index] = true;
    }
  }

  // RxList<Video> searchResults = <Video>[].obs;

  // Future<void> getContentBytesDataVideo(String query) async {
  //   // Set isLoading to true if needed
  //   isLoading.value = true;

  //   try {
  //     // Make API call to fetch search results based on the query
  //     final response = await ContentBytesApi().getContentBytesData({
  //       // Pass query parameters if needed
  //       'search_data': query,
  //       'content_type': "video",
  //       'category_id': "",
  //     });

  //     // Check if the API call was successful
  //     if (response.status == ResponseStatus.SUCCESS) {
  //       // Parse the response data into a list of videos
  //       final List<dynamic> responseData = response.data['data']['video'];
  //       searchResults.value =
  //           responseData.map((data) => Video.fromJson(data)).toList();

  //       // Notify listeners about the changes to the searchResults list
  //       update();
  //     } else {
  //       // Handle API call failure
  //       // You may show an error message or handle it as needed
  //     }
  //   } catch (e) {
  //     // Handle exceptions
  //     // You may show an error message or handle it as needed
  //   } finally {
  //     // Set isLoading to false after the API call completes
  //     isLoading.value = false;
  //   }
  // }
}
