const path = require('node:path');
const fs = require('fs-extra');
const kleur = require('kleur');
const ui = require('../utils/ui');
const { createTranslator, detectDefaultLanguage } = require('../utils/i18n');
const {
  getBaseChecks,
  getPlatformChecks,
  getBackendChecks,
  runChecks,
  hasRequiredFailures
} = require('../utils/checks');
const {
  validateAppleSetup,
  iosReleaseDocPath,
  isKasyFlutterProject,
  checkIosSigning,
} = require('../utils/apple-release');
const { validateCodemagicSetup, codemagicReleaseDocPath } = require('../utils/codemagic-release');
const { validateGoogleIosUrlScheme, validateAppleSignInEntitlement, validateFacebookInfoPlist, validateFacebookAndroidStrings, validateRevenueCat } = require('../scaffold/shared/post-build');
const { printCompactHeader } = require('../utils/brand');

function collectOptionalBackendChecks() {
  return [
    ...getBackendChecks('firebase'),
    ...getBackendChecks('supabase')
  ];
}

/**
 * Reconstruct active modules from kit_setup.json flags + features.dart.
 */
async function getActiveModules(kitSetup, projectDir) {
  const modules = [];
  if (kitSetup.useSentry) modules.push('sentry');
  if (kitSetup.analyticsProvider === 'mixpanel') modules.push('analytics');
  if (kitSetup.withFacebookPixel) modules.push('facebook');
  if (kitSetup.subscriptionModule) modules.push('revenuecat');
  if (kitSetup.withOnboarding) modules.push('onboarding');
  if (kitSetup.webCompat) modules.push('web');
  if (kitSetup.feedbackModule) modules.push('feedback');

  // Read features.dart for llm_chat, widget
  const featuresPath = path.join(projectDir, 'lib', 'core', 'config', 'features.dart');
  if (await fs.pathExists(featuresPath)) {
    const content = await fs.readFile(featuresPath, 'utf8');
    if (/const bool withLlmChat\s*=\s*true/.test(content)) modules.push('llm_chat');
  }

  // Check ci by directory
  if (await fs.pathExists(path.join(projectDir, '.github', 'workflows'))) modules.push('ci');

  return modules;
}

async function runProjectChecks(projectDir, t, options = {}) {
  const kitSetupPath = path.join(projectDir, 'kit_setup.json');
  if (!(await fs.pathExists(kitSetupPath))) return;

  let config;
  try {
    config = await fs.readJson(kitSetupPath);
  } catch {
    return;
  }

  ui.log.step(kleur.bold(t('doctor.project.title')));

  ui.log.success(`${t('doctor.project.appName')}: ${kleur.cyan(config.appName || '—')}`);
  ui.log.success(`${t('doctor.project.backend')}: ${kleur.cyan(config.backendProvider || '—')}`);
  ui.log.success(`${t('doctor.project.bundleId')}: ${kleur.dim(config.bundleId || '—')}`);

  // pub get check
  const lockExists = await fs.pathExists(path.join(projectDir, 'pubspec.lock'));
  if (lockExists) {
    ui.log.success(t('doctor.project.pubGet'));
  } else {
    ui.log.warn(t('doctor.project.pubGetMissing'));
  }

  // Active modules
  const modules = await getActiveModules(config, projectDir);
  if (modules.length > 0) {
    ui.log.success(`${t('doctor.project.modules')}: ${kleur.cyan(modules.join(', '))}`);
  } else {
    ui.log.message(kleur.dim(`– ${t('doctor.project.noModules')}`));
  }

  await runIosReleaseChecks(projectDir, t, options.language, config);
  await runRevenueCatChecks(projectDir, t, config);
}

async function runIosReleaseChecks(projectDir, t, language, config = {}) {
  if (!(await isKasyFlutterProject(projectDir))) return;

  const lang = language || detectDefaultLanguage();
  ui.log.step(kleur.bold(t('doctor.ios.title')));

  if (process.platform !== 'darwin') {
    ui.log.warn(t('doctor.ios.notMac'));
  } else {
    const signing = await checkIosSigning(projectDir);
    if (signing.ok) {
      ui.log.success(t('doctor.ios.signingOk'));
    } else {
      ui.log.warn(t('doctor.ios.signingMissing'));
    }
  }

  const googleScheme = await validateGoogleIosUrlScheme(projectDir);
  if (googleScheme.skipped) {
    ui.log.message(kleur.dim(`– ${t('doctor.ios.googleUrlSchemeSkipped')}`));
  } else if (googleScheme.ok) {
    ui.log.success(t('doctor.ios.googleUrlSchemeOk'));
  } else {
    ui.log.error(`${t('doctor.ios.googleUrlSchemeMissing')}\n${kleur.dim(googleScheme.error)}`);
  }

  const appleEntitlement = await validateAppleSignInEntitlement(projectDir);
  if (appleEntitlement.ok) {
    ui.log.success(t('doctor.ios.appleSignInEntitlementOk'));
  } else {
    ui.log.warn(`${t('doctor.ios.appleSignInEntitlementMissing')}\n${kleur.dim(appleEntitlement.error)}`);
  }

  if (config.withFacebookPixel) {
    const facebook = await validateFacebookInfoPlist(projectDir);
    if (facebook.skipped) {
      ui.log.message(kleur.dim(`– ${t('doctor.ios.facebookSkipped')}`));
    } else if (facebook.ok) {
      ui.log.success(t('doctor.ios.facebookOk'));
    } else {
      ui.log.warn(`${t('doctor.ios.facebookPlaceholders')}\n${kleur.dim(facebook.error)}`);
    }

    const facebookAndroid = await validateFacebookAndroidStrings(projectDir);
    if (!facebookAndroid.skipped) {
      if (facebookAndroid.ok) {
        ui.log.success(t('doctor.android.facebookOk'));
      } else {
        ui.log.warn(`${t('doctor.android.facebookPlaceholders')}\n${kleur.dim(facebookAndroid.error)}`);
      }
    }
  }

  const apple = await validateAppleSetup(projectDir);
  if (apple.ok) {
    ui.log.success(t('doctor.ios.appleOk'));
    ui.log.success(t('doctor.ios.p8Ok'));
  } else {
    if (apple.issues.includes('missing_env') || apple.issues.includes('missing_credentials')) {
      ui.log.warn(t('doctor.ios.appleMissing'));
    }
    if (apple.issues.includes('missing_p8')) {
      ui.log.warn(t('doctor.ios.p8Missing'));
    }
  }

  const cm = await validateCodemagicSetup(projectDir);
  if (cm.ok) {
    ui.log.success(t('doctor.ios.codemagicOk'));
  } else if (cm.issues.includes('missing_env')) {
    ui.log.message(kleur.dim(`– ${t('doctor.ios.codemagicMissing')}`));
  }

  const docPath = iosReleaseDocPath(lang);
  ui.log.message(kleur.dim(`– ${t('doctor.ios.doc')}: ${docPath}, ${codemagicReleaseDocPath(lang)}`));
}

async function runRevenueCatChecks(projectDir, t, config) {
  if (!config.subscriptionModule) return;

  ui.log.step(kleur.bold(t('doctor.revenuecat.title')));

  const rc = await validateRevenueCat(projectDir, config);
  if (rc.skipped) return;

  if (rc.legacy) {
    // Project predates the test/prod split — show the old summary.
    if (!rc.iosEmpty && !rc.androidEmpty) {
      ui.log.success(t('doctor.revenuecat.keysOk'));
    } else {
      ui.log.warn(t('doctor.revenuecat.keysEmpty'));
    }
    if (rc.bothTest) {
      ui.log.warn(t('doctor.revenuecat.keysTest'));
    }
  } else {
    // New 3-key scheme. One line per key with granular status.
    if (rc.testOk) {
      ui.log.success(t('doctor.revenuecat.testKeyOk'));
    } else if (rc.testBadPrefix) {
      ui.log.warn(t('doctor.revenuecat.prefixMismatch', { key: 'RC_TEST_KEY', expected: 'test_' }));
    } else {
      ui.log.warn(t('doctor.revenuecat.testKeyMissing'));
    }

    if (rc.iosProdOk) {
      ui.log.success(t('doctor.revenuecat.iosProdOk'));
    } else if (rc.iosProdBadPrefix) {
      ui.log.warn(t('doctor.revenuecat.prefixMismatch', { key: 'RC_IOS_PROD_KEY', expected: 'appl_' }));
    } else {
      ui.log.message(kleur.dim(`– ${t('doctor.revenuecat.iosProdMissing')}`));
    }

    if (rc.androidProdOk) {
      ui.log.success(t('doctor.revenuecat.androidProdOk'));
    } else if (rc.androidProdBadPrefix) {
      ui.log.warn(t('doctor.revenuecat.prefixMismatch', { key: 'RC_ANDROID_PROD_KEY', expected: 'goog_' }));
    } else {
      ui.log.message(kleur.dim(`– ${t('doctor.revenuecat.androidProdMissing')}`));
    }

    if (rc.onlyTest) {
      ui.log.warn(t('doctor.revenuecat.keysTest'));
    }
  }

  if (rc.webhookUrl) {
    ui.log.success(`${t('doctor.revenuecat.webhookUrlSupabase')}:\n${kleur.cyan(rc.webhookUrl)}`);
  } else if (config.backendProvider === 'firebase' || config.firebaseProjectId) {
    ui.log.message(kleur.dim(`– ${t('doctor.revenuecat.webhookUrlFirebase')}`));
  }
}

async function runDoctor(options = {}) {
  const language = options.language || detectDefaultLanguage();
  const t = createTranslator(language);
  const projectDir = path.resolve(options.directory || '.');
  printCompactHeader(t);
  ui.intro(t('doctor.title'));

  // Project-specific checks (only when inside a kasy project)
  await runProjectChecks(projectDir, t, { language });

  // Compact mode integrates with the Clack rail (│). Non-compact mode uses
  // legacy `ora` which would break the visual flow opened by ui.intro above.
  const baseResults = await runChecks(
    [...getBaseChecks(), ...getPlatformChecks()],
    t('doctor.baseEnvironment'),
    { t, compact: true, spinnerLabel: t('doctor.baseEnvironment'), doneLabel: t('doctor.baseEnvironment') }
  );

  const optionalBackend = collectOptionalBackendChecks();
  if (optionalBackend.length > 0) {
    await runChecks(optionalBackend, t('doctor.optionalBackend'), {
      t, compact: true, spinnerLabel: t('doctor.optionalBackend'), doneLabel: t('doctor.optionalBackend'),
    });
  }

  if (hasRequiredFailures(baseResults)) {
    throw new Error(t('doctor.requiredMissing'));
  }

  ui.outro(t('doctor.requiredPassed'));
}

module.exports = {
  runDoctor
};
