using ChatMvc.Models;
using Microsoft.AspNetCore.Mvc;
using System.Net.Http.Headers;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using Newtonsoft.Json;
using Microsoft.AspNetCore.Antiforgery;
using Microsoft.AspNetCore.Authorization;
using System.Linq;
using Microsoft.AspNetCore.Authentication;

namespace ChatMvc.Controllers
{
    [Authorize]
    public class ChatController : Controller
    {
        private readonly IHttpClientFactory _httpClientFactory;
        private readonly IConfiguration _configuration;
        private readonly IAntiforgery _antiforgery;

        public ChatController(IHttpClientFactory httpClientFactory, IConfiguration configuration, IAntiforgery antiforgery)
        {
            _httpClientFactory = httpClientFactory;
            _configuration = configuration;
            _antiforgery = antiforgery;
        }

        public IActionResult Index()
        {
            var tokens = _antiforgery.GetAndStoreTokens(HttpContext);
            var token = HttpContext.GetTokenAsync("access_token").Result;
            ViewBag.Token = token;
            return View();
        }

        [HttpGet("chat/proxy-response")]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> ProxyResponse(string sessionId, string message)
        {
            try
            {
                if (!Request.Headers["X-Requested-With"].Equals("XMLHttpRequest"))
                {
                    return BadRequest("Requisição inválida");
                }

                var userId = User.Claims.FirstOrDefault(f => f.Type == "UserId").Value;
                var name = User.Claims.FirstOrDefault(f => f.Type == "FirstName").Value;
                var company = User.Claims.FirstOrDefault(f => f.Type == "CompanyName").Value;
                var token = User.Claims.FirstOrDefault(f => f.Type == "TokenExternal").Value;

                var client = _httpClientFactory.CreateClient();
                var baseUrl = _configuration["ExternalApiBaseUrl"];

                client.DefaultRequestHeaders.Authorization =
                    new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));

                var response = await client.GetAsync(
                    $"{baseUrl}/chat/response?sessionId={sessionId}&message={message}");

                response.EnsureSuccessStatusCode();
                var content = await response.Content.ReadAsStringAsync();

                return Ok(content);
            }
            catch (Exception ex)
            {
                return BadRequest($"Erro ao processar mensagem: {ex.Message}");
            }
        }

        [HttpPost("chat/authenticate")]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Authenticate([FromBody] AuthenticateRequest request)
        {
            try
            {
                if (!Request.Headers["X-Requested-With"].Equals("XMLHttpRequest"))
                {
                    return BadRequest("Requisição inválida");
                }

                var client = _httpClientFactory.CreateClient();
                var baseUrl = _configuration["ExternalApiBaseUrl"];

                // Primeira requisição - newclient
                var newClientRequest = new
                {
                    localId = request.UserId,
                    companyTenant = request.Company,
                    name = request.Name
                };

                var newClientResponse = await client.PostAsync(
                    $"{baseUrl}/login/newclient",
                    new StringContent(JsonConvert.SerializeObject(newClientRequest),
                        Encoding.UTF8, "application/json"));

                newClientResponse.EnsureSuccessStatusCode();
                var clientContent = await newClientResponse.Content.ReadAsStringAsync();
                var clientResult = JsonConvert.DeserializeObject<NewClientResponse>(clientContent);

                // Segunda requisição - token
                var tokenRequest = new
                {
                    clientId = request.UserId,
                    clientName = request.Name,
                    clientSecret = clientResult.Secret
                };

                var tokenResponse = await client.PostAsync(
                    $"{baseUrl}/login/token",
                    new StringContent(JsonConvert.SerializeObject(tokenRequest),
                        Encoding.UTF8, "application/json"));

                tokenResponse.EnsureSuccessStatusCode();
                var tokenContent = await tokenResponse.Content.ReadAsStringAsync();
                var tokenResult = JsonConvert.DeserializeObject<TokenResponse>(tokenContent);

                return Ok(new { token = tokenResult.Token });
            }
            catch (Exception ex)
            {
                return BadRequest($"Erro na autenticação: {ex.Message}");
            }
        }
    }

    public class AuthenticateRequest
    {
        public string UserId { get; set; }
        public string Company { get; set; }
        public string Name { get; set; }
    }

    public class NewClientResponse
    {
        public string Secret { get; set; }
    }

    public class TokenResponse
    {
        public string Token { get; set; }
    }
}
