import 'dart:io';

import 'package:device_info_plus/device_info_plus.dart';
import 'package:didvan/constants/assets.dart';
import 'package:didvan/models/requests/studio.dart';
import 'package:didvan/models/studio_details_data.dart';
import 'package:didvan/models/view/action_sheet_data.dart';
import 'package:didvan/providers/media.dart';
import 'package:didvan/services/network/request.dart';
import 'package:didvan/services/network/request_helper.dart';
import 'package:didvan/services/storage/storage.dart';
import 'package:didvan/utils/action_sheet.dart';
import 'package:flutter/material.dart';
import 'package:flutter_downloader/flutter_downloader.dart';
import 'package:get/get.dart';
import 'package:image_picker/image_picker.dart';
import 'package:just_audio/just_audio.dart';
import 'package:path/path.dart' as p;
import 'package:file_picker/file_picker.dart';
import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:universal_html/html.dart' as html;

class MediaService {
  static final audioPlayer = AudioPlayer();
  static String? audioPlayerTag;
  static StudioDetailsData? currentPodcast;
  static StudioRequestArgs? podcastPlaylistArgs;
  static int maxSizeInBytes = 15 * 1024 * 1024;
  static bool isPlayingFromFeaturedCard = false;

  static Duration? get duration => audioPlayer.duration;

  static Future<void> handleAudioPlayback({
    required dynamic audioSource,
    required int id,
    bool isNetworkAudio = true,
    bool isVoiceMessage = true,
    bool isBlob = false,
    void Function(bool isNext)? onTrackChanged,
  }) async {
    try {
      String tag;
      tag =
          '${currentPodcast?.description == 'radar' ? 'radar' : isVoiceMessage ? 'message' : 'podcast'}-$id';
      if (!isVoiceMessage && MediaProvider.downloadedItemIds.contains(id)) {
        audioSource = '${StorageService.appDocsDir}/podcasts/podcast-$id.mp3';
        isNetworkAudio = false;
      }
      if (audioPlayerTag == tag) {
        if (audioPlayer.playing) {
          await audioPlayer.pause();
        } else {
          await audioPlayer.play();
        }

        return;
      }
      await audioPlayer.stop();
      audioPlayerTag = tag;
      String source;
      if (isNetworkAudio) {
        if (isVoiceMessage) {
          source =
              '${RequestHelper.baseUrl + audioSource}?accessToken=${RequestService.token}';
        } else {
          source = audioSource;
        }
        audioPlayer.setUrl(
          source,
          tag: isVoiceMessage
              ? null
              : {
                  "artist": 'استودیو دیدوان',
                  "title": currentPodcast?.title ?? '',
                },
        );
      } else {
        if (isBlob) {
          audioPlayer.setAudioSource(AudioSource.uri(Uri.parse(audioSource)));
        } else {
          audioPlayer.setFilePath(
            audioSource,
            tag: isVoiceMessage
                ? null
                : {
                    "artist": 'استودیو دیدوان',
                    "title": currentPodcast?.title ?? '',
                  },
          );
        }
      }
      await audioPlayer.play();
    } catch (e) {
      // rethrow;
    }
  }

  static Future<void> resetAudioPlayer() async {
    audioPlayerTag = null;
    currentPodcast = null;
    podcastPlaylistArgs = null;
    isPlayingFromFeaturedCard = false;
    await MediaService.audioPlayer.stop();
  }

  static Future<XFile?> pickImage({required ImageSource source}) async {
    try {
      final imagePicker = ImagePicker();
      final XFile? pickedFile = await imagePicker.pickImage(source: source);
      return pickedFile;
    } catch (e) {
      e.printError(info: 'Pick Image Fail');
      return null;
    }
  }

  static Future<FilePickerResult?> pickPdfFile() async {
    try {
      final FilePickerResult? result = await FilePicker.platform.pickFiles(
        type: FileType.custom,
        allowedExtensions: ['pdf', 'doc', 'docx', 'xls', 'xlsx', 'csv'],
        allowMultiple: false,
      );
      return result;
    } catch (e) {
      e.printError(info: 'Pick PDF Fail');
      return null;
    }
  }

  static Future<FilePickerResult?> pickMultiFile() async {
    try {
      return await FilePicker.platform
          .pickFiles(
        type: FileType.any,
        allowMultiple: true,
      )
          .then((result) {
        if (result != null && result.files.length > 3) {
          return null; 
        }
        return result;
      });
    } catch (e) {
      e.printError(info: 'Pick Multi File Fail');
      return null;
    }
  }

  static Future<FilePickerResult?> pickAudioFile() async {
    try {
      return await FilePicker.platform.pickFiles(
        type: FileType.audio,
        allowMultiple: false,
      );
    } catch (e) {
      e.printError(info: 'Pick Audio Fail');
      return null;
    }
  }

  static Future<String?> downloadFile(String url, {final String? name}) async {
    debugPrint("Attempting to download file from URL: $url");
    final basename = name ?? p.basename(url).split('?accessToken=').first;
    
    PermissionStatus status;
    if (Platform.isAndroid) {
        final androidInfo = await DeviceInfoPlugin().androidInfo;
        if (androidInfo.version.sdkInt >= 33) {
            debugPrint("Android 13+ detected. Requesting Photos permission.");
            status = await Permission.photos.request();
        } else {
            debugPrint("Older Android version detected. Requesting Storage permission.");
            status = await Permission.storage.request();
        }
    } else if (Platform.isIOS) {
        debugPrint("iOS detected. Requesting Photos permission.");
        status = await Permission.photos.request();
    } else {
        status = PermissionStatus.granted;
    }

    debugPrint("Permission status after request: $status");

    if (status.isGranted) {
        Directory? dir;
        try {
            if (Platform.isIOS) {
                dir = await getApplicationDocumentsDirectory();
            } else {
                dir = await getExternalStorageDirectory(); 
            }
            
            if (dir == null) {
              debugPrint("Error: Could not determine download directory.");
              return null;
            }

            final path = dir.path;
            debugPrint("Download directory determined: $path");

            final taskId = await FlutterDownloader.enqueue(
                url: url,
                savedDir: path,
                fileName: basename,
                showNotification: true,
                openFileFromNotification: true,
                saveInPublicStorage: true, 
            );
            debugPrint("Download successfully enqueued with taskId: $taskId");
            return path;

        } catch (e) {
            debugPrint("Error during download process: $e");
            return null;
        }
    } else if (status.isPermanentlyDenied) {
        debugPrint("Storage permission is permanently denied. Opening app settings.");
        await openAppSettings();
        return null;
    } else {
        debugPrint("Storage permission was denied.");
        return null;
    }
  }


  static String downloadFileFromWeb(String url) {
    final filename = url.split('/').last.split('?').first;
    html.AnchorElement anchorElement = html.AnchorElement(href: url);
    anchorElement.download = filename;
    anchorElement.click();
    return anchorElement.pathname!;
  }

  static onLoadingPickFile(BuildContext context) {
    ActionSheetUtils(context).openDialog(
        barrierDismissible: false,
        data: ActionSheetData(
          content: Center(
            child: Image.asset(
              Assets.loadingAnimation,
              width: 60,
              height: 60,
            ),
          ),
          hasConfirmButton: false,
          hasDismissButton: false,
        ));
  }
}