using Agent86.Models;
using Agent86.Services;
using Markdig;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Newtonsoft.Json;
using System.Text.RegularExpressions;

namespace Agent86.Pages
{
    [Authorize(Roles = "user")]
    public class IndexModel : PageModel
    {

        private readonly OllamaService _ollama;

        public IndexModel(OllamaService ollama)
        {
            _ollama = ollama;
        }

        [BindProperty]
        public string UserInput { get; set; }

        [BindProperty]
        public Scene theScene { get; set; } = new();
        [BindProperty]
        public List<Scene> Scenes { get; set; } = new();

        public List<ChatMessage> ChatHistory { get; set; } = new();

        private const string SessionKey = "ChatHistory";

        private const string SessionScene = "Scene";

        //private const string RoleplayContext = @"you are a movie theater with two theaters.
//You are contacted by a software developer who wants to create an online shop for your movie theater.
//You want this online shop to sell tickets for the events and possibly also to sell popcorn and drinks.
//Stay in character as a curious and slightly demanding customer.";


        public static string ToPlainText(string markdown)
        {
            // Convert markdown to HTML
            var html = Markdown.ToHtml(markdown);

            // Remove HTML tags
            var plainText = Regex.Replace(html, "<.*?>", string.Empty);

            // Decode HTML entities (e.g. &amp; -> &)
            plainText = System.Net.WebUtility.HtmlDecode(plainText);

            return plainText;
        }

        public void OnGet()
        {
            LoadHistory();
            if (theScene.role == "error")
            {
                // Handle the case where the scene role is not set
                Scenes = [.. new Persistence.DbOps().GetScenes().OrderBy(s => s.role)];
            }
        }

        public async Task<IActionResult> OnPostAsync(string role = "error")
        {
            LoadHistory();
            if (role != "error") 
            {
                // Handle the case where the scene role is not set
                Scenes = new Persistence.DbOps().GetScenes();
                foreach (var scene in Scenes)
                {
                    if (scene.role == role)
                    {
                        theScene = scene;
                        break;
                    }
                }
            }
            else
            {
                ChatHistory.Add(new ChatMessage { Role = theScene.me, Content = UserInput });

                var reply = await _ollama.GenerateReplyAsync(ChatHistory, theScene.instruction);

                ChatHistory.Add(new ChatMessage { Role = theScene.customer, Content = ToPlainText(reply) });

            }
            SaveHistory();
            return RedirectToPage();
        }

        private void LoadHistory()
        {
            var data = HttpContext.Session.GetString(SessionKey);
            if (!string.IsNullOrEmpty(data))
            {
                ChatHistory = JsonConvert.DeserializeObject<List<ChatMessage>>(data);
            }
            data = HttpContext.Session.GetString(SessionScene);
            if (!string.IsNullOrEmpty(data))
            {
                theScene = JsonConvert.DeserializeObject<Scene>(HttpContext.Session.GetString(SessionScene));
            }
        }

        private void SaveHistory()
        {
            HttpContext.Session.SetString(SessionKey,
                JsonConvert.SerializeObject(ChatHistory));
            HttpContext.Session.SetString(SessionScene,
                JsonConvert.SerializeObject(theScene));
        }
    }
}
