import 'dart:convert';
import 'dart:io';

import 'package:get/get.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../api/api_download.dart';
import '../common_widget/Song_widegt.dart';
import 'package:path/path.dart' as path;

class DownloadItem {
  final Song song;
  double progress;
  bool isCompleted;
  bool isDownloading;

  DownloadItem({
    required this.song,
    this.progress = 0.0,
    this.isCompleted = false,
    this.isDownloading = false,
  });

  Map<String, dynamic> toJson() {
    return {
      'song': {
        'pic': song.pic,
        'artistPic': song.artistPic,
        'title': song.title,
        'artist': song.artist,
        'musicurl': song.musicurl,
        'id': song.id,
        'likes': song.likes,
        'collection': song.collection
      },
      'progress': progress,
      'isCompleted': isCompleted,
      'isDownloading': isDownloading,
    };
  }

  // 从JSON创建DownloadItem
  factory DownloadItem.fromJson(Map<String, dynamic> json) {
    return DownloadItem(
      song: Song(
        pic: json['song']['pic'],
        artistPic: json['song']['artistPic'],
        title: json['song']['title'],
        artist: json['song']['artist'],
        musicurl: json['song']['musicurl'],
        id: json['song']['id'],
        likes: json['song']['likes'],
        collection: json['song']['collection'],
      ),
      progress: json['progress'],
      isCompleted: json['isCompleted'],
      isDownloading: json['isDownloading'],
    );
  }
}

class DownloadManager extends GetxController {
  static const String PREFS_KEY = 'downloads_data';
  final _downloads = <String, DownloadItem>{}.obs;
  final downloadApi = DownloadApi();
  late SharedPreferences _prefs;

  @override
  void onInit() async {
    super.onInit();
    await _initPrefs();
  }

  Future<void> _initPrefs() async {
    _prefs = await SharedPreferences.getInstance();
    await _loadDownloadsFromPrefs();
  }

  // 从SharedPreferences加载数据
  Future<void> _loadDownloadsFromPrefs() async {
    final String? downloadsJson = _prefs.getString(PREFS_KEY);
    if (downloadsJson != null) {
      final Map<String, dynamic> downloadsMap = json.decode(downloadsJson);
      downloadsMap.forEach((key, value) {
        _downloads[key] = DownloadItem.fromJson(value);
      });
    }
  }

  // 保存数据到SharedPreferences
  Future<void> _saveDownloadsToPrefs() async {
    final Map<String, dynamic> downloadsMap = {};
    _downloads.forEach((key, value) {
      downloadsMap[key] = value.toJson();
    });
    await _prefs.setString(PREFS_KEY, json.encode(downloadsMap));
  }

  List<Song> getLocalSongs() {
    final localSongs = <Song>[];
    _downloads.forEach((key, value) {
      if (value.isCompleted) {
        localSongs.add(value.song);
      }
    });
    return localSongs;
  }

  Map<String, DownloadItem> get downloads => _downloads;

  bool isDownloading(int id) => _downloads[id.toString()]?.isDownloading ?? false;
  bool isCompleted(int id) => _downloads[id.toString()]?.isCompleted ?? false;
  double getProgress(int id) => _downloads[id.toString()]?.progress ?? 0.0;

  Song? getLocalSong(int id) {
    final downloadItem = _downloads[id.toString()];
    if (downloadItem?.isCompleted ?? false) {
      return downloadItem!.song;
    }
    return null;
  }

  bool removeSong(int id) {
    if (_downloads[id.toString()]?.isCompleted ?? false) {
      File file = File.fromUri(Uri.parse(_downloads[id.toString()]!.song.musicurl));
      file.deleteSync();
      _downloads.remove(id.toString());
      _saveDownloadsToPrefs();
      return true;
    }
    return false;
  }

  int completedNumber() {
    int count = 0;
    _downloads.forEach((key, value) {
      if (value.isCompleted) {
        count++;
      }
    });
    return count;
  }

  Future<void> startDownload({
    required Song song,
    required context,
  }) async {
    if (_downloads[song.id.toString()]?.isDownloading ?? false) return;

    final fileName = '${song.id}_${song.title}_${song.artist}';

    final downloadItem = DownloadItem(
      song: song,
      isDownloading: true,
    );
    _downloads[song.id.toString()] = downloadItem;

    try {
      final filePath = await downloadApi.downloadMusic(
        musicUrl: song.musicurl,
        name: fileName,
        context: context,
        onProgress: (progress) {
          downloadItem.progress = progress;
          _downloads[song.id.toString()] = downloadItem;
        },
      );

      if (filePath != null) {
        downloadItem.isCompleted = true;
        downloadItem.isDownloading = false;
        downloadItem.progress = 1.0;
        song.musicurl = _getLocalAudioPath(fileName, song.musicurl);
        print(song.musicurl);
      } else {
        downloadItem.isDownloading = false;
        downloadItem.progress = 0.0;
      }
    } catch (e) {
      print('Download error: $e');
      downloadItem.isDownloading = false;
      downloadItem.progress = 0.0;
    }

    _downloads[song.id.toString()] = downloadItem;
    await _saveDownloadsToPrefs();
  }

  bool updateSongInfo(int id, bool isCollected, bool isLiked) {
    final downloadItem = _downloads[id.toString()];
    if (downloadItem != null) {
      downloadItem.song.collection = isCollected;
      downloadItem.song.likes = isLiked;
      _downloads[id.toString()] = downloadItem;
      _saveDownloadsToPrefs();
      return true;
    }
    return false;
  }

  String _getFileExtension(String url) {
    // Remove query parameters
    final urlWithoutQuery = url.split('?').first;
    // Get the extension including the dot
    final extension = path.extension(urlWithoutQuery);
    return extension.isNotEmpty ? extension : '.mp3'; // Default to .mp3 if no extension found
  }

  String _getLocalAudioPath(String fileName, String url) {
    final extension = _getFileExtension(url);
    final fullFileName = '$fileName$extension';
    return path.join('/storage/emulated/0/MTMusic', fullFileName);
  }
}