import { Injectable, Logger, BadRequestException } from '@nestjs/common';
import { IPackageParser, ParsedPackageInfo } from '../../domain/ports/package-parser.interface';

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

  async parse(buffer: Buffer, filename: string): Promise<ParsedPackageInfo> {
    const ext = filename.split('.').pop()?.toLowerCase();
    if (ext === 'apk') return this.parseApk(buffer);
    if (ext === 'ipa') return this.parseIpa(buffer);
    throw new BadRequestException('Unsupported file format. Only .apk and .ipa are supported.');
  }

  private async parseApk(buffer: Buffer): Promise<ParsedPackageInfo> {
    try {
      // Dynamic import to handle missing dependency gracefully
      const ApkReader = await import('adbkit-apkreader').then(m => m.default || m);
      const reader = await ApkReader.open(buffer);
      const manifest = await reader.readManifest();
      return {
        packageName: manifest.package || 'unknown',
        versionCode: manifest.versionCode || 0,
        versionName: manifest.versionName || '0.0.0',
        minSdkVersion: manifest.usesSdk?.minSdkVersion?.toString(),
        platform: 'ANDROID',
      };
    } catch (err: any) {
      this.logger.warn(`APK parse failed, using fallback: ${err.message}`);
      return {
        packageName: 'unknown',
        versionCode: 0,
        versionName: '0.0.0',
        platform: 'ANDROID',
      };
    }
  }

  private async parseIpa(buffer: Buffer): Promise<ParsedPackageInfo> {
    try {
      const unzipper = await import('unzipper');
      const bplistParser = await import('bplist-parser');
      const directory = await unzipper.Open.buffer(buffer);
      const plistEntry = directory.files.find((f: any) => /Payload\/[^/]+\.app\/Info\.plist$/.test(f.path));
      if (!plistEntry) throw new Error('Info.plist not found in IPA');

      const plistBuffer = await plistEntry.buffer();
      const parsed = bplistParser.parseBuffer(plistBuffer);
      const info = parsed[0] || {};

      return {
        packageName: info.CFBundleIdentifier || 'unknown',
        versionCode: parseInt(info.CFBundleVersion || '0', 10),
        versionName: info.CFBundleShortVersionString || '0.0.0',
        minSdkVersion: info.MinimumOSVersion,
        platform: 'IOS',
      };
    } catch (err: any) {
      this.logger.warn(`IPA parse failed, using fallback: ${err.message}`);
      return {
        packageName: 'unknown',
        versionCode: 0,
        versionName: '0.0.0',
        platform: 'IOS',
      };
    }
  }
}
