using System.Diagnostics;
using System.Text;
using System.Xml.Linq;

namespace DragonVideoPlayer
{
    public class RadikoClient
    {
        const string FIXED_KEY = "bcd151073c03b352e1ef2fd66c32209da9ca0afa";

        HttpClient client = new HttpClient();

        public string AuthToken;
        public string AreaId;

        public async Task Init()
        {
            var auth1 = await Auth1();

            AuthToken = auth1.token;

            string partialKey = CreatePartialKey(auth1.offset, auth1.length);

            AreaId = await Auth2(AuthToken, partialKey);
        }

        async Task<(string token, int offset, int length)> Auth1()
        {
            var req = new HttpRequestMessage(HttpMethod.Get,
                "https://radiko.jp/v2/api/auth1");

            req.Headers.Add("X-Radiko-App", "pc_html5");
            req.Headers.Add("X-Radiko-App-Version", "0.0.1");
            req.Headers.Add("X-Radiko-User", "dummy_user");
            req.Headers.Add("X-Radiko-Device", "pc");

            var res = await client.SendAsync(req);

            string token = res.Headers.GetValues("X-Radiko-AuthToken").First();

            int offset = int.Parse(res.Headers.GetValues("X-Radiko-KeyOffset").First());

            int length = int.Parse(res.Headers.GetValues("X-Radiko-KeyLength").First());

            return (token, offset, length);
        }

        string CreatePartialKey(int offset, int length)
        {
            string key = FIXED_KEY.Substring(offset, length);

            return Convert.ToBase64String(Encoding.ASCII.GetBytes(key));
        }

        async Task<string> Auth2(string token, string partialKey)
        {
            var req = new HttpRequestMessage(HttpMethod.Get,
                "https://radiko.jp/v2/api/auth2");

            req.Headers.Add("X-Radiko-App", "pc_html5");
            req.Headers.Add("X-Radiko-App-Version", "0.0.1");
            req.Headers.Add("X-Radiko-User", "dummy_user");
            req.Headers.Add("X-Radiko-Device", "pc");

            req.Headers.Add("X-Radiko-AuthToken", token);
            req.Headers.Add("X-Radiko-Partialkey", partialKey);

            var res = await client.SendAsync(req);

            string text = await res.Content.ReadAsStringAsync();



            return text.Split(',')[0];
        }

        public async Task<List<(string id, string name)>> GetStations()
        {
            string url = $"https://radiko.jp/v3/station/list/{AreaId}.xml";

            string xml = await client.GetStringAsync(url);
            Debug.WriteLine(xml);
            XDocument doc = XDocument.Parse(xml);

            var stations = doc.Descendants("station")
                .Select(x => (
                    id: x.Element("id").Value,
                    name: x.Element("name").Value
                ))
                .ToList();

            return stations;


        }

        public async Task<string> GetStreamUrl(string stationId)
        {

            string url = $"https://radiko.jp/v2/station/stream/{stationId}.xml";

            string xml = await client.GetStringAsync(url);

            XDocument doc = XDocument.Parse(xml);

            var urlNode = doc.Descendants("url").FirstOrDefault();

            if (urlNode == null)
                return null;

            var playlistNode = urlNode.Element("playlist_create_url");

            if (playlistNode == null)
                return null;

            return playlistNode.Value;

            return null;

        }
    }
}
