package controllers

import (
	"crypto/rand"
	"encoding/hex"
	"strings"

	"github.com/gofiber/fiber/v2"
	"github.com/sujit-baniya/fiber-boilerplate/pkg/models"
	"github.com/sujit-baniya/fiber-boilerplate/pkg/services"
)

func agenteDeContexto(c *fiber.Ctx) (*models.UmindAgente, error) {
	agente, ok := c.Locals("umind_agente").(*models.UmindAgente)
	if !ok || agente == nil {
		return nil, fiber.NewError(fiber.StatusUnauthorized, "no autenticado")
	}
	return agente, nil
}

func tenantDeContexto(c *fiber.Ctx) (*models.UmindTenant, error) {
	tenant, ok := c.Locals("umind_tenant").(*models.UmindTenant)
	if !ok || tenant == nil {
		return nil, fiber.NewError(fiber.StatusUnauthorized, "no autenticado")
	}
	return tenant, nil
}

func nuevaSessionID() string {
	b := make([]byte, 12)
	_, _ = rand.Read(b)
	return hex.EncodeToString(b)
}

// UmindWidgetInit devuelve una sesión nueva y el mensaje de bienvenida del
// agente, sin gastar una llamada al LLM solo para saludar. El nombre que se
// muestra es el del negocio (tenant dueño del agente), no la etiqueta
// interna del agente.
// Ruta: GET /widget/:site_key/init
func UmindWidgetInit(c *fiber.Ctx) error {
	agente, err := agenteDeContexto(c)
	if err != nil {
		return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": true, "message": err.Error()})
	}
	tenant, err := tenantDeContexto(c)
	if err != nil {
		return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": true, "message": err.Error()})
	}
	bienvenida := strings.TrimSpace(agente.MensajeBienvenida)
	if bienvenida == "" {
		bienvenida = "¡Hola! ¿En qué puedo ayudarte?"
	}
	color := strings.TrimSpace(agente.Color)
	if color == "" {
		color = "#8eb02f"
	}
	return c.JSON(fiber.Map{
		"session_id":         nuevaSessionID(),
		"nombre":             tenant.Nombre,
		"mensaje_bienvenida": bienvenida,
		"color":              color,
	})
}

// UmindWidgetMensaje procesa un mensaje del visitante y devuelve la respuesta del agente.
// Ruta: POST /widget/:site_key/mensaje
func UmindWidgetMensaje(c *fiber.Ctx) error {
	agente, err := agenteDeContexto(c)
	if err != nil {
		return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": true, "message": err.Error()})
	}

	var req struct {
		SessionID string `json:"session_id"`
		Mensaje   string `json:"mensaje"`
	}
	if err := c.BodyParser(&req); err != nil {
		return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": true, "message": "body inválido"})
	}
	if strings.TrimSpace(req.Mensaje) == "" {
		return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": true, "message": "mensaje requerido"})
	}
	sessionID := strings.TrimSpace(req.SessionID)
	if sessionID == "" {
		sessionID = nuevaSessionID()
	}
	// Límite generoso pero real: evita que alguien mande un mensaje gigante al LLM.
	if len(req.Mensaje) > 4000 {
		req.Mensaje = req.Mensaje[:4000]
	}

	respuesta, err := services.ProcessWidgetMessage(agente, sessionID, strings.TrimSpace(req.Mensaje))
	if err != nil {
		return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": true, "message": err.Error()})
	}

	return c.JSON(fiber.Map{
		"session_id": sessionID,
		"respuesta":  respuesta,
	})
}

// UmindWidgetScript sirve el script embebible que renderiza la burbuja de
// chat. Se instala con: <script src="https://admin.u-site.app/widget/umind.js" data-site="SITE_KEY" defer></script>
// Ruta: GET /widget/umind.js
func UmindWidgetScript(c *fiber.Ctx) error {
	c.Set("Content-Type", "application/javascript; charset=utf-8")
	c.Set("Cache-Control", "public, max-age=300")
	return c.SendString(umindWidgetJS)
}

const umindWidgetJS = `(function () {
  var script = document.currentScript;
  var siteKey = script.getAttribute('data-site');
  if (!siteKey) { console.error('[uMind] falta data-site en el <script>'); return; }
  var apiBase = script.src.replace(/\/widget\/umind\.js.*$/, '') + '/widget/' + siteKey;
  var storageKey = 'umind_session_' + siteKey;
  var color = '#8eb02f';

  var style = document.createElement('style');
  style.textContent = [
    '.umind-ring{position:fixed;bottom:20px;right:20px;width:60px;height:60px;border-radius:50%;z-index:999998;pointer-events:none;animation:umind-pulse 2.4s ease-out 3;}',
    '@keyframes umind-pulse{0%{box-shadow:0 0 0 0 var(--umind-color,#8eb02f);}100%{box-shadow:0 0 0 24px transparent;}}',
    '.umind-bubble{position:fixed;bottom:20px;right:20px;width:60px;height:60px;border-radius:50%;display:flex;align-items:center;justify-content:center;cursor:pointer;box-shadow:0 6px 20px rgba(0,0,0,.22);z-index:999999;border:none;transition:transform .15s ease;padding:0;}',
    '.umind-bubble:hover{transform:scale(1.06);}',
    '.umind-bubble svg{width:26px;height:26px;display:block;}',
    '.umind-panel{position:fixed;bottom:92px;right:20px;width:356px;max-width:92vw;height:480px;max-height:72vh;background:#fff;border-radius:16px;box-shadow:0 16px 40px rgba(0,0,0,.22);z-index:999999;display:flex;flex-direction:column;overflow:hidden;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;opacity:0;transform:translateY(14px) scale(.97);pointer-events:none;transition:opacity .18s ease,transform .18s ease;}',
    '.umind-panel.umind-abierto{opacity:1;transform:translateY(0) scale(1);pointer-events:auto;}',
    '.umind-header{padding:16px 40px 16px 16px;color:#fff;position:relative;flex-shrink:0;}',
    '.umind-header b{display:block;font-size:14.5px;font-weight:600;}',
    '.umind-header span{display:block;font-size:11px;opacity:.85;margin-top:2px;}',
    '.umind-close{position:absolute;top:12px;right:12px;background:rgba(255,255,255,.22);border:none;color:#fff;width:24px;height:24px;border-radius:50%;cursor:pointer;font-size:15px;line-height:1;}',
    '.umind-msgs{flex:1;overflow-y:auto;padding:14px;font-size:13px;line-height:1.45;background:#fafafa;}',
    '.umind-msg{margin-bottom:10px;padding:9px 12px;border-radius:13px;max-width:82%;white-space:pre-wrap;}',
    '.umind-msg-bot{background:#fff;color:#222;border:1px solid #ececec;border-bottom-left-radius:4px;}',
    '.umind-msg-user{color:#fff;margin-left:auto;border-bottom-right-radius:4px;}',
    '.umind-inputbar{display:flex;align-items:center;border-top:1px solid #eee;padding:8px;gap:6px;background:#fff;flex-shrink:0;}',
    '.umind-inputbar input{flex:1;border:1px solid #e5e5e5;border-radius:20px;padding:9px 14px;font-size:13px;outline:none;}',
    '.umind-inputbar button{border:none;color:#fff;width:34px;height:34px;border-radius:50%;cursor:pointer;display:flex;align-items:center;justify-content:center;flex-shrink:0;}',
    '.umind-inputbar button svg{width:16px;height:16px;}',
    '.umind-badge{text-align:center;font-size:10.5px;color:#aaa;padding:5px 0 9px;background:#fff;letter-spacing:.02em;flex-shrink:0;}',
  ].join('');
  document.head.appendChild(style);

  var sparkSVG = '<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">' +
    '<path d="M12 2.5c.6 3.6 2.4 5.4 6 6-3.6.6-5.4 2.4-6 6-.6-3.6-2.4-5.4-6-6 3.6-.6 5.4-2.4 6-6z" fill="#fff"/>' +
    '<path d="M19 15c.3 1.8 1.1 2.7 2.9 3-1.8.3-2.6 1.2-2.9 3-.3-1.8-1.1-2.7-2.9-3 1.8-.3 2.6-1.2 2.9-3z" fill="#fff" opacity=".85"/>' +
  '</svg>';
  var sendSVG = '<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M12 19V5M12 5l-6 6M12 5l6 6" stroke="#fff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>';

  var ring = document.createElement('div');
  ring.className = 'umind-ring';
  document.body.appendChild(ring);

  var bubble = document.createElement('button');
  bubble.className = 'umind-bubble';
  bubble.setAttribute('aria-label', 'Abrir chat');
  bubble.innerHTML = sparkSVG;
  document.body.appendChild(bubble);

  var panel = document.createElement('div');
  panel.className = 'umind-panel';
  panel.innerHTML =
    '<div class="umind-header" id="umind-header">' +
      '<b id="umind-title">Asistente</b><span>Asistente con IA &middot; uMind</span>' +
      '<button class="umind-close" id="umind-close" aria-label="Cerrar">&times;</button>' +
    '</div>' +
    '<div class="umind-msgs" id="umind-msgs"></div>' +
    '<div class="umind-inputbar">' +
      '<input id="umind-input" type="text" placeholder="Escribe tu mensaje..." />' +
      '<button id="umind-send" aria-label="Enviar"></button>' +
    '</div>' +
    '<div class="umind-badge">&#10022; Impulsado por uMind</div>';
  document.body.appendChild(panel);
  panel.querySelector('#umind-send').innerHTML = sendSVG;

  function aplicarColor(c) {
    if (!c) return;
    color = c;
    ring.style.setProperty('--umind-color', color);
    bubble.style.background = 'radial-gradient(circle at 30% 28%, rgba(255,255,255,.35), transparent 55%), ' + color;
    panel.querySelector('#umind-header').style.background = color;
    panel.querySelector('#umind-send').style.background = color;
  }
  aplicarColor(color);

  var msgsEl = panel.querySelector('#umind-msgs');
  var inputEl = panel.querySelector('#umind-input');
  var sendEl = panel.querySelector('#umind-send');
  var sessionId = null;
  var abierto = false;

  function agregarMensaje(texto, quien) {
    var burbuja = document.createElement('div');
    burbuja.textContent = texto;
    var esUser = quien === 'user';
    burbuja.className = 'umind-msg ' + (esUser ? 'umind-msg-user' : 'umind-msg-bot');
    if (esUser) burbuja.style.background = color;
    msgsEl.appendChild(burbuja);
    msgsEl.scrollTop = msgsEl.scrollHeight;
  }

  function iniciar() {
    sessionId = sessionStorage.getItem(storageKey) || null;
    fetch(apiBase + '/init')
      .then(function (r) { return r.json(); })
      .then(function (data) {
        if (!sessionId) { sessionId = data.session_id; sessionStorage.setItem(storageKey, sessionId); }
        if (data.nombre) panel.querySelector('#umind-title').textContent = data.nombre;
        aplicarColor(data.color);
        agregarMensaje(data.mensaje_bienvenida, 'bot');
      })
      .catch(function () { agregarMensaje('No se pudo conectar el asistente.', 'bot'); });
  }
  iniciar(); // arranca ya, así el color/nombre reales están listos antes del primer click

  function enviar() {
    var texto = inputEl.value.trim();
    if (!texto) return;
    inputEl.value = '';
    agregarMensaje(texto, 'user');
    fetch(apiBase + '/mensaje', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ session_id: sessionId, mensaje: texto })
    })
      .then(function (r) { return r.json(); })
      .then(function (data) {
        if (data.session_id) { sessionId = data.session_id; sessionStorage.setItem(storageKey, sessionId); }
        agregarMensaje(data.respuesta || data.message || 'No pude responder eso.', 'bot');
      })
      .catch(function () { agregarMensaje('Error de conexión, intenta de nuevo.', 'bot'); });
  }

  function alternar() {
    abierto = !abierto;
    panel.classList.toggle('umind-abierto', abierto);
    if (abierto) inputEl.focus();
  }

  bubble.addEventListener('click', alternar);
  panel.querySelector('#umind-close').addEventListener('click', alternar);
  sendEl.addEventListener('click', enviar);
  inputEl.addEventListener('keydown', function (e) { if (e.key === 'Enter') enviar(); });
})();
`
