import {
  copyFileSync,
  existsSync,
  mkdirSync,
  readFileSync,
  readdirSync,
  writeFileSync,
} from 'node:fs'
import { dirname, resolve } from 'node:path'
import { fileURLToPath } from 'node:url'

const webRoot = resolve(dirname(fileURLToPath(import.meta.url)), '..')

function updateFile(path, update) {
  if (!existsSync(path)) return false
  const current = readFileSync(path, 'utf8')
  const next = update(current)
  if (next !== current) writeFileSync(path, next, 'utf8')
  return true
}

function copyTemplateTree(source, destination) {
  if (!existsSync(source)) {
    throw new Error(`缺少原生模板目录：${source}`)
  }
  mkdirSync(destination, { recursive: true })
  for (const entry of readdirSync(source, { withFileTypes: true })) {
    const sourcePath = resolve(source, entry.name)
    const destinationPath = resolve(destination, entry.name)
    if (entry.isDirectory()) copyTemplateTree(sourcePath, destinationPath)
    else copyFileSync(sourcePath, destinationPath)
  }
}

function configureAndroid() {
  const androidRoot = resolve(webRoot, 'android')
  const variablesPath = resolve(webRoot, 'android', 'variables.gradle')
  const templateRoot = resolve(webRoot, 'native', 'android')
  const manifestPath = resolve(
    androidRoot,
    'app',
    'src',
    'main',
    'AndroidManifest.xml',
  )
  if (!existsSync(variablesPath)) return false

  copyTemplateTree(templateRoot, androidRoot)
  if (!existsSync(manifestPath)) {
    throw new Error('Android 原生模板未生成 AndroidManifest.xml。')
  }

  updateFile(variablesPath, content => {
    if (!/minSdkVersion\s*=\s*\d+/.test(content)) {
      throw new Error('未在 android/variables.gradle 中找到 minSdkVersion。')
    }
    return content.replace(/minSdkVersion\s*=\s*\d+/, 'minSdkVersion = 26')
  })

  updateFile(manifestPath, content => {
    const declarations = [
      '<uses-permission android:name="android.permission.CAMERA" />',
      '<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />',
      '<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />',
      '<uses-feature android:name="android.hardware.camera" android:required="false" />',
      '<uses-feature android:name="android.hardware.location.gps" android:required="false" />',
    ]
    const missing = declarations.filter(declaration => !content.includes(declaration))
    if (!missing.length) return content
    return content.replace(
      '</manifest>',
      `    ${missing.join('\n    ')}\n</manifest>`,
    )
  })
  return true
}

function configureIos() {
  const infoPlistPath = resolve(webRoot, 'ios', 'App', 'App', 'Info.plist')
  if (!existsSync(infoPlistPath)) return false

  updateFile(infoPlistPath, content => {
    const descriptions = [
      ['NSCameraUsageDescription', '用于扫描教师展示的课堂签到二维码。'],
      ['NSLocationWhenInUseUsageDescription', '用于在课堂签到时校验当前位置。'],
      ['NSLocationAlwaysAndWhenInUseUsageDescription', '用于在课堂签到时校验当前位置。'],
    ]
    const missing = descriptions.filter(([key]) => !content.includes(`<key>${key}</key>`))
    if (!missing.length) return content
    const entries = missing
      .map(([key, value]) => `\t<key>${key}</key>\n\t<string>${value}</string>`)
      .join('\n')
    return content.replace('</dict>', `${entries}\n</dict>`)
  })
  return true
}

const configuredPlatforms = [
  configureAndroid() ? 'Android' : null,
  configureIos() ? 'iOS' : null,
].filter(Boolean)

if (!configuredPlatforms.length) {
  throw new Error('尚未生成 Capacitor 原生工程，请先运行 npx cap add android 或 ios。')
}

console.log(`已配置 ${configuredPlatforms.join('、')} 的扫码、定位和原生桌面体验。`)
