using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Tesses.WebServer;
namespace BibleServer
{
    public class MyBibleServer
    {
        //bigger book : book : chapter : verseNo
        public Dictionary<string,ScriptureRoot> Bibles {get;set;}=new Dictionary<string, ScriptureRoot>();
        public MyBibleServer()
        {
            foreach(var item in Directory.GetFiles(Path.Combine("data","scriptures")))
            {
                var name=FixName(item);
                var res=JsonConvert.DeserializeObject<ScriptureRoot>(File.ReadAllText(item));
                if(res != null)
                {
                    Bibles.Add(name, res);
                }
            }
        }

        public Server GetServer()
        {
            RouteServer routeServer = new RouteServer();
            MountableServer mountableServer=new MountableServer(new StaticServer(Path.Combine("data","www")){RedirectToRootInsteadOfNotFound=true});
            
            mountableServer.Mount("/api/v1/",routeServer);

            routeServer.Add("/GetBibles",GetBibles);

            routeServer.Add("/GetBooks",GetBooks);
            routeServer.Add("/GetVerse",GetVerse);
            routeServer.Add("/GetChapterCount",GetChapterCount);
            routeServer.Add("/GetVerseCount",GetVerseCount);
            routeServer.Add("/GetVerses",GetVerses);
            return mountableServer;
        }
        private async Task GetChapterCount(ServerContext ctx)
        {
            if(ctx.QueryParams.TryGetFirst("bible",out var bible))
            {
                if(Bibles.TryGetValue(bible,out var root))
                {
                     if(ctx.QueryParams.TryGetFirst("book",out var bookName))
                    {
                        foreach(var book in root.Books)
                        {
                            if(book.Book == bookName)
                            {
                                await ctx.SendJsonAsync(book.Chapters.Count);
                            }
                        }
                    }
                }
            }
        }
        private async Task GetBooks(ServerContext ctx)
        {
            if(ctx.QueryParams.TryGetFirst("bible",out var bible))
            {
                if(Bibles.TryGetValue(bible,out var root))
                {
                    ScriptureBooksResponse response = new ScriptureBooksResponse(bible,root);
                    await ctx.SendJsonAsync(response);
                }
            }
        }
        private async Task GetVerses(ServerContext ctx)
        {
            if(ctx.QueryParams.TryGetFirst("bible",out var bible))
            {
                

                if(Bibles.TryGetValue(bible,out var root))
                {
                    if(ctx.QueryParams.TryGetFirst("book",out var bookName))
                    {
                        if(ctx.QueryParams.TryGetFirst("chapter",out var chapterStr))
                        if(int.TryParse(chapterStr,out var chapter))
                        foreach(var book in root.Books)
                        {
                            if(book.Book == bookName)
                            {
                                if(chapter <= book.Chapters.Count)
                                {
                                    var c=book.Chapters[chapter-1];
                                    await ctx.SendJsonAsync(c.Verses);
                                }
                                break;
                            }
                        }
                    }
                }
            }
        }
        private async Task GetVerse(ServerContext ctx)
        {
            if(ctx.QueryParams.TryGetFirst("bible",out var bible))
            {
                

                if(Bibles.TryGetValue(bible,out var root))
                {
                    if(ctx.QueryParams.TryGetFirst("book",out var bookName))
                    {
                        if(ctx.QueryParams.TryGetFirst("chapter",out var chapterStr))
                        if(int.TryParse(chapterStr,out var chapter))
                        if(ctx.QueryParams.TryGetFirst("verse",out var verseStr))
                        if(int.TryParse(verseStr,out var verse))
                        foreach(var book in root.Books)
                        {
                            if(book.Book == bookName)
                            {
                                if(chapter <= book.Chapters.Count)
                                {
                                    var c=book.Chapters[chapter-1];
                                    if(verse <= c.Verses.Count)
                                    {
                                        var v = c.Verses[verse-1];
                                        await ctx.SendJsonAsync(v);
                                    }
                                    //await ctx.SendJsonAsync(c.Verses);
                                }
                                break;
                            }
                        }
                    }
                }
            }
        }
        
        private async Task GetVerseCount(ServerContext ctx)
        {
            if(ctx.QueryParams.TryGetFirst("bible",out var bible))
            {
                

                if(Bibles.TryGetValue(bible,out var root))
                {
                    if(ctx.QueryParams.TryGetFirst("book",out var bookName))
                    {
                        if(ctx.QueryParams.TryGetFirst("chapter",out var chapterStr))
                        if(int.TryParse(chapterStr,out var chapter))
                        foreach(var book in root.Books)
                        {
                            if(book.Book == bookName)
                            {
                                if(chapter <= book.Chapters.Count)
                                {
                                    var c=book.Chapters[chapter-1];
                                    await ctx.SendJsonAsync(c.Verses.Count);
                                }
                                break;
                            }
                        }
                    }
                }
            }
        }

        private async Task GetBibles(ServerContext ctx)
        {
            await ctx.SendJsonAsync(Bibles.Keys.ToList());
        }

        private string FixName(string item)
        {
            var n = Path.GetFileNameWithoutExtension(item).Split(new char[]{'-'});
          
            StringBuilder builder = new StringBuilder();
            for(int i = 0;i<n.Length;i++)
            {
                if(i > 0) builder.Append(' ');
                var item2 = n[i];
                for(int j = 0; j < item2.Length;j++)
                {
                    builder.Append(j == 0 ? char.ToUpper(item2[0]) : item2[j]);
                }
            }
            return builder.ToString();
        }
    }
}
