/**
 * 光湖·内测 · 前端逻辑
 * 登录 + 聊天SSE流 + 自动翻转 + 工具调用
 * 无框架 · 纯 Vanilla JS
 */
(function(){
  'use strict';

  // ─── 配置 ───
  const API_BASE = '/hli/ftchat';
  const LS_PREFIX = 'ftchat_';
  const SESSION_THRESHOLD = 50;  // 超过N条自动翻转

  // ─── 状态 ───
  let state = {
    token: null,
    email: null,
    userHash: null,
    slotIndex: null,
    messages: [],
    currentStream: null,  // AbortController
    isSending: false,
    isLoggedIn: false,
    hasCodeSent: false,
    currentEmail: ''
  };

  // ─── DOM 引用 ───
  const $ = (id) => document.getElementById(id);
  const loginScreen = $('loginScreen');
  const chatScreen = $('chatScreen');
  const loginForm = $('loginForm');
  const emailInput = $('emailInput');
  const codeInput = $('codeInput');
  const codeGroup = $('codeGroup');
  const loginBtn = $('loginBtn');
  const loginStatus = $('loginStatus');
  const slotInfo = $('slotInfo');
  const chatMessages = $('chatMessages');
  const chatInput = $('chatInput');
  const sendBtn = $('sendBtn');
  const userEmail = $('userEmail');

  // ─── 星场背景 ───
  function initStarfield() {
    const canvas = document.getElementById('starfield');
    if (!canvas) return;
    const ctx = canvas.getContext('2d');
    let stars = [];
    let W, H;

    function resize() {
      W = canvas.width = window.innerWidth;
      H = canvas.height = window.innerHeight;
    }

    function createStars() {
      stars = [];
      const count = Math.min(Math.floor(W * H / 8000), 120);
      for (let i = 0; i < count; i++) {
        stars.push({
          x: Math.random() * W,
          y: Math.random() * H,
          r: Math.random() * 1.5 + 0.5,
          a: Math.random() * 0.8 + 0.2,
          speed: Math.random() * 0.005 + 0.002
        });
      }
    }

    function draw() {
      ctx.clearRect(0, 0, W, H);
      const t = Date.now();
      for (const s of stars) {
        const twinkle = Math.sin(t * s.speed) * 0.3 + 0.7;
        ctx.beginPath();
        ctx.arc(s.x, s.y, s.r, 0, Math.PI * 2);
        ctx.fillStyle = 'rgba(200, 200, 255, ' + (s.a * twinkle) + ')';
        ctx.fill();
      }
      requestAnimationFrame(draw);
    }

    window.addEventListener('resize', () => { resize(); createStars(); });
    resize();
    createStars();
    draw();
  }

  // ─── 登录逻辑 ───
  function showStatus(msg, type) {
    loginStatus.style.display = 'block';
    loginStatus.className = 'login-status ' + type;
    loginStatus.textContent = msg;
  }

  function updateSlotInfo() {
    fetch(API_BASE + '/status')
      .then(r => r.json())
      .then(d => {
        if (d.slots_remaining !== undefined) {
          slotInfo.textContent = '剩余内测席位: ' + d.slots_remaining + ' / ' + d.slots_total;
        }
      })
      .catch(() => {});
  }

  window.handleLogin = function() {
    const email = emailInput.value.trim();
    if (!email) { showStatus('请输入QQ邮箱', 'error'); return; }

    if (!state.hasCodeSent) {
      // 发送验证码
      loginBtn.disabled = true;
      loginBtn.textContent = '发送中...';
      state.currentEmail = email;

      fetch(API_BASE + '/login', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ email: email })
      })
      .then(r => r.json())
      .then(d => {
        loginBtn.disabled = false;
        if (d.success) {
          state.hasCodeSent = true;
          codeGroup.style.display = 'block';
          codeInput.focus();
          loginBtn.textContent = '登录';
          showStatus('验证码已发送（开发模式: 请查看服务器日志）', 'info');
          emailInput.readOnly = true;
        } else {
          loginBtn.textContent = '发送验证码';
          showStatus(d.message || '发送失败', 'error');
        }
      })
      .catch(err => {
        loginBtn.disabled = false;
        loginBtn.textContent = '发送验证码';
        showStatus('网络错误: ' + err.message, 'error');
      });
    } else {
      // 验证码
      const code = codeInput.value.trim();
      if (!code || code.length !== 6) { showStatus('请输入6位验证码', 'error'); return; }

      loginBtn.disabled = true;
      loginBtn.textContent = '验证中...';

      fetch(API_BASE + '/verify', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ email: state.currentEmail, code: code })
      })
      .then(r => r.json())
      .then(d => {
        loginBtn.disabled = false;
        if (d.success) {
          onLoginSuccess(d);
        } else {
          loginBtn.textContent = '登录';
          showStatus(d.message || '验证失败', 'error');
          codeInput.value = '';
          codeInput.focus();
        }
      })
      .catch(err => {
        loginBtn.disabled = false;
        loginBtn.textContent = '登录';
        showStatus('网络错误: ' + err.message, 'error');
      });
    }
  };

  function onLoginSuccess(data) {
    state.token = data.token;
    state.userHash = data.user_hash;
    state.email = state.currentEmail || data.email;
    state.slotIndex = data.slot_index;
    state.isLoggedIn = true;

    localStorage.setItem(LS_PREFIX + 'token', data.token);
    localStorage.setItem(LS_PREFIX + 'email', state.email);
    localStorage.setItem(LS_PREFIX + 'hash', data.user_hash);

    userEmail.textContent = state.email;
    loginScreen.classList.remove('active');
    chatScreen.classList.add('active');

    loadConversation();
    chatInput.focus();
  }

  function logout() {
    state.token = null;
    state.isLoggedIn = false;
    state.hasCodeSent = false;
    state.messages = [];
    state.currentEmail = '';
    state.email = null;

    localStorage.removeItem(LS_PREFIX + 'token');
    localStorage.removeItem(LS_PREFIX + 'email');
    localStorage.removeItem(LS_PREFIX + 'hash');

    emailInput.value = '';
    emailInput.readOnly = false;
    codeInput.value = '';
    codeGroup.style.display = 'none';
    loginBtn.textContent = '发送验证码';
    loginBtn.disabled = false;
    loginStatus.style.display = 'none';

    chatScreen.classList.remove('active');
    loginScreen.classList.add('active');
  }
  window.logout = logout;

  function restoreSession() {
    const token = localStorage.getItem(LS_PREFIX + 'token');
    const email = localStorage.getItem(LS_PREFIX + 'email');
    const hash = localStorage.getItem(LS_PREFIX + 'hash');
    if (token && email && hash) {
      state.token = token;
      state.email = email;
      state.userHash = hash;
      state.isLoggedIn = true;

      userEmail.textContent = email;
      loginScreen.classList.remove('active');
      chatScreen.classList.add('active');
      loadConversation();
      chatInput.focus();
      return true;
    }
    return false;
  }

  // ─── 聊天逻辑 ───
  function getStorageKey() {
    return LS_PREFIX + state.userHash + '_messages';
  }

  function loadConversation() {
    try {
      const saved = localStorage.getItem(getStorageKey());
      if (saved) {
        state.messages = JSON.parse(saved);
        renderMessages();
      } else {
        state.messages = [];
        chatMessages.innerHTML = '<div class="message system-note"><div class="message-content">开始新对话 · 母模型已就绪</div></div>';
      }
    } catch (e) {
      state.messages = [];
    }
  }

  function saveConversation() {
    try {
      localStorage.setItem(getStorageKey(), JSON.stringify(state.messages));
    } catch (e) {
      // Storage full - trim history
      if (e.name === 'QuotaExceededError') {
        state.messages = state.messages.slice(-100);
        try { localStorage.setItem(getStorageKey(), JSON.stringify(state.messages)); } catch {}
      }
    }
  }

  function addMessage(role, content) {
    state.messages.push({ role: role, content: content });
    saveConversation();
  }

  function renderMessages(scrollToBottom) {
    chatMessages.innerHTML = '';
    for (const msg of state.messages) {
      appendMessageElement(msg.role, msg.content, false);
    }
    if (scrollToBottom !== false) {
      chatMessages.scrollTop = chatMessages.scrollHeight;
    }
  }

  function appendMessageElement(role, content, isNew) {
    const div = document.createElement('div');
    div.className = 'message ' + role;
    const contentDiv = document.createElement('div');
    contentDiv.className = 'message-content';
    contentDiv.textContent = content;
    div.appendChild(contentDiv);
    chatMessages.appendChild(div);
    if (isNew) chatMessages.scrollTop = chatMessages.scrollHeight;
  }

  function appendStreamingMessage(role) {
    const div = document.createElement('div');
    div.className = 'message ' + role;
    const contentDiv = document.createElement('div');
    contentDiv.className = 'message-content cursor-blink';
    contentDiv.textContent = '';
    div.appendChild(contentDiv);
    chatMessages.appendChild(div);
    chatMessages.scrollTop = chatMessages.scrollHeight;
    return contentDiv;
  }

  // ─── 发送消息 ───
  window.sendMessage = function() {
    if (state.isSending) return;
    const text = chatInput.value.trim();
    if (!text) return;

    chatInput.value = '';
    chatInput.style.height = 'auto';

    // Check auto-rotate
    if (state.messages.length >= SESSION_THRESHOLD) {
      rotateConversation();
    }

    // Add user message
    addMessage('user', text);
    appendMessageElement('user', text, true);

    // Send
    state.isSending = true;
    sendBtn.disabled = true;

    const controller = new AbortController();
    state.currentStream = controller;

    // Show typing indicator
    const typingDiv = document.createElement('div');
    typingDiv.className = 'message assistant';
    typingDiv.innerHTML = '<div class="typing-indicator"><span></span><span></span><span></span></div>';
    chatMessages.appendChild(typingDiv);
    chatMessages.scrollTop = chatMessages.scrollHeight;

    // Format messages for API - NO system prompt
    const apiMessages = state.messages.map(m => ({ role: m.role, content: m.content }));

    fetch(API_BASE + '/chat', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': 'Bearer ' + state.token
      },
      body: JSON.stringify({
        messages: apiMessages,
        max_tokens: 1024,
        temperature: 0.7
      }),
      signal: controller.signal
    })
    .then(response => {
      // Remove typing indicator
      typingDiv.remove();

      const contentDiv = appendStreamingMessage('assistant');
      let fullContent = '';
      const reader = response.body.getReader();
      const decoder = new TextDecoder();
      let buffer = '';

      function readStream() {
        reader.read().then(({ done, value }) => {
          if (done) {
            contentDiv.classList.remove('cursor-blink');
            state.isSending = false;
            sendBtn.disabled = false;
            state.currentStream = null;

            if (fullContent) {
              addMessage('assistant', fullContent);
            }
            return;
          }

          buffer += decoder.decode(value, { stream: true });
          const lines = buffer.split('\n');
          buffer = lines.pop() || '';

          for (const line of lines) {
            const trimmed = line.trim();
            if (!trimmed) continue;
            try {
              const parsed = JSON.parse(trimmed);
              if (parsed.delta) {
                fullContent += parsed.delta;
                contentDiv.textContent = fullContent;
                chatMessages.scrollTop = chatMessages.scrollHeight;
              }
              if (parsed.error) {
                fullContent += '\n[错误: ' + parsed.error + ']';
                contentDiv.textContent = fullContent;
              }
            } catch (e) {
              // Non-JSON line (e.g. [DONE])
              if (trimmed === 'data: [DONE]') {
                // Stream complete
              }
            }
          }

          readStream();
        }).catch(err => {
          if (err.name !== 'AbortError') {
            contentDiv.textContent = '请求中断: ' + err.message;
          }
          contentDiv.classList.remove('cursor-blink');
          state.isSending = false;
          sendBtn.disabled = false;
          state.currentStream = null;
        });
      }

      readStream();
    })
    .catch(err => {
      typingDiv.remove();
      state.isSending = false;
      sendBtn.disabled = false;
      state.currentStream = null;
      if (err.name !== 'AbortError') {
        const errorDiv = appendStreamingMessage('assistant');
        errorDiv.textContent = '连接失败: ' + err.message;
        errorDiv.classList.remove('cursor-blink');
      }
    });
  };

  function rotateConversation() {
    // Save current and start new
    state.messages = [];
    saveConversation();
    renderMessages();
    addMessage('system', '[对话已自动翻转，继续当前上下文]');
    appendMessageElement('system-note', '—— 对话已自动翻转，继续当前上下文 ——', true);
  }

  window.newConversation = function() {
    if (state.messages.length > 0) {
      state.messages = [];
      saveConversation();
      renderMessages();
      chatMessages.innerHTML = '<div class="message system-note"><div class="message-content">新对话 · 母模型已就绪</div></div>';
    }
  };

  window.handleInputKeydown = function(e) {
    if (e.key === 'Enter' && !e.shiftKey) {
      e.preventDefault();
      sendMessage();
    }
  };

  // Auto-resize textarea
  chatInput.addEventListener('input', function() {
    this.style.height = 'auto';
    this.style.height = Math.min(this.scrollHeight, 120) + 'px';
  });

  // ─── 初始化 ───
  initStarfield();
  updateSlotInfo();

  if (!restoreSession()) {
    // Try to check if token in URL params
    const params = new URLSearchParams(window.location.search);
    const tokenParam = params.get('token');
    if (tokenParam) {
      localStorage.setItem(LS_PREFIX + 'token', tokenParam);
      // Force reload to pick up the token
      window.location.href = '/';
    }
  }

  // Periodically update slot info
  setInterval(updateSlotInfo, 30000);

  
  chatInput.addEventListener('keydown', function(e) {
    if (e.key === 'Escape' && document.activeElement === chatInput) {
      chatInput.blur();
    }
  });

})();
