/* eslint-disable @typescript-eslint/no-var-requires */
/**
 * Workaround für Xcode 16 + RN 0.79 + fmt 11.0.2:
 *   "Call to consteval function 'fmt::basic_format_string<...>' is not a constant expression"
 *
 * Grund: fmt/include/fmt/base.h definiert FMT_USE_CONSTEVAL UNCONDITIONAL —
 * kein `#ifndef`-Guard. Daher hilft `-DFMT_USE_CONSTEVAL=0` als Compiler-Flag
 * NICHT — fmt's eigener Header überschreibt es.
 *
 * Wir patchen daher direkt die Source-Datei nach `pod install`:
 *  - In ios/Pods/fmt/include/fmt/base.h einen Override-Block einfügen, der
 *    nach fmt's eigener Detection FMT_USE_CONSTEVAL auf 0 zwingt.
 *
 * Wirkung:
 *  - basic_format_string-Konstruktor ist nicht mehr consteval, sondern constexpr
 *  - FMT_STRING("{}{}") expansion compiliert wieder unter Apple Clang 16+
 *
 * Idempotent — markiert die Patch-Stelle mit einem Magic-Comment.
 */
const { withDangerousMod } = require('@expo/config-plugins');
const fs = require('fs');
const path = require('path');

const PATCH_MARKER = '/* REBREAK_FMT_CONSTEVAL_FIX */';

const SOURCE_PATCH = `

${PATCH_MARKER}
// Xcode 16 + Apple Clang 16+ haben einen consteval-Bug der fmt's
// FMT_STRING-basierte format_to-Calls bricht. Wir zwingen daher
// FMT_USE_CONSTEVAL=0 nach fmt's eigener Detection.
#undef FMT_USE_CONSTEVAL
#define FMT_USE_CONSTEVAL 0
#undef FMT_CONSTEVAL
#define FMT_CONSTEVAL
#undef FMT_CONSTEXPR20
#define FMT_CONSTEXPR20
${PATCH_MARKER}
`;

function patchFmtBaseHeader(podsDir) {
  const baseHeader = path.join(podsDir, 'fmt', 'include', 'fmt', 'base.h');
  if (!fs.existsSync(baseHeader)) {
    console.warn('[with-fmt-consteval-fix] fmt/base.h not found at', baseHeader);
    return false;
  }

  let content = fs.readFileSync(baseHeader, 'utf-8');
  if (content.includes(PATCH_MARKER)) {
    return false; // schon gepatcht
  }

  // Patch nach der Detection-Block einfügen, vor dem `#if FMT_USE_CONSTEVAL`
  // Suche nach dem End-of-Detection (line endet mit `#endif` direkt vor
  // `#if FMT_USE_CONSTEVAL`).
  const anchor = '#if FMT_USE_CONSTEVAL';
  const idx = content.indexOf(anchor);
  if (idx === -1) {
    console.warn('[with-fmt-consteval-fix] anchor not found in base.h');
    return false;
  }

  // Patch direkt vor dem anchor einfügen
  content = content.slice(0, idx) + SOURCE_PATCH + '\n' + content.slice(idx);
  fs.writeFileSync(baseHeader, content);
  console.log('[with-fmt-consteval-fix] patched', baseHeader);
  return true;
}

module.exports = function withFmtConstevalFix(config) {
  return withDangerousMod(config, [
    'ios',
    async (cfg) => {
      const podsDir = path.join(cfg.modRequest.platformProjectRoot, 'Pods');
      // Wenn Pods/ noch nicht existiert (= prebuild Phase, vor pod install):
      // Patch wird automatisch beim nächsten Run angewendet sobald Pods da sind.
      // Damit der User aber NICHT manuell nachpatchen muss, packen wir den
      // Patch zusätzlich in einen Podfile-pre_install-Hook der bei JEDEM
      // pod install läuft (auch beim ersten).
      if (fs.existsSync(podsDir)) {
        patchFmtBaseHeader(podsDir);
      }

      // Podfile pre_install-Hook injizieren — patched die fmt-Source bei
      // jedem pod install (nachdem Pods/fmt/ bereits gedownloaded ist).
      const podfilePath = path.join(cfg.modRequest.platformProjectRoot, 'Podfile');
      let podfile = fs.readFileSync(podfilePath, 'utf-8');

      // Alten Patch (frühere Plugin-Version) entfernen
      const oldPatchRegex = /\s*# ─── Rebreak: fmt consteval fix[\s\S]*?# ───────────────────────────────────────────────────────/g;
      podfile = podfile.replace(oldPatchRegex, '');
      const oldPostInstallPatchRegex = /\s*# ═══ Rebreak: fmt consteval source-patch[\s\S]*?# ═══════════════════════════════════════════════════════/g;
      podfile = podfile.replace(oldPostInstallPatchRegex, '');

      // Neuen pre_install-Hook injizieren (vor `target` block).
      // Wir patchen die fmt/base.h-Datei direkt im pre_install — pod install
      // hat dann zu dem Zeitpunkt schon den Pod gedownloaded.
      const PRE_INSTALL = `
# ═══ Rebreak: fmt consteval source-patch (Xcode 16 + RN 0.79) ═══
pre_install do |installer|
  fmt_base_h = File.join(installer.sandbox.root, 'fmt', 'include', 'fmt', 'base.h')
  if File.exist?(fmt_base_h)
    content = File.read(fmt_base_h)
    marker = '/* REBREAK_FMT_CONSTEVAL_FIX */'
    unless content.include?(marker)
      patch = <<~PATCH

#{marker}
// Xcode 16 + Apple Clang 16+ consteval-Bug Workaround
#undef FMT_USE_CONSTEVAL
#define FMT_USE_CONSTEVAL 0
#undef FMT_CONSTEVAL
#define FMT_CONSTEVAL
#undef FMT_CONSTEXPR20
#define FMT_CONSTEXPR20
#{marker}
      PATCH
      anchor = '#if FMT_USE_CONSTEVAL'
      if content.include?(anchor)
        content = content.sub(anchor, patch + "\\n" + anchor)
        File.write(fmt_base_h, content)
        Pod::UI.puts "  -> Patched fmt/base.h with consteval workaround".green
      end
    end
  end
end
# ═══════════════════════════════════════════════════════
`;

      // Inject vor dem ersten `target` block (Top-level)
      const targetMatch = podfile.match(/^target\s+['"][^'"]+['"]\s+do/m);
      if (targetMatch) {
        const insertAt = targetMatch.index;
        podfile = podfile.slice(0, insertAt) + PRE_INSTALL + '\n' + podfile.slice(insertAt);
      } else {
        // Fallback: ans Ende anhängen
        podfile += PRE_INSTALL;
      }

      fs.writeFileSync(podfilePath, podfile);
      return cfg;
    },
  ]);
};
