import { Injectable, Logger } from '@nestjs/common'
import { Platform } from '../../domain/version-management'
import * as fs from 'fs'
import * as path from 'path'
import * as os from 'os'

export interface ParsedPackageInfo {
  packageName: string
  versionCode: number
  versionName: string
  minSdkVersion?: string
  targetSdkVersion?: string
}

@Injectable()
export class PackageParserService {
  private readonly logger = new Logger(PackageParserService.name)

  async parsePackage(buffer: Buffer, platform: Platform): Promise<ParsedPackageInfo | null> {
    try {
      if (platform === Platform.ANDROID) {
        return await this.parseApk(buffer)
      } else if (platform === Platform.IOS) {
        return await this.parseIpa(buffer)
      }
      return null
    } catch (error) {
      this.logger.error(`Failed to parse ${platform} package:`, error)
      return null
    }
  }

  private async parseApk(buffer: Buffer): Promise<ParsedPackageInfo | null> {
    // ApkReader 需要文件路径，所以先保存到临时文件
    const tempDir = os.tmpdir()
    const tempFile = path.join(tempDir, `apk_${Date.now()}_${Math.random().toString(36).slice(2)}.apk`)

    try {
      // 写入临时文件
      fs.writeFileSync(tempFile, buffer)

      // 动态导入 adbkit-apkreader (CJS module, exports class directly)
      const ApkReader = require('adbkit-apkreader')
      const reader = await ApkReader.open(tempFile)
      const manifest = await reader.readManifest()

      return {
        packageName: manifest.package || '',
        versionCode: manifest.versionCode || 0,
        versionName: manifest.versionName || '',
        minSdkVersion: manifest.usesSdk?.minSdkVersion?.toString(),
        targetSdkVersion: manifest.usesSdk?.targetSdkVersion?.toString(),
      }
    } catch (error) {
      this.logger.error('Failed to parse APK:', error)
      return null
    } finally {
      // 清理临时文件
      try {
        if (fs.existsSync(tempFile)) {
          fs.unlinkSync(tempFile)
        }
      } catch (e) {
        this.logger.warn('Failed to cleanup temp APK file:', e)
      }
    }
  }

  private async parseIpa(buffer: Buffer): Promise<ParsedPackageInfo | null> {
    try {
      // 动态导入 jszip 和 plist
      const JSZip = await import('jszip')
      const plist = await import('plist')

      const zip = await JSZip.default.loadAsync(buffer)

      // 找到 Info.plist 文件
      let infoPlistPath: string | null = null
      for (const filename of Object.keys(zip.files)) {
        if (filename.match(/^Payload\/[^/]+\.app\/Info\.plist$/)) {
          infoPlistPath = filename
          break
        }
      }

      if (!infoPlistPath) {
        this.logger.error('Info.plist not found in IPA')
        return null
      }

      const plistData = await zip.files[infoPlistPath].async('nodebuffer')
      const plistObj = plist.default.parse(plistData.toString('utf-8')) as Record<string, unknown>

      return {
        packageName: (plistObj.CFBundleIdentifier as string) || '',
        versionCode: parseInt((plistObj.CFBundleVersion as string) || '0', 10),
        versionName: (plistObj.CFBundleShortVersionString as string) || '',
        minSdkVersion: plistObj.MinimumOSVersion as string | undefined,
      }
    } catch (error) {
      this.logger.error('Failed to parse IPA:', error)
      return null
    }
  }
}
