using Newtonsoft.Json.Linq;
using System.Diagnostics;
using System.Text;
using System.Text.RegularExpressions;
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()
        {
            try { 
            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);
            }
            catch (Exception ex)
            {

                Debug.WriteLine(ex.Message + ex.StackTrace);

            }
            return ("",0,0);
        }

        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)
        {
            string text = "";
            try
            {
                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);

           text = await res.Content.ReadAsStringAsync();
                return text.Split(',')[0];
            }
            catch (Exception ex)
            {

                Debug.WriteLine(ex.Message + ex.StackTrace);

            }

            return "";


        }

        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);
            
            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 radiko_xml_write()
        {
            String xml_path = "radiko_epg.xml";
            if (File.Exists(xml_path))
            {
                try { 
                File.Delete(xml_path);
            }
            catch (Exception ex)
            {

                Debug.WriteLine(ex.Message + ex.StackTrace);

            }

        }
            
            using HttpClient client = new HttpClient();
            try { 
            string html =
                await client.GetStringAsync("https://radiko.jp/area");
           
            Match m = Regex.Match(
                html,
                @"class=""(JP\d+)"""
            );

            string areaId = m.Groups[1].Value;
          
            string date = DateTime.Now.ToString("yyyyMMdd");

            string url =
                $"https://radiko.jp/v3/program/date/{date}/{areaId}.xml";

         

            string xml = await client.GetStringAsync(url);
                await File.WriteAllTextAsync(xml_path, xml, Encoding.UTF8);


            }
            catch (System.Exception ex)
            {
                Debug.WriteLine(ex.Message + ex.StackTrace);

            }

   
        }
        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;

        }
    }
}
