import { parseVersion, checkUpdate } from '@yuzu-gca/shared';
import Constants from 'expo-constants';
import * as FileSystem from 'expo-file-system';
import { NativeModules, Platform } from 'react-native';

// ============================================================
// 1. 版本号读取
// ============================================================

export function getLocalVersion(): string {
  return Constants.expoConfig?.version ?? '0.1.0';
}

export function getLocalBuildTag(): string {
  const v = getLocalVersion();
  const versionCode = Constants.expoConfig?.android?.versionCode ?? 1;
  return `v${v}-dav-android-${versionCode}`;
}

// ============================================================
// 2. JS Bundle OTA（expo-updates 自动处理）
// ============================================================

export async function checkJsBundleUpdate(): Promise<{
  hasUpdate: boolean;
  remoteVersion: string;
}> {
  const localVersion = getLocalVersion();
  const localTag = getLocalBuildTag();
  const local = parseVersion(localTag);
  if (!local) return { hasUpdate: false, remoteVersion: localVersion };

  const result = await checkUpdate('android', local);
  if (!result.shouldUpdate || !result.remoteVersion) {
    return { hasUpdate: false, remoteVersion: localVersion };
  }

  return { hasUpdate: true, remoteVersion: result.remoteVersion.raw };
}

// ============================================================
// 3. APK 静默安装（大更新）
// ============================================================

const ALLOWED_DOWNLOAD_HOSTS = [
  'git.childish-ghost.com',
  'github.com',
];

const { PackageInstallerModule } = NativeModules;

function validateUrl(url: string): void {
  try {
    const host = new URL(url).hostname;
    if (!ALLOWED_DOWNLOAD_HOSTS.some(h => host === h || host.endsWith('.' + h))) {
      throw new Error(`不允许的下载域名: ${host}`);
    }
  } catch (e) {
    if (e instanceof TypeError) throw new Error('下载URL格式无效');
    throw e;
  }
}

export async function downloadAndInstallApk(apkUrl: string, sha256: string): Promise<void> {
  validateUrl(apkUrl);

  const localPath = `${FileSystem.cacheDirectory ?? ''}gca-update.apk`;

  const download = FileSystem.createDownloadResumable(
    apkUrl,
    localPath,
    {},
    (progress) => {
      const pct = (progress.totalBytesWritten / progress.totalBytesExpectedToWrite) * 100;
      console.log(`[OTA] 下载进度: ${pct.toFixed(0)}%`);
    },
  );

  const result = await download.downloadAsync();
  if (!result?.uri) throw new Error('APK 下载失败');

  if (Platform.OS === 'android' && PackageInstallerModule) {
    // SHA256 校验在原生层完成（避免 TOCTOU + 密码学误用）
    await PackageInstallerModule.installApk(result.uri, sha256);
    console.log('[OTA] SHA256校验通过，APK已提交安装');
  } else {
    throw new Error('PackageInstaller 原生模块不可用');
  }
}

// ============================================================
// 4. 启动时一键检查
// ============================================================

export async function onAppStartCheckUpdate(): Promise<{
  jsUpdate: boolean;
  apkUpdate: boolean;
}> {
  const localTag = getLocalBuildTag();
  const local = parseVersion(localTag);
  if (!local) return { jsUpdate: false, apkUpdate: false };

  const result = await checkUpdate('android', local);
  if (!result.shouldUpdate || !result.build) {
    return { jsUpdate: false, apkUpdate: false };
  }

  if (result.build.type === 'apk') {
    await downloadAndInstallApk(result.build.url, result.build.sha256);
    return { jsUpdate: false, apkUpdate: true };
  }

  return { jsUpdate: true, apkUpdate: false };
}
