/**
 * 代理配置管理模块
 * 提供 HTTP/HTTPS 代理的配置存储、读取和连接测试
 */

import * as fs from 'fs'
import * as path from 'path'
import { app, session } from 'electron'
import { getSettingsDir } from '../paths'

// 代理模式
export type ProxyMode = 'off' | 'system' | 'manual'

// 代理配置接口
export interface ProxyConfig {
  mode: ProxyMode // 代理模式：关闭、跟随系统、手动配置
  url: string // 完整的代理 URL，如 http://127.0.0.1:7890（仅 manual 模式使用）
}

// 默认配置 - 默认跟随系统
const DEFAULT_CONFIG: ProxyConfig = {
  mode: 'system',
  url: '',
}

// 配置文件路径
let CONFIG_PATH: string | null = null

function getConfigPath(): string {
  if (CONFIG_PATH) return CONFIG_PATH
  CONFIG_PATH = path.join(getSettingsDir(), 'proxy.json')
  return CONFIG_PATH
}

/**
 * 迁移旧版配置到新版
 * 旧版: { enabled: boolean, url: string }
 * 新版: { mode: ProxyMode, url: string }
 */
function migrateOldConfig(data: Record<string, unknown>): ProxyConfig {
  // 如果是旧版配置（有 enabled 字段，没有 mode 字段）
  if ('enabled' in data && !('mode' in data)) {
    const enabled = Boolean(data.enabled)
    const url = String(data.url || '')
    return {
      mode: enabled && url ? 'manual' : 'system', // 旧版关闭的改为跟随系统
      url: url,
    }
  }
  // 新版配置
  const mode = data.mode as ProxyMode
  if (!['off', 'system', 'manual'].includes(mode)) {
    return { ...DEFAULT_CONFIG }
  }
  return {
    mode: mode,
    url: String(data.url || ''),
  }
}

/**
 * 加载代理配置
 */
export function loadProxyConfig(): ProxyConfig {
  const configPath = getConfigPath()

  if (!fs.existsSync(configPath)) {
    return { ...DEFAULT_CONFIG }
  }

  try {
    const content = fs.readFileSync(configPath, 'utf-8')
    const data = JSON.parse(content)
    return migrateOldConfig(data)
  } catch {
    return { ...DEFAULT_CONFIG }
  }
}

/**
 * 保存代理配置
 */
export function saveProxyConfig(config: ProxyConfig): void {
  const configPath = getConfigPath()
  const dir = path.dirname(configPath)

  if (!fs.existsSync(dir)) {
    fs.mkdirSync(dir, { recursive: true })
  }

  fs.writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf-8')

  // 保存后立即应用代理设置到 Electron session
  applyProxyToSession()
}

/**
 * 验证代理 URL 格式
 */
export function validateProxyUrl(url: string): { valid: boolean; error?: string } {
  if (!url) {
    return { valid: false, error: '代理地址不能为空' }
  }

  try {
    const parsed = new URL(url)
    if (!['http:', 'https:'].includes(parsed.protocol)) {
      return { valid: false, error: '仅支持 http:// 或 https:// 协议' }
    }
    if (!parsed.hostname) {
      return { valid: false, error: '代理地址格式无效' }
    }
    return { valid: true }
  } catch {
    return { valid: false, error: '代理地址格式无效，请使用 http://host:port 格式' }
  }
}

/**
 * 将代理设置应用到 Electron session
 * 这会影响所有通过 Electron 发起的网络请求（包括主进程的 fetch）
 */
export async function applyProxyToSession(): Promise<void> {
  const config = loadProxyConfig()

  try {
    switch (config.mode) {
      case 'off':
        // 直接连接，不使用代理
        await session.defaultSession.setProxy({
          mode: 'direct',
        })
        console.log('[Proxy] 代理已关闭（直接连接）')
        break

      case 'system':
        // 使用系统代理设置
        await session.defaultSession.setProxy({
          mode: 'system',
        })
        console.log('[Proxy] 使用系统代理')
        break

      case 'manual':
        // 手动配置代理
        if (config.url) {
          const validation = validateProxyUrl(config.url)
          if (validation.valid) {
            await session.defaultSession.setProxy({
              proxyRules: config.url,
            })
            console.log(`[Proxy] 手动代理已启用: ${config.url}`)
          } else {
            // URL 无效，回退到系统代理
            await session.defaultSession.setProxy({
              mode: 'system',
            })
            console.log('[Proxy] 手动代理 URL 无效，回退到系统代理')
          }
        } else {
          // 没有填写 URL，回退到系统代理
          await session.defaultSession.setProxy({
            mode: 'system',
          })
          console.log('[Proxy] 手动代理未配置 URL，回退到系统代理')
        }
        break

      default:
        // 未知模式，使用系统代理
        await session.defaultSession.setProxy({
          mode: 'system',
        })
        console.log('[Proxy] 未知代理模式，使用系统代理')
    }
  } catch (error) {
    console.error('[Proxy] 设置代理失败:', error)
  }
}

/**
 * 测试代理连接
 * 通过代理请求一个可靠的 HTTPS 地址来验证代理是否可用
 */
export async function testProxyConnection(proxyUrl: string): Promise<{ success: boolean; error?: string }> {
  // 先验证格式
  const validation = validateProxyUrl(proxyUrl)
  if (!validation.valid) {
    return { success: false, error: validation.error }
  }

  // 测试 URL 列表（按优先级）
  const testUrls = [
    'https://www.google.com',
    'https://www.cloudflare.com',
    'https://api.deepseek.com',
  ]

  try {
    // 临时设置代理
    await session.defaultSession.setProxy({
      proxyRules: proxyUrl,
    })

    // 使用 Electron 的 net 模块测试连接
    const { net } = await import('electron')

    let lastError: string = ''

    for (const testUrl of testUrls) {
      try {
        const result = await new Promise<{ success: boolean; error?: string }>((resolve) => {
          const request = net.request({
            method: 'HEAD',
            url: testUrl,
          })

          const timeout = setTimeout(() => {
            request.abort()
            resolve({ success: false, error: '连接超时' })
          }, 10000)

          request.on('response', (response) => {
            clearTimeout(timeout)
            // 任何响应都说明代理可用
            if (response.statusCode < 500) {
              resolve({ success: true })
            } else {
              resolve({ success: false, error: `HTTP ${response.statusCode}` })
            }
          })

          request.on('error', (error) => {
            clearTimeout(timeout)
            resolve({ success: false, error: error.message })
          })

          request.end()
        })

        if (result.success) {
          // 恢复之前的代理设置
          await applyProxyToSession()
          return { success: true }
        }

        lastError = result.error || ''
      } catch (e) {
        lastError = e instanceof Error ? e.message : String(e)
      }
    }

    // 恢复之前的代理设置
    await applyProxyToSession()
    return { success: false, error: lastError || '无法通过代理连接到测试服务器' }
  } catch (error) {
    // 恢复之前的代理设置
    await applyProxyToSession()

    const errorMessage = error instanceof Error ? error.message : String(error)

    // 友好的错误提示
    if (errorMessage.includes('ECONNREFUSED')) {
      return { success: false, error: '连接被拒绝，请检查代理服务器是否运行中' }
    }
    if (errorMessage.includes('ETIMEDOUT') || errorMessage.includes('timeout')) {
      return { success: false, error: '连接超时，请检查代理地址和端口' }
    }
    if (errorMessage.includes('ENOTFOUND')) {
      return { success: false, error: '无法解析代理服务器地址' }
    }

    return { success: false, error: `代理连接失败: ${errorMessage}` }
  }
}

/**
 * 获取当前有效的代理 URL
 * 仅在手动模式且 URL 有效时返回代理 URL，否则返回 undefined
 */
export function getActiveProxyUrl(): string | undefined {
  const config = loadProxyConfig()
  if (config.mode === 'manual' && config.url) {
    const validation = validateProxyUrl(config.url)
    if (validation.valid) {
      return config.url
    }
  }
  return undefined
}

/**
 * 初始化代理模块
 * 应用启动时调用，加载并应用代理配置
 */
export function initProxy(): void {
  // 延迟执行，确保 app ready
  if (app.isReady()) {
    applyProxyToSession()
  } else {
    app.whenReady().then(() => {
      applyProxyToSession()
    })
  }
}
