import { app, safeStorage } from 'electron'
import { readFile, writeFile } from 'fs/promises'
import { join } from 'path'

import type { ModelConfig } from '../types/model'
import type {
  LoadSettingsResponse,
  SaveSettingsResponse,
  SettingsFile,
  StoredApiKey
} from '../types/settings'

function getSettingsPath(): string {
  return join(app.getPath('userData'), 'settings.json')
}

function encodeApiKey(apiKey: string): StoredApiKey {
  if (safeStorage.isEncryptionAvailable()) {
    return {
      encoding: 'safeStorage',
      value: safeStorage.encryptString(apiKey).toString('base64')
    }
  }

  return {
    encoding: 'plain',
    value: apiKey
  }
}

function decodeApiKey(apiKey?: StoredApiKey): string {
  if (!apiKey) return ''

  if (apiKey.encoding === 'safeStorage') {
    return safeStorage.decryptString(Buffer.from(apiKey.value, 'base64'))
  }

  return apiKey.value
}

export async function loadSettings(): Promise<LoadSettingsResponse> {
  try {
    const raw = await readFile(getSettingsPath(), 'utf-8').catch((error: NodeJS.ErrnoException) => {
      if (error.code === 'ENOENT') return null
      throw error
    })

    if (!raw) {
      return { ok: true, modelConfig: null }
    }

    const settings = JSON.parse(raw) as SettingsFile

    if (!settings.modelConfig) {
      return { ok: true, modelConfig: null }
    }

    const { apiKey, ...modelConfig } = settings.modelConfig

    return {
      ok: true,
      modelConfig: {
        ...modelConfig,
        apiKey: decodeApiKey(apiKey)
      }
    }
  } catch (error) {
    return {
      ok: false,
      message: error instanceof Error ? error.message : '读取配置失败'
    }
  }
}

export async function saveSettings(modelConfig: ModelConfig): Promise<SaveSettingsResponse> {
  try {
    const settings: SettingsFile = {
      modelConfig: {
        provider: modelConfig.provider,
        baseUrl: modelConfig.baseUrl,
        model: modelConfig.model,
        temperature: modelConfig.temperature,
        maxTokens: modelConfig.maxTokens,
        systemPrompt: modelConfig.systemPrompt,
        apiKey: encodeApiKey(modelConfig.apiKey)
      }
    }

    await writeFile(getSettingsPath(), JSON.stringify(settings, null, 2), 'utf-8')

    return { ok: true }
  } catch (error) {
    return {
      ok: false,
      message: error instanceof Error ? error.message : '保存配置失败'
    }
  }
}
