/**
 * 资源点余额管理服务
 * 负责缓存余额、主动查询、发送前检测
 */

import * as vscode from 'vscode';
import * as https from 'https';
import * as http from 'http';
import { URL } from 'url';
import { getStrangeLoopApiUrl } from '../config/settings';
import { getCachedUserInfo } from './userService';

/** 低余额阈值 */
const LOW_CREDIT_THRESHOLD = 5;

/** 缓存的余额 */
let cachedBalance: number | null = null;

/** 最后更新时间 */
let lastUpdateTime: number = 0;

/** 缓存有效期（5分钟） */
const CACHE_TTL_MS = 5 * 60 * 1000;

/** ExtensionContext 用于持久化存储 */
let extensionContext: vscode.ExtensionContext | null = null;

/** 余额更新回调函数 */
let onBalanceUpdateCallback: ((balance: number) => void) | null = null;

/**
 * 初始化 Credits 服务（设置 context）
 */
export function initCreditsService(context: vscode.ExtensionContext): void {
  extensionContext = context;
  // 从持久化存储加载余额
  const savedBalance = extensionContext.globalState.get<number>('icCoderCreditsBalance');
  if (savedBalance !== undefined) {
    cachedBalance = savedBalance;
    lastUpdateTime = Date.now();
    console.log('[CreditsService] 从持久化存储加载余额:', savedBalance);
  }
}

/**
 * 设置余额更新回调
 */
export function setBalanceUpdateCallback(callback: (balance: number) => void): void {
  onBalanceUpdateCallback = callback;
}

/**
 * 保存余额到持久化存储
 */
async function saveBalance(balance: number): Promise<void> {
  if (extensionContext) {
    await extensionContext.globalState.update('icCoderCreditsBalance', balance);
    console.log('[CreditsService] 余额已保存到持久化存储:', balance);
  }
}

/**
 * 更新缓存的余额（从 SSE credit_update 事件调用）
 */
export function updateCachedBalance(balance: number): void {
  cachedBalance = balance;
  lastUpdateTime = Date.now();
  console.log('[CreditsService] 余额已更新:', balance);
  // 异步保存到持久化存储
  saveBalance(balance).catch(err => {
    console.error('[CreditsService] 保存余额失败:', err);
  });
  // 通知前端更新余额显示
  if (onBalanceUpdateCallback) {
    onBalanceUpdateCallback(balance);
  }
}

/**
 * 获取缓存的余额
 */
export function getCachedBalance(): number | null {
  return cachedBalance;
}

/**
 * 检查缓存是否有效
 */
function isCacheValid(): boolean {
  if (cachedBalance === null) return false;
  return Date.now() - lastUpdateTime < CACHE_TTL_MS;
}

/**
 * StrangeLoop 余额响应类型
 */
interface StrangeLoopBalanceResponse {
  userId?: number;
  availableCredits?: number;
  totalCredits?: number;
  error?: string;
  message?: string;
}

/**
 * 主动查询余额（直接调用 StrangeLoop 接口）
 */
export async function fetchBalance(): Promise<number | null> {
  try {
    // 获取 JWT token
    const session = await vscode.authentication.getSession('iccoder', [], { silent: true });
    if (!session?.accessToken) {
      console.warn('[CreditsService] 无法查询余额：未登录');
      return null;
    }

    return await fetchBalanceWithToken(session.accessToken);
  } catch (error) {
    console.error('[CreditsService] 查询余额异常:', error);
    return null;
  }
}

/**
 * 使用指定 token 查询余额（登录过程中使用）
 */
export async function fetchBalanceWithToken(token: string): Promise<number | null> {
  try {
    console.log('[CreditsService] 开始查询余额，token 长度:', token.length);

    // 直接调用 StrangeLoop 的 /api/credit/balance 接口
    const response = await callStrangeLoopBalance(token);

    if (response.availableCredits !== undefined) {
      const balance = response.availableCredits;
      updateCachedBalance(balance);
      console.log('[CreditsService] 余额查询成功:', balance);
      return balance;
    } else {
      console.warn('[CreditsService] 查询余额失败:', response.error || response.message);
      return null;
    }
  } catch (error) {
    console.error('[CreditsService] 查询余额异常:', error);
    return null;
  }
}

/**
 * 调用 StrangeLoop 余额接口
 */
async function callStrangeLoopBalance(token: string): Promise<StrangeLoopBalanceResponse> {
  const urlStr = getStrangeLoopApiUrl('/strangeloop/api/credit/balance');
  const url = new URL(urlStr);

  const isHttps = url.protocol === 'https:';
  const httpModule = isHttps ? https : http;

  // 余额查询使用固定短超时，避免阻塞发送前检查
  const BALANCE_TIMEOUT_MS = 5000;

  const requestOptions: http.RequestOptions = {
    hostname: url.hostname,
    port: url.port || (isHttps ? 443 : 80),
    path: url.pathname + url.search,
    method: 'GET',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${token}`
    },
    timeout: BALANCE_TIMEOUT_MS
  };

  return new Promise((resolve, reject) => {
    const req = httpModule.request(requestOptions, (res) => {
      let data = '';

      res.on('data', (chunk) => {
        data += chunk;
      });

      res.on('end', () => {
        console.log('[CreditsService] 响应状态码:', res.statusCode);
        console.log('[CreditsService] 响应内容:', data);

        try {
          const json = JSON.parse(data);
          if (res.statusCode && res.statusCode >= 200 && res.statusCode < 300) {
            resolve(json as StrangeLoopBalanceResponse);
          } else if (res.statusCode === 401 || res.statusCode === 403) {
            // 登录过期或无权限
            resolve({ error: '登录已过期，请重新登录' });
          } else {
            resolve({ error: json.error || json.message || json.msg || `HTTP ${res.statusCode}` });
          }
        } catch (e) {
          resolve({ error: `解析响应失败: ${data}` });
        }
      });
    });

    req.on('error', (error) => {
      reject(error);
    });

    req.on('timeout', () => {
      req.destroy();
      reject(new Error('请求超时'));
    });

    req.end();
  });
}

/**
 * 获取当前余额（优先使用缓存，过期则主动查询）
 */
export async function getBalance(): Promise<number | null> {
  if (isCacheValid()) {
    return cachedBalance;
  }
  return await fetchBalance();
}

/**
 * 检查余额是否足够发送消息
 * @returns { allowed: boolean, balance: number | null, message?: string }
 */
export async function checkBalanceBeforeSend(): Promise<{
  allowed: boolean;
  balance: number | null;
  message?: string;
}> {
  const userInfo = getCachedUserInfo();
  if (!userInfo) {
    // 未登录，允许发送（后端会处理）
    return { allowed: true, balance: null };
  }

  const balance = await getBalance();

  if (balance === null) {
    // 无法获取余额，允许发送（后端会处理）
    console.warn('[CreditsService] 无法获取余额，允许发送');
    return { allowed: true, balance: null };
  }

  if (balance < LOW_CREDIT_THRESHOLD) {
    return {
      allowed: false,
      balance,
      message: `资源点余额不足！当前余额 ${balance.toFixed(2)} 点，低于最低要求 ${LOW_CREDIT_THRESHOLD} 点。请充值后再试。`
    };
  }

  return { allowed: true, balance };
}

/**
 * 清除缓存（登出时调用）
 */
export async function clearBalanceCache(): Promise<void> {
  cachedBalance = null;
  lastUpdateTime = 0;
  if (extensionContext) {
    await extensionContext.globalState.update('icCoderCreditsBalance', undefined);
  }
  console.log('[CreditsService] 余额缓存已清除');
}
