import { promises as fs } from 'fs'
import { encryptText, decryptText } from './crypto'

export interface ProjectJson {
  appName?: string
  version?: string
  pages?: PageFileJson[]
}

interface PageFileJson {
  PageID?: unknown
  PageTitle?: unknown
  PageDescribe?: unknown
  ScreenIndex?: unknown
  ControllerIndex?: unknown
  IsDisplay?: unknown
  PageUrl?: unknown
  PageParams?: unknown
  PagePreview?: unknown
}

export interface SyncPage {
  id: string
  title: string
  url: string
  screen: number
  ctrl: number
  display: boolean
}

export interface ReadResult {
  json: ProjectJson | null
  path: string
  error?: string
}

/** 解析页面 JSON 为可同步给播放端的页面列表 */
export function pagesToSync(json: ProjectJson): SyncPage[] {
  const list = Array.isArray(json.pages) ? json.pages : []
  return list.map((f: PageFileJson, i) => ({
    id: String(f.PageID ?? 'P-' + String(i + 1).padStart(3, '0')),
    title: String(f.PageTitle ?? '页面 ' + (i + 1)),
    url: String(f.PageUrl ?? 'about:blank'),
    screen: Number(f.ScreenIndex) || 1,
    ctrl: Number(f.ControllerIndex) || 0,
    display: f.IsDisplay !== false
  }))
}

/**
 * 读取工程文件并解密敏感字段。
 * 密码错误时返回 error='密码错误'
 */
export async function readProjectFile(path: string, password: string): Promise<ReadResult> {
  try {
    const raw = await fs.readFile(path, 'utf8')
    const json = JSON.parse(raw) as ProjectJson
    if (Array.isArray(json.pages)) {
      for (const p of json.pages) {
        if (typeof p.PageUrl === 'string' && p.PageUrl.startsWith('enc:')) {
          const dec = decryptText(p.PageUrl, password)
          if (dec === null) return { json: null, path, error: '密码错误' }
          p.PageUrl = dec
        }
        if (typeof p.PageParams === 'string' && p.PageParams.startsWith('enc:')) {
          const dec = decryptText(p.PageParams, password)
          if (dec === null) return { json: null, path, error: '密码错误' }
          p.PageParams = dec
        }
      }
    }
    return { json, path }
  } catch {
    return { json: null, path, error: 'JSON 文件无法解析' }
  }
}

/** 保存工程文件；设置了密码时对 URL / 参数加密存储 */
export async function writeProjectFile(
  path: string,
  data: string,
  password: string
): Promise<{ ok: boolean; error?: string }> {
  try {
    let out = data
    if (password) {
      const json = JSON.parse(data) as ProjectJson
      if (Array.isArray(json.pages)) {
        for (const p of json.pages) {
          if (typeof p.PageUrl === 'string') p.PageUrl = encryptText(p.PageUrl, password)
          if (typeof p.PageParams === 'string') p.PageParams = encryptText(p.PageParams, password)
        }
      }
      out = JSON.stringify(json, null, 2)
    }
    await fs.writeFile(path, out, 'utf8')
    return { ok: true }
  } catch (e) {
    return { ok: false, error: String(e) }
  }
}

// ===== URL 构造（播放端自动发布用，与渲染层 pageSrc 逻辑保持一致）=====

let urlBase = 'file://'

export function setUrlBase(base: string): void {
  urlBase = base
}

export function buildPageUrl(url: string, params: string, id: string, title: string): string {
  if (!url || url === 'about:blank') return 'about:blank'
  try {
    const u = new URL(url, urlBase)
    if (params) {
      params.split('\n').forEach((line) => {
        const eq = line.indexOf('=')
        if (eq > 0) {
          const k = line.slice(0, eq).trim()
          const v = line.slice(eq + 1).trim()
          if (k) u.searchParams.set(k, v)
        }
      })
    }
    if (!u.searchParams.has('no')) u.searchParams.set('no', id.replace(/\D/g, '') || '0')
    if (!u.searchParams.has('title')) u.searchParams.set('title', title)
    return u.href
  } catch {
    return 'about:blank'
  }
}
