'use strict';

const https = require('node:https');
const kleur = require('kleur');
const { getStoredLicenseKey, isLicenseFormatValid, setStoredLicenseKey, readLocalConfig, writeLocalConfig } = require('./license');
const { promptLicenseKey } = require('./prompts');
const { createTranslator, detectDefaultLanguage } = require('./i18n');

const VALIDATE_URL = 'https://xkefozfsrmqjtesiitvk.supabase.co/functions/v1/validate-license';
const CACHE_TTL_MS = 7 * 24 * 60 * 60 * 1000; // 7 days

// No key needed
const FREE_COMMANDS = new Set(['run', 'doctor', 'features', 'version', 'help', 'uninstall']);

// Requires key — even if subscription expired (you bought it, it's yours forever)
const PREMIUM_COMMANDS = new Set(['new', 'setup', 'add', 'remove', 'deploy', 'check', 'validate', 'docs', 'ios', 'codemagic', 'notifications']);

// Requires key AND active subscription (update/upgrade only while plan is current)
const UPDATE_COMMANDS = new Set(['upgrade', 'update']);

function resolveCommandFromArgv(argv = []) {
  for (let i = 0; i < argv.length; i += 1) {
    const arg = argv[i];
    if (!arg) continue;
    if (arg === '--lang' || arg === '-l') { i += 1; continue; }
    if (arg.startsWith('--') || (arg.startsWith('-') && arg.length > 1)) continue;
    return arg;
  }
  return null;
}

function shouldRequireLicenseForArgv(argv = []) {
  const command = resolveCommandFromArgv(argv);
  return !!command && (PREMIUM_COMMANDS.has(command) || UPDATE_COMMANDS.has(command));
}

function requiresActiveSubscription(argv = []) {
  const command = resolveCommandFromArgv(argv);
  return !!command && UPDATE_COMMANDS.has(command);
}

function validateOnServer(key) {
  return new Promise((resolve) => {
    const body = JSON.stringify({ key });
    const url = new URL(VALIDATE_URL);
    const options = {
      hostname: url.hostname,
      path: url.pathname,
      method: 'POST',
      headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(body) },
      timeout: 5000,
    };
    const req = https.request(options, (res) => {
      let data = '';
      res.on('data', (chunk) => { data += chunk; });
      res.on('end', () => {
        try { resolve(JSON.parse(data)); }
        catch { resolve(null); }
      });
    });
    req.on('error', () => resolve(null));
    req.on('timeout', () => { req.destroy(); resolve(null); });
    req.write(body);
    req.end();
  });
}

function getCachedValidation() {
  const config = readLocalConfig();
  const cache = config.licenseCache;
  if (!cache || !cache.checkedAt) return null;
  if (Date.now() - cache.checkedAt > CACHE_TTL_MS) return null;
  return cache;
}

function setCachedValidation(result) {
  const config = readLocalConfig();
  writeLocalConfig({ ...config, licenseCache: { ...result, checkedAt: Date.now() } });
}

async function ensureLicenseKey(options = {}) {
  const language = options.language || detectDefaultLanguage();
  const t = createTranslator(language);
  const needsActiveSubscription = requiresActiveSubscription(options.argv || []);

  let key = getStoredLicenseKey();

  // No key stored — ask the user
  if (!key || !isLicenseFormatValid(key)) {
    console.log('');
    console.log(kleur.yellow(t('license.required')));
    console.log('');
    const entered = await promptLicenseKey('', { t });
    key = entered.trim().toUpperCase();
    if (!isLicenseFormatValid(key)) throw new Error(t('license.invalid'));
  }

  // Check local cache (avoids network on every command)
  const cached = getCachedValidation();
  if (cached && cached.valid) {
    if (needsActiveSubscription && !cached.subscription_active) {
      throw new Error(t('license.subscriptionExpired'));
    }
    return key;
  }

  // Validate against server
  process.stdout.write(kleur.cyan(t('license.checking')) + ' ');
  const result = await validateOnServer(key);

  // Network error — offline tolerance
  if (!result) {
    console.log(kleur.yellow(t('license.offlineWarning')));
    console.log('');
    return key;
  }

  // Key not found or deactivated
  if (!result.valid) {
    if (result.reason === 'inactive') {
      // Admin deactivated this key (fraud/chargeback) — clear it so user can enter a new one
      setStoredLicenseKey('');
      throw new Error(t('license.inactive'));
    }
    // Not found: keep the stored key (might not be in DB yet), never cache failures
    throw new Error(t('license.invalid'));
  }

  // Key valid — save cache
  setStoredLicenseKey(key);
  setCachedValidation({
    valid: true,
    subscription_active: result.subscription_active,
    plan: result.plan,
    expires_at: result.expires_at,
  });

  console.log(kleur.green('✓'));
  console.log('');

  // Check subscription for update commands
  if (needsActiveSubscription && !result.subscription_active) {
    throw new Error(t('license.subscriptionExpired'));
  }

  return key;
}

module.exports = { ensureLicenseKey, shouldRequireLicenseForArgv };
