using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using Dalamud.Plugin.Services;
using Lumina.Data;
using Lumina.Excel.Sheets;
using Lumina.Text.ReadOnly;

namespace OmicronMountMusicFixer;

public class SongList
{
	private const string SheetPath = "https://docs.google.com/spreadsheets/d/1s-xJjxqp6pwS7oewNy1aOQnr3gaJbewvIBbyYchZ6No/gviz/tq?tqx=out:csv&sheet={0}";

	private const string SheetFileName = "xiv_bgm_{0}.csv";

	private readonly Dictionary<int, Song> _songs;

	private readonly HttpClient _client = new HttpClient();

	private static SongList _instance;

	public static SongList Instance => _instance ?? (_instance = new SongList());

	private SongList()
	{
		_songs = new Dictionary<int, Song>();
		try
		{
			DalamudApi.PluginLog.Information("[SongList] Checking for updated bgm sheets", Array.Empty<object>());
			LoadMetadataSheet(GetRemoteSheet("metadata"));
			LoadLangSheet(GetRemoteSheet("en"), "en");
			LoadLangSheet(GetRemoteSheet("ja"), "ja");
			LoadLangSheet(GetRemoteSheet("de"), "de");
			LoadLangSheet(GetRemoteSheet("fr"), "fr");
			LoadLangSheet(GetRemoteSheet("zh"), "zh");
		}
		catch (Exception ex)
		{
			DalamudApi.PluginLog.Error(ex, "[SongList] Orchestrion failed to update bgm sheet; using previous version", Array.Empty<object>());
			LoadMetadataSheet(GetLocalSheet("metadata"));
			LoadLangSheet(GetLocalSheet("en"), "en");
			LoadLangSheet(GetLocalSheet("ja"), "ja");
			LoadLangSheet(GetLocalSheet("de"), "de");
			LoadLangSheet(GetLocalSheet("fr"), "fr");
			LoadLangSheet(GetLocalSheet("zh"), "zh");
		}
	}

	private void DebugLogSongs()
	{
		DalamudApi.PluginLog.Debug("Songs:", Array.Empty<object>());
		foreach (KeyValuePair<int, Song> song in _songs)
		{
			DalamudApi.PluginLog.Debug($"{song.Key}: {song.Value.Id} {song.Value.Strings} {song.Value.FilePath}", Array.Empty<object>());
		}
	}

	private string GetRemoteSheet(string code)
	{
		return _client.GetStringAsync($"https://docs.google.com/spreadsheets/d/1s-xJjxqp6pwS7oewNy1aOQnr3gaJbewvIBbyYchZ6No/gviz/tq?tqx=out:csv&sheet={code}").Result;
	}

	private string GetLocalSheet(string code)
	{
		return File.ReadAllText(Path.Combine(DalamudApi.PluginInterface.AssemblyLocation.DirectoryName, $"xiv_bgm_{code}.csv"));
	}

	private void SaveLocalSheet(string text, string code)
	{
		File.WriteAllText(Path.Combine(DalamudApi.PluginInterface.AssemblyLocation.DirectoryName, $"xiv_bgm_{code}.csv"), text);
	}

	private void LoadMetadataSheet(string sheetText)
	{
		//IL_017a: Unknown result type (might be due to invalid IL or missing references)
		//IL_019c: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_0209: Unknown result type (might be due to invalid IL or missing references)
		//IL_020e: Unknown result type (might be due to invalid IL or missing references)
		_songs.Clear();
		Dictionary<uint, BGM> dictionary = ((IEnumerable<BGM>)DalamudApi.DataManager.Excel.GetSheet<BGM>((Language?)null, (string)null)).ToDictionary((BGM k) => ((BGM)(ref k)).RowId, (BGM v) => v);
		string[] array = sheetText.Split('\n');
		for (int num = 1; num < array.Length; num++)
		{
			string[] array2 = array[num].Split(new string[1] { "\"," }, StringSplitOptions.None);
			int num2 = int.Parse(array2[0].Substring(1));
			string text = array2[1].Substring(1, array2[1].Length - 2).Replace("\"\"", "\"");
			double result;
			bool num3 = double.TryParse(text, out result);
			TimeSpan duration = (num3 ? TimeSpan.FromSeconds(result) : TimeSpan.Zero);
			if (!num3)
			{
				DalamudApi.PluginLog.Debug($"failed parse {num2}: {text}", Array.Empty<object>());
			}
			if (dictionary.TryGetValue((uint)num2, out var value))
			{
				DalamudApi.PluginLog.Debug($"{num2}", Array.Empty<object>());
				DalamudApi.PluginLog.Debug($"{((BGM)(ref value)).File}", Array.Empty<object>());
				IPluginLog pluginLog = DalamudApi.PluginLog;
				ReadOnlySeString file = ((BGM)(ref value)).File;
				pluginLog.Debug(((ReadOnlySeString)(ref file)).ExtractText() ?? "", Array.Empty<object>());
				Song song = new Song();
				song.Id = num2;
				file = ((BGM)(ref value)).File;
				song.FilePath = ((ReadOnlySeString)(ref file)).ExtractText();
				song.SpecialMode = ((BGM)(ref value)).SpecialMode;
				song.DisableRestart = ((BGM)(ref value)).DisableRestart;
				IDataManager dataManager = DalamudApi.DataManager;
				file = ((BGM)(ref value)).File;
				song.FileExists = dataManager.FileExists(((ReadOnlySeString)(ref file)).ExtractText());
				song.Duration = duration;
				Song value2 = song;
				_songs[num2] = value2;
			}
		}
		SaveLocalSheet(sheetText, "metadata");
	}

	private void LoadLangSheet(string sheetText, string code)
	{
		string[] array = sheetText.Split('\n');
		for (int i = 1; i < array.Length; i++)
		{
			string[] array2 = array[i].Split(new string[1] { "\"," }, StringSplitOptions.None);
			int key = int.Parse(array2[0].Substring(1));
			string text = array2[1].Substring(1);
			string alternateName = array2[2].Substring(1);
			string specialModeName = array2[3].Substring(1);
			string locations = array2[4].Substring(1);
			string additionalInfo = array2[5].Substring(1, array2[5].Length - 2).Replace("\"\"", "\"");
			if (_songs.TryGetValue(key, out var value))
			{
				if ((code == "en" && string.IsNullOrEmpty(text)) || text == "Null BGM" || text == "test")
				{
					_songs.Remove(key);
				}
				value.Strings[code] = new SongStrings
				{
					Name = text,
					AlternateName = alternateName,
					SpecialModeName = specialModeName,
					Locations = locations,
					AdditionalInfo = additionalInfo
				};
			}
		}
		SaveLocalSheet(sheetText, code);
	}

	public bool IsDisableRestart(int id)
	{
		if (_songs.TryGetValue(id, out var value))
		{
			return value.DisableRestart;
		}
		return false;
	}

	public Dictionary<int, Song> GetSongs()
	{
		return _songs;
	}

	public Song GetSong(int id)
	{
		if (!_songs.TryGetValue(id, out var value))
		{
			return default(Song);
		}
		return value;
	}

	public bool TryGetSong(int id, out Song song)
	{
		return _songs.TryGetValue(id, out song);
	}

	public string GetSongTitle(int id)
	{
		if (!_songs.TryGetValue(id, out var value))
		{
			return "";
		}
		return value.Name;
	}

	public bool SongExists(int id)
	{
		return _songs.ContainsKey(id);
	}

	public bool TryGetSongByName(string name, out int songId)
	{
		songId = 0;
		foreach (Song value in _songs.Values)
		{
			foreach (string availableTitleLanguage in Util.AvailableTitleLanguages)
			{
				if (string.Equals(value.Strings[availableTitleLanguage].Name, name, StringComparison.InvariantCultureIgnoreCase) || string.Equals(value.Strings[availableTitleLanguage].AlternateName, name, StringComparison.InvariantCultureIgnoreCase))
				{
					songId = value.Id;
					return true;
				}
			}
		}
		return false;
	}
}
