/* eslint-disable @typescript-eslint/no-var-requires */
/**
 * Expo Config-Plugin — wires the NEFilter Extension target into the iOS
 * project at prebuild time.
 *
 * Was es macht:
 *   1) Setzt die Entitlements der Haupt-App (family-controls, network-
 *      extension, app-groups).
 *   2) Kopiert `modules/rebreak-protection/ios/RebreakURLFilter/` nach
 *      `ios/RebreakURLFilter/` (idempotent).
 *   3) Fügt einen neuen Xcode-Target `RebreakURLFilter` (Bundle-ID
 *      `org.rebreak.app.RebreakURLFilter`) zum Projekt hinzu, mit:
 *       - Source-File: FilterControlProvider.swift
 *       - NetworkExtension.framework
 *       - Embed-App-Extensions Build-Phase im Haupt-Target
 *       - Entitlements via `RebreakURLFilter.entitlements`
 *
 * Wird aus app.config.ts via `plugins: ['./plugins/with-rebreak-protection-ios']`
 * registriert. Idempotent — kann beliebig oft via `expo prebuild` laufen.
 */

const fs = require('fs');
const path = require('path');

const {
  withEntitlementsPlist,
  withDangerousMod,
  withXcodeProject,
} = require('@expo/config-plugins');

const APP_GROUP = 'group.org.rebreak.app';
const TARGET_NAME = 'RebreakURLFilter';
const EXT_BUNDLE_SUFFIX = 'RebreakURLFilter';
const MODULE_DIR = path.join(
  __dirname,
  '..',
  'modules',
  'rebreak-protection',
  'ios',
  TARGET_NAME,
);

// ─── 1) Haupt-App Entitlements ──────────────────────────────────────────────

function withMainAppEntitlements(config) {
  return withEntitlementsPlist(config, (cfg) => {
    cfg.modResults['com.apple.developer.networking.networkextension'] = [
      'content-filter-provider',
    ];
    // Family Controls: das DISTRIBUTION-Entitlement liegt noch bei Apple zur Freigabe
    // → AppStore/TestFlight-Builds (Profile preview/production) dürfen es NICHT claimen,
    // sonst kippt EAS' Provisioning ("doesn't support the Family Controls capability").
    // Für development-Builds (Dev-Entitlement, internal distribution) schalten wir's per
    // Env-Flag wieder ein (eas.json → development.env.REBREAK_ENABLE_FAMILY_CONTROLS="1"),
    // damit denyAppRemoval / ManagedSettings im Dev-Client testbar ist. Sobald Apple das
    // Distribution-Entitlement freigibt: Flag auch in preview/production env setzen + buildNumber bump.
    if (process.env.REBREAK_ENABLE_FAMILY_CONTROLS === '1') {
      cfg.modResults['com.apple.developer.family-controls'] = true;
    }
    const groups = cfg.modResults['com.apple.security.application-groups'] || [];
    if (!groups.includes(APP_GROUP)) {
      cfg.modResults['com.apple.security.application-groups'] = [...groups, APP_GROUP];
    }
    return cfg;
  });
}

// ─── 2) Extension-Sources ins ios/-Verzeichnis kopieren ─────────────────────

function withCopyExtensionSources(config) {
  return withDangerousMod(config, [
    'ios',
    async (cfg) => {
      const platformProjectRoot = cfg.modRequest.platformProjectRoot;
      const dest = path.join(platformProjectRoot, TARGET_NAME);
      if (!fs.existsSync(MODULE_DIR)) {
        throw new Error(
          `[with-rebreak-protection-ios] Extension source dir missing: ${MODULE_DIR}`,
        );
      }
      if (!fs.existsSync(dest)) fs.mkdirSync(dest, { recursive: true });
      for (const file of fs.readdirSync(MODULE_DIR)) {
        const srcFile = path.join(MODULE_DIR, file);
        const destFile = path.join(dest, file);
        fs.copyFileSync(srcFile, destFile);
      }
      return cfg;
    },
  ]);
}

// ─── 3) Xcode-Target hinzufügen ──────────────────────────────────────────────

function withExtensionTarget(config) {
  return withXcodeProject(config, async (cfg) => {
    const proj = cfg.modResults;

    // Idempotenz: skip wenn Target schon angelegt
    if (proj.pbxTargetByName(TARGET_NAME)) {
      return cfg;
    }

    const mainBundleId = cfg.ios?.bundleIdentifier;
    if (!mainBundleId) {
      throw new Error('[with-rebreak-protection-ios] ios.bundleIdentifier fehlt in app.config');
    }
    const extBundleId = `${mainBundleId}.${EXT_BUNDLE_SUFFIX}`;

    // ── Target anlegen (Type: app_extension) ──
    const target = proj.addTarget(TARGET_NAME, 'app_extension', TARGET_NAME, extBundleId);

    // ── Build-Phasen: Sources + Frameworks + Resources ──
    proj.addBuildPhase(
      ['FilterControlProvider.swift'],
      'PBXSourcesBuildPhase',
      'Sources',
      target.uuid,
    );
    proj.addBuildPhase(
      ['NetworkExtension.framework'],
      'PBXFrameworksBuildPhase',
      'Frameworks',
      target.uuid,
    );
    // Info.plist gehört NICHT als Resource — wird via INFOPLIST_FILE referenziert.

    // ── PBXGroup für die Sources ──
    const pbxGroup = proj.addPbxGroup(
      ['FilterControlProvider.swift', 'Info.plist', 'RebreakURLFilter.entitlements'],
      TARGET_NAME,
      TARGET_NAME,
    );
    // Group ans CustomTemplate-Group hängen damit sie im Project Navigator erscheint
    const groups = proj.hash.project.objects.PBXGroup;
    Object.keys(groups).forEach((key) => {
      if (
        groups[key].name === 'CustomTemplate' ||
        (groups[key].name === undefined && groups[key].path === undefined)
      ) {
        proj.addToPbxGroup(pbxGroup.uuid, key);
      }
    });

    // ── Build-Settings auf der Target-Configuration anpassen ──
    const configurations = proj.pbxXCBuildConfigurationSection();
    Object.keys(configurations)
      .filter((k) => typeof configurations[k] === 'object')
      .forEach((k) => {
        const buildSettingsObj = configurations[k].buildSettings;
        if (
          buildSettingsObj &&
          buildSettingsObj.PRODUCT_NAME &&
          buildSettingsObj.PRODUCT_NAME.replace(/"/g, '') === TARGET_NAME
        ) {
          buildSettingsObj.INFOPLIST_FILE = `"${TARGET_NAME}/Info.plist"`;
          buildSettingsObj.CODE_SIGN_ENTITLEMENTS = `"${TARGET_NAME}/${TARGET_NAME}.entitlements"`;
          buildSettingsObj.IPHONEOS_DEPLOYMENT_TARGET = '15.1';
          buildSettingsObj.SWIFT_VERSION = '5.9';
          buildSettingsObj.TARGETED_DEVICE_FAMILY = '"1,2"';
          buildSettingsObj.CODE_SIGN_STYLE = 'Automatic';
          // EAS managed credentials setzen DEVELOPMENT_TEAM nur auf der Main-App.
          // Die Extension ist ein eigenes Target → muss expliziten Team-Wert haben,
          // sonst: "Signing for 'RebreakURLFilter' requires a development team".
          buildSettingsObj.DEVELOPMENT_TEAM = '84BQ7MTFYK';
        }
      });

    // ── Embed App Extensions Build-Phase im Haupt-Target ──
    // Suche nach existierender CopyFilesBuildPhase mit Comment "Embed App Extensions"
    const mainTargetUuid = proj.getFirstTarget().uuid;
    const buildPhases = proj.hash.project.objects.PBXNativeTarget[mainTargetUuid].buildPhases;
    const copyFilesPhases = proj.hash.project.objects.PBXCopyFilesBuildPhase || {};
    const hasEmbedPhase = Object.keys(copyFilesPhases).some((key) => {
      const phase = copyFilesPhases[key];
      return (
        typeof phase === 'object' &&
        phase.dstSubfolderSpec === 13 && // 13 = PluginsAndFrameworks (App Extensions)
        buildPhases.some((bp) => bp.value === key)
      );
    });
    if (!hasEmbedPhase) {
      proj.addBuildPhase(
        [`${TARGET_NAME}.appex`],
        'PBXCopyFilesBuildPhase',
        'Embed App Extensions',
        mainTargetUuid,
        'app_extension', // dstSubfolderSpec=13
      );
    }

    // ── Target-Dependency: Haupt-App muss Extension vor sich bauen ──
    proj.addTargetDependency(mainTargetUuid, [target.uuid]);

    return cfg;
  });
}

// ─── Composition ────────────────────────────────────────────────────────────

module.exports = function withRebreakProtectionIos(config) {
  config = withMainAppEntitlements(config);
  config = withCopyExtensionSources(config);
  config = withExtensionTarget(config);
  return config;
};
