﻿using Autofac.Integration.Mvc;
using Jumbo.CognitiveService;
using Jumbo.Helpers;
using Microsoft.Bot.Builder.Dialogs;
using Microsoft.Bot.Builder.Luis;
using Microsoft.Bot.Builder.Luis.Models;
using Microsoft.Bot.Connector;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;
using Autofac;
using Jumbo.Dialogs.Ask;
using System.Diagnostics;

namespace Jumbo.Dialogs.English
{
    
    public partial class JumboEnglishDialog:LuisDialog<object>
    {
        [LuisIntent("Translation")]
        public async Task Translation(IDialogContext context, LuisResult result)
        {
            Logger.Info($"In Translation");
            var language = result.Entities.Where(e => e.Type == "TranslationTargetLang").SingleOrDefault()?.Entity;
            var text = result.Entities.Where(e => e.Type == "TranslationText").SingleOrDefault()?.Entity;
            Logger.Info($"{language} - {text}");
            if (!string.IsNullOrEmpty(language))
            {
                SaveState(context, "PreviousLanguage", language);
            }
            else if(!TryGetState(context, "PreviousLanguage", out language))
            {
                await ReplyAsync(context, context.Activity.AsMessageActivity() as Activity, 
                    new SearchResult { Text = App_GlobalResources.TextMessages.BotTranslationMissingParameter });
            }

            var translator = new BingTranslator();
            var token = await translator.AcquireTokenAsync(ConfigurationManager.AppSettings["Translator_Key"]);
            var lc = GetLanguageCode(language);
            Logger.Info($"Language - {lc}");
            var resultText = await translator.TranslateAsync(text, lc);
            Logger.Info($"resultText - {resultText}");
            lc = GetTranslatorLanguageCode(language);
            await ReplyAsync(context, context.Activity.AsMessageActivity() as Activity, new SearchResult { Text = resultText }, lc);

            context.Done(resultText);
        }
        public static string GetLanguageCode(string language)
        {
            switch (language.ToLower())
            {
                case "chinese tranditional":
                case "chinese traditional":
                case "traditional chinese":
                case "tranditional chinese":
                    return "zh-CHT";
                case "chinese simplified":
                case "simplified chinese":
                    return "zh-CHS";
                case "english":
                    return "en";
                default:
                    var cul = System.Globalization.CultureInfo.GetCultures(System.Globalization.CultureTypes.AllCultures).Where(c => c.EnglishName.ToLower() == language).SingleOrDefault();
                    if (cul == null)
                        return null;
                    return cul.TextInfo.CultureName;
            }
            //return "zh-CHT";
        }
        public static string GetTranslatorLanguageCode(string language)
        {
            switch (language.ToLower())
            {
                case "chinese tranditional":
                case "chinese traditional":
                case "traditional chinese":
                case "tranditional chinese":
                    return "zh-TW";
                case "chinese simplified":
                case "simplified chinese":
                    return "zh-CN";
                case "english":
                    return "en-US";
                default:
                    var cul = System.Globalization.CultureInfo.GetCultures(System.Globalization.CultureTypes.AllCultures).Where(c => c.EnglishName.ToLower() == language).SingleOrDefault();
                    if (cul == null)
                        return null;
                    return cul.TextInfo.CultureName;
            }
            //return "zh-CHT";
        }
        private async Task ReplyAsync(IDialogContext context, Activity activity, SearchResult result, string languageCode)
        {
            Activity reply = activity.CreateReply(result.Text);
            CognitiveService.BingTTS tts = new CognitiveService.BingTTS(ConfigurationManager.AppSettings["BingSpeechAPI_Key"]);
            //var token = await tts.AcquireTokenAsync();
            Stream stream = await tts.Synthesize(reply.Text, languageCode);
            var sh = new StorageHelper();
            var guid = Guid.NewGuid().ToString();
            var fn = sh.UploadFile(guid + ".wav", stream);
            Logger.Info($"result uploaded to {fn}");
            if (reply.Attachments == null)
            {
                reply.Attachments = new List<Attachment>();
            }

            SetupAttachment(reply, activity, fn, guid, result);
            //if (activity.ChannelId.ToLower().Contains("jumbo") == true)
            //{

            //    reply.Attachments.Add(new Attachment()
            //    {
            //        ContentUrl = fn,
            //        ContentType = "audio/wav",
            //        Name = guid + ".wav"
            //    });
            //}
            //else
            //{
            //    var card = GenerateVideoCard(activity.Text, text, fn, "audio/wav");
            //    reply.Attachments.Add(card.ToAttachment());
            //}

            await context.PostAsync(reply);
        }
        private void SetupAttachment(Activity reply, Activity activity, string fn, string name, SearchResult result)
        {
            if (activity.ChannelId.ToLower().Contains("jumbo") ||
                activity.ChannelId.ToLower().Contains("directline"))
            {

                reply.Attachments.Add(new Attachment()
                {
                    ContentUrl = fn,
                    ContentType = "audio/wav",
                    Name = name
                });
            }
            else
            {
                var card = GenerateVideoCard(activity.Text, result.Text, fn, "audio/wav");
                if (result.ImageUrl != null)
                {
                    card.Image = new ThumbnailUrl(result.ImageUrl);
                }
                reply.Attachments.Add(card.ToAttachment());
            }
        }
        private VideoCard GenerateVideoCard(string title, string text, string file, string contentType)
        {
            VideoCard card = new VideoCard()
            {
                Media = new MediaUrl[] { new MediaUrl(file) },
                Autostart = false,
                Title = title,
                Subtitle = text,
                Autoloop = false
            };

            return card;
        }
    }
}