/**
 * 充电桩大盘 - API 模块
 */

import { CONFIG } from './config.js';
import { state } from './state.js';
import { updateFreeCache } from './cache.js';
import { renderStation } from './render.js';
import { getPollModeText } from './polling.js';
import { initAnalytics } from './analytics.js';
import { showToast, refreshIcons } from './utils.js';
import { loadPreferences, savePreferences } from './preferences.js';

// 请求锁，防止重复点击
let refreshLock = false;

/**
 * 带超时的 fetch
 */
async function fetchWithTimeout(url, options = {}, timeout = 10000) {
  const controller = new AbortController();
  const timeoutId = setTimeout(() => controller.abort(), timeout);
  try {
    const res = await fetch(url, { ...options, signal: controller.signal });
    clearTimeout(timeoutId);
    return res;
  } catch (e) {
    clearTimeout(timeoutId);
    if (e.name === 'AbortError') {
      throw new Error('请求超时，请检查网络连接');
    }
    throw e;
  }
}

function buildStationSignature(station) {
  return JSON.stringify({
    fetch_timestamp: station?.fetch_timestamp,
    connectors: (station?.connectors || []).map(c => [
      c.connector_id,
      c.connector_name,
      c.state?.type,
      c.idle_seconds || 0,
      c.charging_seconds || 0,
      c.occupied_seconds || 0,
      c.estimated_charging_ready_time ?? null,
      c.charging_progress ?? null,
    ]),
  });
}

/**
 * 刷新数据
 */
export async function refreshData(silent = false) {
  // 防止重复点击
  if (refreshLock) return;
  refreshLock = true;

  const icon = document.getElementById('refresh-icon');
  if (!silent) {
    icon.classList.add('animate-spin');
  }

  try {
    const headers = {};
    if (state.stationEtag) {
      headers['If-None-Match'] = state.stationEtag;
    }
    const res = await fetchWithTimeout(`${CONFIG.API_BASE}/station/${CONFIG.STATION_ID}`, { headers });

    if (res.status === 304) {
      updateHeaderStatus(true, state.station?.fetch_time);
      return;
    }

    if (!res.ok) {
      throw new Error(`服务器错误 (${res.status})`);
    }

    const result = await res.json();
    if (result.success) {
      const nextEtag = res.headers.get('ETag');
      const nextSignature = buildStationSignature(result.data);
      const changed = nextSignature !== state.stationSignature;
      state.stationEtag = nextEtag || state.stationEtag;
      state.stationSignature = nextSignature;
      state.station = result.data;
      if (changed) {
        updateFreeCache(result.data.connectors);
        renderStation(result.data);
      }
      document.getElementById('error-state').classList.add('hidden');
      // 仅在监控 Tab 时显示 data-content
      if (window.currentTab !== 'analytics') {
        document.getElementById('data-content').classList.remove('hidden');
      }
      updateHeaderStatus(true, result.data.fetch_time);
      // 如果在数据分析 Tab，同时刷新分析数据
      if (window.currentTab === 'analytics') {
        initAnalytics(CONFIG.STATION_ID);
      }
      if (changed) {
        refreshIcons();
      }
    } else {
      throw new Error(result.message || '数据获取失败');
    }
  } catch (e) {
    console.error('刷新失败:', e);
    if (!silent) {
      // 显示具体错误信息
      const errorEl = document.getElementById('error-state');
      const msgEl = document.getElementById('error-message');
      if (msgEl) {
        msgEl.textContent = e.message || '网络波动，请刷新重试';
      }
      errorEl.classList.remove('hidden');
      document.getElementById('data-content').classList.add('hidden');
      updateHeaderStatus(false);
    } else {
      // 静默失败时显示过期提示
      if (state.station) {
        updateHeaderStatus('stale', state.station.fetch_time);
      }
    }
  } finally {
    refreshLock = false;
    icon.classList.remove('animate-spin');
  }
}

/**
 * 更新头部状态
 */
function updateHeaderStatus(online, time) {
  const statusEl = document.getElementById('header-status');
  const pollMode = getPollModeText();

  if (online === true) {
    statusEl.innerHTML = `
      <span class="relative flex h-2 w-2">
        <span class="animate-ping absolute inline-flex h-full w-full rounded-full opacity-75 bg-emerald-400"></span>
        <span class="relative inline-flex rounded-full h-2 w-2 bg-emerald-500"></span>
      </span>
      <span>数据更新于 ${time} · ${pollMode}</span>
    `;
  } else if (online === 'stale') {
    statusEl.innerHTML = `
      <span class="relative flex h-2 w-2">
        <span class="animate-ping absolute inline-flex h-full w-full rounded-full opacity-75 bg-yellow-400"></span>
        <span class="relative inline-flex rounded-full h-2 w-2 bg-yellow-500"></span>
      </span>
      <span>数据可能已过期 · 更新于 ${time}</span>
    `;
  } else {
    statusEl.innerHTML = `
      <span class="relative flex h-2 w-2">
        <span class="animate-ping absolute inline-flex h-full w-full rounded-full opacity-75 bg-red-500"></span>
        <span class="relative inline-flex rounded-full h-2 w-2 bg-red-500"></span>
      </span>
      <span>离线 · ${pollMode}</span>
    `;
  }
}

/**
 * 重试连接
 */
export function retryConnect(btn) {
  const icon = document.getElementById('retry-icon');
  icon.classList.add('animate-spin');
  btn.disabled = true;
  btn.classList.add('opacity-70');

  refreshData().finally(() => {
    setTimeout(() => {
      icon.classList.remove('animate-spin');
      btn.disabled = false;
      btn.classList.remove('opacity-70');
    }, 500);
  });
}

/**
 * 提交订阅
 */
export async function submitSubscribe(e) {
  e.preventDefault();
  const email = document.getElementById('email-input').value.trim();
  const feishuName = document.getElementById('feishu-name-input').value.trim();
  const chargerType = document.querySelector('input[name="charger-type"]:checked')?.value || 'all';
  const vendor = document.querySelector('input[name="vendor"]:checked')?.value || 'all';

  // 验证飞书花名
  if (!feishuName) {
    document.getElementById('feishu-name-error').classList.remove('hidden');
    return;
  }
  document.getElementById('feishu-name-error').classList.add('hidden');

  // 验证邮箱
  if (!email || !/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/.test(email)) {
    document.getElementById('email-error').classList.remove('hidden');
    return;
  }
  document.getElementById('email-error').classList.add('hidden');

  const btn = document.getElementById('subscribe-submit-btn');
  btn.disabled = true;
  btn.textContent = '订阅中...';

  try {
    const res = await fetch(`${CONFIG.API_BASE}/subscribe`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ email, feishu_name: feishuName, charger_type: chargerType, vendor })
    });

    // 尝试解析响应
    let result;
    try {
      result = await res.json();
    } catch (parseErr) {
      // JSON 解析失败
      if (!res.ok) {
        showToast(`服务暂时不可用 (${res.status})，请稍后重试`, 'error');
      } else {
        showToast('响应格式错误，请重试', 'error');
      }
      return;
    }

    // 检查响应状态
    if (!res.ok) {
      showToast(result?.message || `服务错误 (${res.status})`, 'error');
      return;
    }

    if (result.success) {
      savePreferences({
        email,
        feishuName,
        chargerType,
        vendor,
      });
      const chargerText = { 'all': '任意充电桩', 'AC': 'AC 慢充', 'DC': 'DC 快充' }[chargerType];
      const vendorText = { 'all': '全部品牌', 'nio': '蔚来', 'gongniu': '公牛' }[vendor];
      const queuePos = result.data?.queue_position || 1;
      showToast(`订阅成功！您排在第 ${queuePos} 位，${vendorText} · ${chargerText}有空位时会邮件通知您`, 'success');
      hideSubscribeModal();
    } else {
      showToast(result.message || '订阅失败', 'error');
    }
  } catch (err) {
    console.error('订阅请求失败:', err);
    showToast('网络连接失败，请检查网络后重试', 'error');
  } finally {
    btn.disabled = false;
    btn.textContent = '确认订阅';
  }
}

/**
 * 获取排队状态
 */
async function fetchQueueStatus() {
  try {
    const res = await fetch(`${CONFIG.API_BASE}/queue/status`);
    const result = await res.json();
    if (result.success) {
      const count = result.data?.queue_count || 0;
      const statusEl = document.getElementById('queue-status');
      const textEl = document.getElementById('queue-count-text');

      if (count > 0) {
        textEl.textContent = `当前排队人数：${count} 人`;
        statusEl.classList.remove('hidden');
      } else {
        statusEl.classList.add('hidden');
      }
    }
  } catch (err) {
    const statusEl = document.getElementById('queue-status');
    if (statusEl) statusEl.classList.add('hidden');
    if (!isLocalMockMode()) {
      console.warn('获取排队状态失败:', err);
    }
  }
}

function isLocalMockMode() {
  const params = new URLSearchParams(window.location.search);
  if (params.get('mock') === 'true') return true;
  if (window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1') {
    return params.has('mock') || !window.RUNTIME_CONFIG?.apiAvailable;
  }
  return false;
}

/**
 * 显示订阅弹窗
 */
export function showSubscribeModal() {
  document.getElementById('subscribe-modal').classList.add('show');
  const preferences = loadPreferences();
  if (preferences.email && !document.getElementById('email-input').value) {
    document.getElementById('email-input').value = preferences.email;
  }
  if (preferences.feishuName && !document.getElementById('feishu-name-input').value) {
    document.getElementById('feishu-name-input').value = preferences.feishuName;
  }
  const chargerInput = document.querySelector(`input[name="charger-type"][value="${preferences.chargerType}"]`);
  const vendorInput = document.querySelector(`input[name="vendor"][value="${preferences.vendor}"]`);
  if (chargerInput) chargerInput.checked = true;
  if (vendorInput) vendorInput.checked = true;
  // 获取排队状态
  fetchQueueStatus();
}

/**
 * 隐藏订阅弹窗
 */
export function hideSubscribeModal(e) {
  if (e && e.target !== e.currentTarget) return;
  document.getElementById('subscribe-modal').classList.remove('show');
  document.getElementById('email-input').value = '';
  document.getElementById('feishu-name-input').value = '';
  document.querySelector('input[name="charger-type"][value="all"]').checked = true;
  document.querySelector('input[name="vendor"][value="all"]').checked = true;
  document.getElementById('email-error').classList.add('hidden');
  document.getElementById('feishu-name-error').classList.add('hidden');
}
