// Elementos DOM
const container = document.getElementById('ai-chat-container');
const button = document.getElementById('ai-chat-button');
const expanded = document.getElementById('ai-chat-expanded');
const close = document.getElementById('ai-chat-close');
const retryBtn = document.getElementById('retry-button');
const textarea = document.querySelector('.ai-chat-textarea');
const sendBtn = document.getElementById('ai-chat-send-btn');
const pauseBtn = document.getElementById('ai-chat-pause-btn');
const chatBody = document.querySelector('.ai-chat-body');

// CSRF token de Laravel
const csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content');

// Variables de estado
let abortController = null;
let isChatOpen = false;
let isAwaitingResponse = false;
const maxHeight = 150;

// --- EVENTOS ---

button.addEventListener('click', () => {
  container.classList.add('expanded');
  button.style.display = 'flex';
  expanded.style.display = 'none';
  close.style.display = 'block';
  hideRetryButton();
  isChatOpen = true;
  container.addEventListener('transitionend', onExpandTransitionEnd);
});

function onExpandTransitionEnd(e) {
  if (e.propertyName === 'width' && container.classList.contains('expanded')) {
    button.style.display = 'flex';
    expanded.style.display = 'none';
    hideRetryButton();
    close.style.display = 'block';
    showLoader();

    pingOllama().then(success => {
      if (!isChatOpen) return;

      hideLoader();
      if (success) {
        button.style.display = 'none';
        expanded.style.display = 'flex';
        sendBtn.style.display = 'inline-flex';
        pauseBtn.style.display = 'none';
        showAllMicButtons();
      } else {
        showRetryButton();
        button.style.display = 'flex';
        expanded.style.display = 'none';
      }
    });

    container.removeEventListener('transitionend', onExpandTransitionEnd);
  }
}

close.addEventListener('click', () => {
  if (abortController) {
    abortController.abort();
    abortController = null;
  }

  isChatOpen = false;
  isAwaitingResponse = false;
  expanded.style.display = 'none';
  button.style.display = 'flex';
  container.classList.remove('expanded');
  hideRetryButton();
  hideLoader();
  close.style.display = 'none';
});

textarea.addEventListener('input', () => {
  textarea.style.height = 'auto';
  if (textarea.scrollHeight > maxHeight) {
    textarea.style.height = maxHeight + 'px';
    textarea.style.overflowY = 'auto';
  } else {
    textarea.style.height = textarea.scrollHeight + 'px';
    textarea.style.overflowY = 'hidden';
  }
});

textarea.addEventListener('keydown', (e) => {
  if (e.key === 'Enter' && !e.shiftKey) {
    e.preventDefault();
    sendMessage();
  }
});

sendBtn.addEventListener('click', () => {
  sendMessage();
});

pauseBtn.addEventListener('click', () => {
  if (abortController) {
    abortController.abort();
    abortController = null;
    isAwaitingResponse = false;

    const loadingMsg = chatBody.querySelector('.ai-chat-message-loading');
    if (loadingMsg) {
      loadingMsg.classList.remove('ai-chat-message-loading');
      loadingMsg.classList.add('ai-chat-message-assistant');
      loadingMsg.innerHTML = `<p>⛔ Respuesta cancelada.</p>`;
    }

    pauseBtn.style.display = 'none';
    sendBtn.style.display = 'inline-flex';
    showAllMicButtons();
  }
});

// Función para enviar mensaje
function sendMessage() {
  if (isAwaitingResponse) return;

  const message = textarea.value.trim();
  if (!message) return;

  isAwaitingResponse = true;

  addUserMessageToChat(message);
  textarea.value = '';
  textarea.style.height = 'auto';

  sendBtn.style.display = 'none';
  pauseBtn.style.display = 'inline-flex';

  const aiLoaderDiv = document.createElement('div');
  aiLoaderDiv.classList.add('ai-chat-message', 'ai-chat-message-assistant', 'ai-chat-message-loading');

  const thinkingText = document.createElement('span');
  thinkingText.textContent = 'Thinking';

  const dotsSpan = document.createElement('span');
  dotsSpan.textContent = '';
  dotsSpan.classList.add('thinking-dots');

  aiLoaderDiv.appendChild(thinkingText);
  aiLoaderDiv.appendChild(dotsSpan);
  chatBody.appendChild(aiLoaderDiv);
  chatBody.scrollTop = chatBody.scrollHeight;

  let dotCount = 0;
  const thinkingInterval = setInterval(() => {
    dotCount = (dotCount + 1) % 4;
    dotsSpan.textContent = '.'.repeat(dotCount);
  }, 500);

  const course = container.dataset.course;
  const chapter = container.dataset.chapter;
  const url = `/api/ai/ask/${course}/${chapter}`;

  if (abortController) abortController.abort();
  abortController = new AbortController();

  fetch(url, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-CSRF-TOKEN': csrfToken
    },
    signal: abortController.signal,
    body: JSON.stringify({ question: message })
  })
    .then(res => {
      if (!res.ok) throw new Error('Error de red');
      return res.json();
    })
    .then(data => {
      clearInterval(thinkingInterval);
      isAwaitingResponse = false;

      if (!data || !data.answer) throw new Error('Respuesta vacía');

      aiLoaderDiv.classList.remove('ai-chat-message-loading');
      aiLoaderDiv.innerHTML = `
        <p>${escapeHTML(data.answer)}</p>
        <button class="ai-speaker-button" aria-label="Listen to the response" title="Listen to the response">
          <i class="bi bi-ear"></i>
        </button>
      `;

      pauseBtn.style.display = 'none';
      sendBtn.style.display = 'inline-flex';
    })
    .catch(err => {
      clearInterval(thinkingInterval);
      isAwaitingResponse = false;

      if (err.name === 'AbortError') return;

      aiLoaderDiv.classList.remove('ai-chat-message-loading');
      aiLoaderDiv.classList.add('ai-chat-message-assistant');
      aiLoaderDiv.innerHTML = `<p>⚠️ Error: ${err.message}</p>`;

      pauseBtn.style.display = 'none';
      sendBtn.style.display = 'inline-flex';
    });
}

function addUserMessageToChat(message) {
  const messageDiv = document.createElement('div');
  messageDiv.classList.add('ai-chat-message', 'ai-chat-message-user');
  messageDiv.innerText = message;

  chatBody.appendChild(messageDiv);
  chatBody.scrollTop = chatBody.scrollHeight;
}

// --- FUNCIONES UTILES ---

function showLoader() {
  let loaderCircle = button.querySelector('.loader-circle');
  if (!loaderCircle) {
    loaderCircle = document.createElement('div');
    loaderCircle.classList.add('loader-circle');
    const wrapper = button.querySelector('.loader-wrapper');
    if (wrapper) {
      wrapper.appendChild(loaderCircle);
    } else {
      button.appendChild(loaderCircle);
    }
  }
  loaderCircle.style.display = 'block';
}

function hideLoader() {
  const loaderCircle = button.querySelector('.loader-circle');
  if (loaderCircle) {
    loaderCircle.style.display = 'none';
  }
}

function pingOllama() {
  if (abortController) abortController.abort();
  abortController = new AbortController();

  return new Promise((resolve) => {
    const start = Date.now();

    fetch('/api/ai/ping', {
      headers: { 'Accept': 'application/json' }
    })
      .then(res => res.json())
      .then(data => {
        const elapsed = Date.now() - start;
        const minDelay = 2000;
        setTimeout(() => {
          resolve(data.status === 'success');
        }, Math.max(0, minDelay - elapsed));
      })
      .catch((err) => {
        if (err.name === 'AbortError') {
          resolve(false);
        } else {
          setTimeout(() => resolve(false), 2000);
        }
      });
  });
}

function showRetryButton() {
  if (!retryBtn) return;
  retryBtn.style.display = 'block';

  retryBtn.onclick = () => {
    retryBtn.style.display = 'none';
    showLoader();

    pingOllama().then(success => {
      if (!isChatOpen) return;

      hideLoader();
      if (success) {
        button.style.display = 'none';
        expanded.style.display = 'flex';
      } else {
        showRetryButton();
      }
    });
  };
}

function hideRetryButton() {
  if (retryBtn) {
    retryBtn.style.display = 'none';
  }
}

function hideAllMicButtons() {
  document.querySelectorAll('.ai-speaker-button').forEach(btn => {
    btn.style.display = 'none';
  });
}

function showAllMicButtons() {
  document.querySelectorAll('.ai-speaker-button').forEach(btn => {
    btn.style.display = 'inline-flex';
  });
}

function escapeHTML(str) {
  return str
    .replace(/&/g, "&amp;")
    .replace(/</g, "&lt;")
    .replace(/>/g, "&gt;")
    .replace(/"/g, "&quot;")
    .replace(/'/g, "&#039;");
}

let currentAudio = null;
let isSpeaking = false;
let activeSpeakerButton = null;

chatBody.addEventListener('click', async (e) => {
  const btn = e.target.closest('.ai-speaker-button');
  if (!btn) return;

  if (isSpeaking) {
    stopAudio();
    return;
  }

  const parent = btn.closest('.ai-chat-message-assistant');
  if (!parent) return;

  const text = parent.querySelector('p')?.innerText;
  if (!text) return;

  activeSpeakerButton = btn;
  speakViaLaravel(text, btn);
});

async function speakViaLaravel(text, button) {
  button.innerHTML = `<span class="loader-button-small"></span>`;
  isSpeaking = true;

  try {
    const response = await fetch('/api/text-to-speech', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'X-CSRF-TOKEN': csrfToken
      },
      body: JSON.stringify({ text: text })
    });

    if (!response.ok) throw new Error('TTS failed');

    const audioBlob = await response.blob();
    const audioURL = URL.createObjectURL(audioBlob);
    const audio = new Audio(audioURL);
    currentAudio = audio;

    button.innerHTML = `<i class="bi bi-stop-fill"></i>`;

    audio.play();

    audio.onended = () => {
      resetSpeakerButton();
    };

    audio.onerror = () => {
      resetSpeakerButton();
      console.error('Error reproduciendo el audio');
    };
  } catch (error) {
    console.error(error);
    resetSpeakerButton();
  }
}

function stopAudio() {
  if (currentAudio) {
    currentAudio.pause();
    currentAudio.currentTime = 0;
    currentAudio = null;
  }
  resetSpeakerButton();
}

function resetSpeakerButton() {
  if (activeSpeakerButton) {
    activeSpeakerButton.innerHTML = `<i class="bi bi-ear"></i>`;
    activeSpeakerButton = null;
  }
  isSpeaking = false;
}

const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;

if (SpeechRecognition) {
  const recognition = new SpeechRecognition();
  recognition.lang = 'es-ES';
  recognition.continuous = true;
  recognition.interimResults = true;

  const voiceBtn = document.getElementById('ai-voice-btn');
  const inputField = document.getElementById('ai-chat-input');
  let listening = false;

  voiceBtn.addEventListener('click', () => {
    if (!listening) {
      recognition.start();
      voiceBtn.innerHTML = '<i class="bi bi-stop-fill"></i>';
      listening = true;
    } else {
      recognition.stop();
      voiceBtn.innerHTML = '<i class="bi bi-mic-fill"></i>';
      listening = false;
    }
  });

  recognition.onresult = (event) => {
    let finalTranscript = '';
    for (let i = event.resultIndex; i < event.results.length; ++i) {
      const transcript = event.results[i][0].transcript;
      finalTranscript += transcript;
    }
    inputField.value = finalTranscript;
  };

  recognition.onerror = (event) => {
    console.error('Speech recognition error:', event.error);
    voiceBtn.innerHTML = '<i class="bi bi-mic-fill"></i>';
    listening = false;
  };

  recognition.onend = () => {
    voiceBtn.innerHTML = '<i class="bi bi-mic-fill"></i>';
    listening = false;
  };
} else {
  console.warn('Speech recognition not supported in this browser.');
  const btn = document.getElementById('ai-voice-btn');
  if (btn) btn.disabled = true;
}
