using SimpleHttp;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using TYTD;
using Newtonsoft.Json;
using System.IO;
using YoutubeExplode.Channels;
using Hyperlinq;
namespace Autofetch_YT
{   
    public class RSSState
    {
        public RSSState()
        {

            ReqDuration = new TimeSpan(0,30, 0);
        }
        public Dictionary<string,YoutubeRSS> VideoRSS { get; set; }
        public TimeSpan ReqDuration { get; set; }
    }

    public class AutofetchYT : Api
    {
        RSSState state;
        public override void OnStart()
        {
            Route.Add("/api/Extensions/AutofetchYT/", (HttpAction)Autofetch);
            Route.Add("/api/Extensions/AutofetchYT/change", (HttpAction)AutofetchChange, "POST");
            Load();
            SetTimer(state.ReqDuration);
        }
        public override IEnumerable<KeyValuePair<string, string>> GetUrls()
        {
            yield return new KeyValuePair<string, string>("AutoFetch", "api/Extensions/AutofetchYT/");
        }
        
        protected override void TimerElapsed()
        {
            foreach(var item in state.VideoRSS)
            {
                item.Value.Scan();
            }
        }
        
        public HElement GetSite()
        {
            return H.html(
                H.head(
                    H.meta(e => e.charset("UTF8")),
                    H.meta(e => e.http_equiv("X-UA-Compatible").content("IE=edge")),
                    H.meta(e => e.name("viewport").content("width=device-width, initial-scale=1.0")),
                    H.title("Autofetch YT"),
                    H.link(e => e.href("https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css").rel("stylesheet")),
                    H.script(e => e.src("https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js")),
                    H.script(e => e.src("https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js")),
                    H.link(e => e.href("../../favicon.ico").rel("shortcut icon").type("image/x-icon").Custom("crossorigin","use-credentials"))
                    ),
                H.body(
                    H.div(e=>e.css("container"),
                            H.h1("Autofetch YT"),
                            H.ul(e=>e.css("nav nav-tabs"),
                                H.li(e=>e.css("active"),
                                    H.a(e=>e.Custom("data-toggle","tab").href("#addchannel"),"Add")
                                ),
                                H.li(
                                    H.a(e=> e.Custom("data-toggle", "tab").href("#channels"),"Channels")
                                ),
                                H.li(
                                    H.a(e => e.Custom("data-toggle", "tab").href("#more"), "More")
                                )
                           ),
                           H.div(e=>e.css("tab-content"),
                                H.div(e=>e.id("addchannel").css("tab-pane fad in active"),
                                    H.br(),
                                    H.div(e=>e.css("container"),
                                        H.form(e=>e.action("change").method("POST"),
                                            H.input(e=>e.type("hidden").name("operation").value("add")),
                                            H.input(e=>e.type("text").placeholder("Name").name("key")),
                                            H.br(),H.br(),
                                            H.input(e=>e.type("text").placeholder("Channel ID or URL").name("value")),
                                            H.br(),H.br(),
                                            H.input(e=>e.type("submit").value("Add Channel").css("btn btn-primary"))
                                        )
                                    )
                                ),
                                H.div(e=>e.id("channels").css("tab-pane fade"),
                                    H.br(),
                                    H.div(e=>e.css("container"),
                                        H.table(e=>e.css("table table-striped"),
                                            H.thead(
                                                H.tr(
                                                    H.th("Name"),
                                                    H.th("Channel Url"),
                                                    H.th("Delete")
                                                )
                                            ),
                                            H.tbody(
                                                from item in state.VideoRSS
                                                select RSSTr(item)
                                            )

                                        )
                                    )
                                ),
                                H.div(e => e.id("more").css("tab-pane fade"),
                                    H.br(),
                                    H.div(e => e.css("container"),
                                        H.form(e=>e.action("change").method("POST"),
                                            H.h1("Clear All Channels"),
                                            H.input(e=>e.type("hidden").name("operation").value("clear")),
                                            H.input(e=>e.type("submit").value("Clear").css("btn btn-danger"))
                                        ),
                                        H.form(e => e.action("change").method("POST"),
                                            H.h1("Interval"),
                                            H.input(e=>e.type("hidden").name("operation").value("setinterval")),
                                            H.input(e=>e.type("text").name("interval").value(state.ReqDuration.ToString())),
                                            H.br(),H.br(),
                                            H.input(e=>e.type("submit").value("Set Interval").css("btn btn-primary"))
                                        )

                                    )
                                )

                    )
                )
                ));
        }
        public HElement RSSTr(KeyValuePair<string,YoutubeRSS> item)
        { string url = $"https://www.youtube.com/channel/{item.Value.ID}";
            return H.tr(
                    H.td(item.Key),
                    H.td(H.A(url, url)),
                    H.td(
                        H.form(
                                H.input(e => e.type("submit").css("btn-danger").value("X")),
                                H.input(e => e.type("hidden").name("operation").value("delete")),
                                H.input(e => e.type("hidden").name("key").value(item.Value.ID)
                            )

                )));
        }
        public void Autofetch(HttpListenerRequest req, HttpListenerResponse resp, Dictionary<string, string> args)
        {
         
            resp.AsText(GetSite().ToString());
        }
        public void AutofetchChange(HttpListenerRequest req, HttpListenerResponse resp, Dictionary<string, string> args)
        {
            TimerEnabled = false;
            req.ParseBody(args);
            if (args.ContainsKey("operation"))
            {
                string operation = args["operation"];
                switch (operation)
                {
                    case "add":
                        if(args.ContainsKey("key") && args.ContainsKey("value"))
                        {
                            string key = args["key"];
                            string value = args["value"];
                            ChannelId? id = ChannelId.TryParse(value);
                            if(id.HasValue)
                            {
                                state.VideoRSS.Add(key, new YoutubeRSS(this, id.Value));
                            }

                        }
                        break;
                    case "delete":
                        if (args.ContainsKey("key"))
                        {
                            string key = args["key"];
                            if(state.VideoRSS.ContainsKey(key))
                            {
                                state.VideoRSS.Remove(key);
                            }
                        }
                        break;
                    case "clear":
                        state.VideoRSS.Clear();
                        break;
                    case "setinterval":
                        if (args.ContainsKey("interval"))
                        {
                            TimeSpan span;
                            if (TimeSpan.TryParse(args["interval"], out span))
                            {
                                state.ReqDuration = span;
                            }
                        }
                        break;
                }
            }
            Save();
            resp.AsText("<script>window.location.href=\".\"</script>");
        }
        public void Save()
        {
            string videoInfo = Path.Combine(StorageLocation, "autofetch.json");
            File.WriteAllText(videoInfo, JsonConvert.SerializeObject(state));
            SetTimer(state.ReqDuration);
        }
        public void Load()
        {
            string videoInfo = Path.Combine(StorageLocation, "autofetch.json");
            if (File.Exists(videoInfo))
            {
                state = JsonConvert.DeserializeObject<RSSState>(File.ReadAllText(videoInfo));
                foreach(var item in state.VideoRSS)
                {
                    item.Value.SetApi(this);
                }
            }
            else
            {
                state = new RSSState();
                state.VideoRSS = new Dictionary<string, YoutubeRSS>();
            }
        }
    }
   public class YoutubeRSS
    {
        Api api;
        public string ID { get; set; }

        public YoutubeRSS(Api api,string id)
        {
            this.api = api;
            this.ID = id;
            
            //  UCZkURf9tDolFOeuw_4RD7XQ
        }
        public YoutubeRSS()
        {

        }
        public void SetApi(Api api)
        {
            this.api = api;
        }
        public void Scan()
        {
            
            var xml = System.Xml.XmlReader.Create("https://www.youtube.com/feeds/videos.xml?channel_id=" + this.ID);
            var feed = System.ServiceModel.Syndication.SyndicationFeed.Load(xml);



            foreach (var item in feed.Items)
            {

                string id = item.Id;

                
               
                   api.AddItem(id.Substring("yt:videoId".Length - 1));
                
            }

            
        }

    }
}
