using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Excel = Microsoft.Office.Interop.Excel;
using NAudio.Wave;

namespace TableMagic.Skills
{
    public class ExcelMusicSkill : ISkill
    {
        public string Name => "ExcelMusic";
        public string Description => "音乐播放技能,支持播放本地音乐文件和播放列表管理";

        public List<SkillTool> GetTools()
        {
            return new List<SkillTool>
            {
                new SkillTool
                {
                    Name = "play_music",
                    Description = "播放音乐文件。当用户要求播放音乐时使用此工具。",
                    Parameters = new Dictionary<string, object>
                    {
                        { "type", "object" },
                        { "properties", new Dictionary<string, object>
                            {
                                { "filePath", new { type = "string", description = "音乐文件路径" } },
                                { "volume", new { type = "integer", description = "音量(0-100,默认50)" } }
                            }
                        }
                    },
                    RequiredParameters = new List<string> { "filePath" }
                },
                new SkillTool
                {
                    Name = "play_playlist",
                    Description = "播放文件夹中的所有音乐文件。当用户要求播放播放列表、播放文件夹音乐时使用此工具。",
                    Parameters = new Dictionary<string, object>
                    {
                        { "type", "object" },
                        { "properties", new Dictionary<string, object>
                            {
                                { "folderPath", new { type = "string", description = "音乐文件夹路径" } },
                                { "shuffle", new { type = "boolean", description = "是否随机播放(默认false)" } },
                                { "volume", new { type = "integer", description = "音量(0-100,默认50)" } }
                            }
                        }
                    },
                    RequiredParameters = new List<string> { "folderPath" }
                },
                new SkillTool
                {
                    Name = "pause_music",
                    Description = "暂停/继续播放音乐。",
                    Parameters = new Dictionary<string, object>
                    {
                        { "type", "object" },
                        { "properties", new Dictionary<string, object>() }
                    },
                    RequiredParameters = new List<string>()
                },
                new SkillTool
                {
                    Name = "stop_music",
                    Description = "停止播放音乐。",
                    Parameters = new Dictionary<string, object>
                    {
                        { "type", "object" },
                        { "properties", new Dictionary<string, object>() }
                    },
                    RequiredParameters = new List<string>()
                },
                new SkillTool
                {
                    Name = "set_volume",
                    Description = "设置音量。",
                    Parameters = new Dictionary<string, object>
                    {
                        { "type", "object" },
                        { "properties", new Dictionary<string, object>
                            {
                                { "volume", new { type = "integer", description = "音量(0-100)" } }
                            }
                        }
                    },
                    RequiredParameters = new List<string> { "volume" }
                },
                new SkillTool
                {
                    Name = "next_track",
                    Description = "播放下一首。",
                    Parameters = new Dictionary<string, object>
                    {
                        { "type", "object" },
                        { "properties", new Dictionary<string, object>() }
                    },
                    RequiredParameters = new List<string>()
                },
                new SkillTool
                {
                    Name = "previous_track",
                    Description = "播放上一首。",
                    Parameters = new Dictionary<string, object>
                    {
                        { "type", "object" },
                        { "properties", new Dictionary<string, object>() }
                    },
                    RequiredParameters = new List<string>()
                },
                new SkillTool
                {
                    Name = "get_player_status",
                    Description = "获取播放器状态。",
                    Parameters = new Dictionary<string, object>
                    {
                        { "type", "object" },
                        { "properties", new Dictionary<string, object>() }
                    },
                    RequiredParameters = new List<string>()
                }
            };
        }

        public async Task<SkillResult> ExecuteToolAsync(string toolName, Dictionary<string, object> arguments)
        {
            try
            {
                switch (toolName)
                {
                    case "play_music":
                        return PlayMusic(arguments);
                    case "play_playlist":
                        return PlayPlaylist(arguments);
                    case "pause_music":
                        return PauseMusic();
                    case "stop_music":
                        return StopMusic();
                    case "set_volume":
                        return SetVolume(arguments);
                    case "next_track":
                        return NextTrack();
                    case "previous_track":
                        return PreviousTrack();
                    case "get_player_status":
                        return GetPlayerStatus();
                    default:
                        return new SkillResult { Success = false, Error = $"Tool {toolName} not implemented in ExcelMusicSkill" };
                }
            }
            catch (Exception ex)
            {
                return new SkillResult { Success = false, Error = ex.Message };
            }
        }

        private static WaveOutEvent _waveOut;
        private static AudioFileReader _audioFile;
        private static List<string> _playlist = new List<string>();
        private static int _currentTrackIndex = 0;
        private static bool _shuffle = false;
        private static PlaybackState _playbackState = PlaybackState.Stopped;
        private static float _volume = 0.5f;

        private enum PlaybackState
        {
            Stopped,
            Playing,
            Paused
        }

        private SkillResult PlayMusic(Dictionary<string, object> arguments)
        {
            var filePath = arguments["filePath"].ToString();
            var volume = arguments.ContainsKey("volume") ? Convert.ToInt32(arguments["volume"]) : 50;

            if (!File.Exists(filePath))
                return new SkillResult { Success = false, Error = $"文件不存在: {filePath}" };

            DisposeWavePlayer();

            _audioFile = new AudioFileReader(filePath);
            _waveOut = new WaveOutEvent();
            _waveOut.Init(_audioFile);
            _waveOut.Volume = volume / 100f;
            _volume = volume / 100f;
            _waveOut.PlaybackStopped += WaveOut_PlaybackStopped;
            _waveOut.Play();

            _playlist = new List<string> { filePath };
            _currentTrackIndex = 0;
            _playbackState = PlaybackState.Playing;

            return new SkillResult { Success = true, Content = $"正在播放: {Path.GetFileName(filePath)}" };
        }

        private SkillResult PlayPlaylist(Dictionary<string, object> arguments)
        {
            var folderPath = arguments["folderPath"].ToString();
            var shuffle = arguments.ContainsKey("shuffle") && Convert.ToBoolean(arguments["shuffle"]);
            var volume = arguments.ContainsKey("volume") ? Convert.ToInt32(arguments["volume"]) : 50;

            if (!Directory.Exists(folderPath))
                return new SkillResult { Success = false, Error = $"文件夹不存在: {folderPath}" };

            var extensions = new[] { "*.mp3", "*.wav", "*.wma", "*.m4a", "*.flac", "*.aac", "*.aiff" };
            var files = new List<string>();

            foreach (var ext in extensions)
            {
                files.AddRange(Directory.GetFiles(folderPath, ext, SearchOption.AllDirectories));
            }

            if (files.Count == 0)
                return new SkillResult { Success = false, Error = "文件夹中没有音乐文件" };

            _playlist = files;
            _shuffle = shuffle;

            if (shuffle)
            {
                var random = new Random();
                _playlist = _playlist.OrderBy(x => random.Next()).ToList();
            }

            _currentTrackIndex = 0;

            DisposeWavePlayer();

            _audioFile = new AudioFileReader(_playlist[_currentTrackIndex]);
            _waveOut = new WaveOutEvent();
            _waveOut.Init(_audioFile);
            _waveOut.Volume = volume / 100f;
            _volume = volume / 100f;
            _waveOut.PlaybackStopped += WaveOut_PlaybackStopped;
            _waveOut.Play();

            _playbackState = PlaybackState.Playing;

            return new SkillResult { Success = true, Content = $"正在播放播放列表,共 {_playlist.Count} 首歌曲\n当前: {Path.GetFileName(_playlist[_currentTrackIndex])}" };
        }

        private SkillResult PauseMusic()
        {
            if (_waveOut == null)
                return new SkillResult { Success = false, Error = "没有正在播放的音乐" };

            if (_playbackState == PlaybackState.Playing)
            {
                _waveOut.Pause();
                _playbackState = PlaybackState.Paused;
                return new SkillResult { Success = true, Content = "音乐已暂停" };
            }
            else if (_playbackState == PlaybackState.Paused)
            {
                _waveOut.Play();
                _playbackState = PlaybackState.Playing;
                return new SkillResult { Success = true, Content = "音乐继续播放" };
            }
            else
            {
                return new SkillResult { Success = false, Error = "当前状态无法暂停" };
            }
        }

        private SkillResult StopMusic()
        {
            if (_waveOut == null)
                return new SkillResult { Success = true, Content = "没有正在播放的音乐" };

            _waveOut.Stop();
            _playbackState = PlaybackState.Stopped;
            return new SkillResult { Success = true, Content = "音乐已停止" };
        }

        private SkillResult SetVolume(Dictionary<string, object> arguments)
        {
            var volume = Convert.ToInt32(arguments["volume"]);

            if (_waveOut == null)
            {
                _volume = Math.Max(0, Math.Min(100, volume)) / 100f;
                return new SkillResult { Success = true, Content = $"音量已设置为: {volume}" };
            }

            _waveOut.Volume = Math.Max(0, Math.Min(100, volume)) / 100f;
            _volume = _waveOut.Volume;
            return new SkillResult { Success = true, Content = $"音量已设置为: {volume}" };
        }

        private SkillResult NextTrack()
        {
            if (_playlist.Count == 0)
                return new SkillResult { Success = false, Error = "播放列表为空" };

            _currentTrackIndex = (_currentTrackIndex + 1) % _playlist.Count;

            DisposeWavePlayer();

            _audioFile = new AudioFileReader(_playlist[_currentTrackIndex]);
            _waveOut = new WaveOutEvent();
            _waveOut.Init(_audioFile);
            _waveOut.Volume = _volume;
            _waveOut.PlaybackStopped += WaveOut_PlaybackStopped;
            _waveOut.Play();

            _playbackState = PlaybackState.Playing;

            return new SkillResult { Success = true, Content = $"正在播放: {Path.GetFileName(_playlist[_currentTrackIndex])}" };
        }

        private SkillResult PreviousTrack()
        {
            if (_playlist.Count == 0)
                return new SkillResult { Success = false, Error = "播放列表为空" };

            _currentTrackIndex = (_currentTrackIndex - 1 + _playlist.Count) % _playlist.Count;

            DisposeWavePlayer();

            _audioFile = new AudioFileReader(_playlist[_currentTrackIndex]);
            _waveOut = new WaveOutEvent();
            _waveOut.Init(_audioFile);
            _waveOut.Volume = _volume;
            _waveOut.PlaybackStopped += WaveOut_PlaybackStopped;
            _waveOut.Play();

            _playbackState = PlaybackState.Playing;

            return new SkillResult { Success = true, Content = $"正在播放: {Path.GetFileName(_playlist[_currentTrackIndex])}" };
        }

        private SkillResult GetPlayerStatus()
        {
            if (_waveOut == null)
                return new SkillResult { Success = true, Content = "播放器未初始化" };

            var state = _playbackState switch
            {
                PlaybackState.Stopped => "已停止",
                PlaybackState.Playing => "正在播放",
                PlaybackState.Paused => "已暂停",
                _ => "未知状态"
            };

            var currentTrack = _playlist.Count > 0 && _currentTrackIndex < _playlist.Count
                ? Path.GetFileName(_playlist[_currentTrackIndex])
                : "无";

            var currentTime = _audioFile?.CurrentTime.ToString(@"mm\:ss") ?? "00:00";
            var totalTime = _audioFile?.TotalTime.ToString(@"mm\:ss") ?? "00:00";

            return new SkillResult 
            { 
                Success = true, 
                Content = $"播放器状态: {state}\n当前曲目: {currentTrack}\n播放进度: {currentTime}/{totalTime}\n音量: {(int)(_volume * 100)}\n播放列表: {_playlist.Count} 首\n随机播放: {(_shuffle ? "是" : "否")}" 
            };
        }

        private void WaveOut_PlaybackStopped(object sender, StoppedEventArgs e)
        {
            if (_playlist.Count > 1)
            {
                _currentTrackIndex = (_currentTrackIndex + 1) % _playlist.Count;

                try
                {
                    DisposeWavePlayer();

                    _audioFile = new AudioFileReader(_playlist[_currentTrackIndex]);
                    _waveOut = new WaveOutEvent();
                    _waveOut.Init(_audioFile);
                    _waveOut.Volume = _volume;
                    _waveOut.PlaybackStopped += WaveOut_PlaybackStopped;
                    _waveOut.Play();

                    _playbackState = PlaybackState.Playing;
                }
                catch { }
            }
        }

        private void DisposeWavePlayer()
        {
            if (_waveOut != null)
            {
                _waveOut.PlaybackStopped -= WaveOut_PlaybackStopped;
                _waveOut.Stop();
                _waveOut.Dispose();
                _waveOut = null;
            }

            if (_audioFile != null)
            {
                _audioFile.Dispose();
                _audioFile = null;
            }
        }
    }
}