{% extends "base.html" %}

{% block title %}Unit Swap - Seismo Fleet Manager{% endblock %}

{% block content %}
<div class="max-w-md mx-auto">
    <div class="mb-4 flex items-center justify-between">
        <div>
            <h1 class="text-2xl font-bold text-gray-900 dark:text-white">Unit Swap</h1>
            <p class="text-sm text-gray-500 dark:text-gray-400 mt-1">
                Swap a vibration unit (and modem) at a monitoring location.
            </p>
        </div>
        <a href="/tools" class="text-xs text-seismo-orange hover:text-seismo-burgundy whitespace-nowrap">← Tools</a>
    </div>

    <!-- Stepper -->
    <div class="flex items-center justify-between mb-4 text-[11px] text-gray-500 dark:text-gray-400">
        <div id="swap-pill-1" class="flex items-center gap-1 text-seismo-orange font-medium">
            <span class="w-5 h-5 rounded-full bg-seismo-orange text-white inline-flex items-center justify-center text-[10px]">1</span>
            Project
        </div>
        <div class="flex-1 h-px bg-gray-200 dark:bg-gray-700 mx-1"></div>
        <div id="swap-pill-2" class="flex items-center gap-1">
            <span class="w-5 h-5 rounded-full bg-gray-200 dark:bg-gray-700 inline-flex items-center justify-center text-[10px]">2</span>
            Location
        </div>
        <div class="flex-1 h-px bg-gray-200 dark:bg-gray-700 mx-1"></div>
        <div id="swap-pill-3" class="flex items-center gap-1">
            <span class="w-5 h-5 rounded-full bg-gray-200 dark:bg-gray-700 inline-flex items-center justify-center text-[10px]">3</span>
            Unit
        </div>
        <div class="flex-1 h-px bg-gray-200 dark:bg-gray-700 mx-1"></div>
        <div id="swap-pill-4" class="flex items-center gap-1">
            <span class="w-5 h-5 rounded-full bg-gray-200 dark:bg-gray-700 inline-flex items-center justify-center text-[10px]">4</span>
            Modem
        </div>
        <div class="flex-1 h-px bg-gray-200 dark:bg-gray-700 mx-1"></div>
        <div id="swap-pill-5" class="flex items-center gap-1">
            <span class="w-5 h-5 rounded-full bg-gray-200 dark:bg-gray-700 inline-flex items-center justify-center text-[10px]">5</span>
            Confirm
        </div>
    </div>

    <!-- Step 1: Project picker -->
    <div id="swap-step-1" class="bg-white dark:bg-slate-800 rounded-xl shadow-lg p-5 space-y-3">
        <label class="block">
            <span class="text-sm font-medium text-gray-700 dark:text-gray-300">Which project?</span>
            <input id="swap-project-search" type="search" autocomplete="off"
                   placeholder="Filter by number, client, or name…"
                   class="mt-2 w-full px-3 py-3 text-base border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-slate-700 text-gray-900 dark:text-white">
        </label>
        <div id="swap-project-list" class="max-h-96 overflow-y-auto space-y-1.5"></div>
    </div>

    <!-- Step 2: Location picker -->
    <div id="swap-step-2" class="hidden bg-white dark:bg-slate-800 rounded-xl shadow-lg p-5 space-y-3">
        <div class="flex items-center justify-between">
            <div class="min-w-0">
                <p class="text-xs text-gray-500 dark:text-gray-400">Project</p>
                <p class="font-semibold text-seismo-orange truncate" id="swap-project-label">—</p>
            </div>
            <button onclick="swapGoToStep(1)" class="text-xs text-gray-500 hover:text-seismo-orange whitespace-nowrap">Change</button>
        </div>
        <div>
            <p class="text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">Which location?</p>
            <div id="swap-location-list" class="max-h-96 overflow-y-auto space-y-1.5"></div>
        </div>
    </div>

    <!-- Step 3: New unit picker -->
    <div id="swap-step-3" class="hidden bg-white dark:bg-slate-800 rounded-xl shadow-lg p-5 space-y-3">
        <div class="flex items-center justify-between">
            <div class="min-w-0 flex-1">
                <p class="text-xs text-gray-500 dark:text-gray-400">Swapping at</p>
                <p class="font-semibold text-seismo-orange truncate" id="swap-location-label">—</p>
                <p class="text-xs text-gray-500 dark:text-gray-400 mt-1">
                    Out: <span id="swap-old-unit-label" class="font-mono">—</span>
                </p>
            </div>
            <button onclick="swapGoToStep(2)" class="text-xs text-gray-500 hover:text-seismo-orange whitespace-nowrap">Change</button>
        </div>
        <label class="block">
            <span class="text-sm font-medium text-gray-700 dark:text-gray-300">Incoming unit</span>
            <input id="swap-unit-search" type="search" autocomplete="off"
                   placeholder="Filter by serial…"
                   class="mt-2 w-full px-3 py-3 text-base border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-slate-700 text-gray-900 dark:text-white">
            <p class="text-xs text-gray-500 dark:text-gray-400 mt-1">Only seismographs without an active assignment.</p>
        </label>
        <div id="swap-unit-list" class="max-h-72 overflow-y-auto space-y-1.5"></div>
    </div>

    <!-- Step 4: Modem decision -->
    <div id="swap-step-4" class="hidden bg-white dark:bg-slate-800 rounded-xl shadow-lg p-5 space-y-4">
        <div class="flex items-center justify-between">
            <div class="min-w-0 flex-1">
                <p class="text-xs text-gray-500 dark:text-gray-400">Incoming</p>
                <p class="font-mono font-semibold text-seismo-orange" id="swap-new-unit-label">—</p>
            </div>
            <button onclick="swapGoToStep(3)" class="text-xs text-gray-500 hover:text-seismo-orange whitespace-nowrap">Change</button>
        </div>

        <div>
            <p class="text-sm font-medium text-gray-700 dark:text-gray-300 mb-2" id="swap-modem-question">Modem?</p>
            <div id="swap-modem-choice-list" class="space-y-2"></div>
        </div>

        <div id="swap-modem-picker-wrap" class="hidden">
            <label class="block">
                <span class="text-sm font-medium text-gray-700 dark:text-gray-300">Pick a modem</span>
                <input id="swap-modem-search" type="search" autocomplete="off"
                       placeholder="Filter modems…"
                       class="mt-2 w-full px-3 py-3 text-base border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-slate-700 text-gray-900 dark:text-white">
            </label>
            <div id="swap-modem-list" class="max-h-60 overflow-y-auto space-y-1.5 mt-2"></div>
        </div>

        <button id="swap-modem-next"
                onclick="swapAfterModem()"
                class="w-full px-4 py-3 bg-seismo-orange hover:bg-orange-600 text-white rounded-lg font-medium text-base disabled:opacity-50 disabled:cursor-not-allowed"
                disabled>
            Continue
        </button>
    </div>

    <!-- Step 5: Review + confirm -->
    <div id="swap-step-5" class="hidden bg-white dark:bg-slate-800 rounded-xl shadow-lg p-5 space-y-4">
        <h3 class="text-lg font-semibold text-gray-900 dark:text-white">Review the swap</h3>

        <dl class="text-sm space-y-2">
            <div class="flex justify-between gap-2">
                <dt class="text-gray-500 dark:text-gray-400">Project</dt>
                <dd class="text-right text-gray-900 dark:text-white font-medium truncate" id="swap-review-project">—</dd>
            </div>
            <div class="flex justify-between gap-2">
                <dt class="text-gray-500 dark:text-gray-400">Location</dt>
                <dd class="text-right text-gray-900 dark:text-white font-medium truncate" id="swap-review-location">—</dd>
            </div>
            <div class="border-t border-gray-200 dark:border-gray-700 pt-2 flex justify-between gap-2">
                <dt class="text-gray-500 dark:text-gray-400">Unit out</dt>
                <dd class="text-right font-mono text-gray-900 dark:text-white" id="swap-review-old-unit">—</dd>
            </div>
            <div class="flex justify-between gap-2">
                <dt class="text-gray-500 dark:text-gray-400">Unit in</dt>
                <dd class="text-right font-mono text-seismo-orange font-semibold" id="swap-review-new-unit">—</dd>
            </div>
            <div class="border-t border-gray-200 dark:border-gray-700 pt-2 flex justify-between gap-2">
                <dt class="text-gray-500 dark:text-gray-400">Modem out</dt>
                <dd class="text-right font-mono text-gray-900 dark:text-white" id="swap-review-old-modem">—</dd>
            </div>
            <div class="flex justify-between gap-2">
                <dt class="text-gray-500 dark:text-gray-400">Modem in</dt>
                <dd class="text-right font-mono text-seismo-orange font-semibold" id="swap-review-new-modem">—</dd>
            </div>
        </dl>

        <label class="block">
            <span class="text-sm font-medium text-gray-700 dark:text-gray-300">Notes (optional)</span>
            <textarea id="swap-notes" rows="2"
                      placeholder="Reason for swap, anything to remember…"
                      class="mt-2 w-full px-3 py-2 text-base border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-slate-700 text-gray-900 dark:text-white"></textarea>
        </label>

        <div id="swap-error" class="hidden text-sm text-red-600"></div>

        <button id="swap-confirm-btn"
                onclick="swapConfirm()"
                class="w-full px-4 py-3 bg-seismo-orange hover:bg-orange-600 text-white rounded-lg font-medium text-base">
            Confirm swap
        </button>
        <button onclick="swapGoToStep(4)" class="w-full text-sm text-gray-500 hover:text-seismo-orange">← Back</button>
    </div>

    <!-- Step 6: Success + optional photo -->
    <div id="swap-step-done" class="hidden bg-white dark:bg-slate-800 rounded-xl shadow-lg p-5 space-y-4">
        <div class="text-center">
            <div class="w-14 h-14 mx-auto rounded-full bg-green-100 dark:bg-green-900/30 flex items-center justify-center">
                <svg class="w-8 h-8 text-green-600 dark:text-green-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/>
                </svg>
            </div>
            <h3 class="text-lg font-semibold text-gray-900 dark:text-white mt-3">Swap complete</h3>
            <p class="text-sm text-gray-500 dark:text-gray-400 mt-1" id="swap-done-summary">—</p>
        </div>

        <div class="border-t border-gray-200 dark:border-gray-700 pt-4">
            <p class="text-sm font-medium text-gray-700 dark:text-gray-300">Add a photo of the new install?</p>
            <p class="text-xs text-gray-500 dark:text-gray-400 mt-1">Optional. EXIF GPS will populate the unit's coordinates.</p>
            <input id="swap-photo-input" type="file" accept="image/*" capture="environment"
                   onchange="swapOnPhotoPicked(event)"
                   class="mt-2 w-full text-sm text-gray-500 file:mr-4 file:py-3 file:px-4 file:rounded-lg file:border-0 file:text-sm file:font-semibold file:bg-seismo-orange file:text-white hover:file:bg-orange-600">
            <div id="swap-photo-preview-wrap" class="hidden mt-3">
                <img id="swap-photo-preview" class="w-full rounded-lg border border-gray-200 dark:border-gray-700" alt="">
            </div>
            <div id="swap-photo-error" class="hidden text-sm text-red-600 mt-2"></div>
            <div id="swap-photo-status" class="hidden text-sm text-green-600 mt-2"></div>
        </div>

        <div class="grid grid-cols-2 gap-2">
            <button id="swap-photo-upload-btn"
                    onclick="swapUploadPhoto()"
                    class="px-4 py-3 bg-seismo-orange hover:bg-orange-600 text-white rounded-lg font-medium disabled:opacity-50 disabled:cursor-not-allowed"
                    disabled>
                Upload photo
            </button>
            <button onclick="swapReset()"
                    class="px-4 py-3 border border-gray-300 dark:border-gray-600 hover:bg-gray-50 dark:hover:bg-gray-700 text-gray-700 dark:text-gray-300 rounded-lg font-medium">
                Done — another swap
            </button>
        </div>
    </div>
</div>

<script>
const _swap = {
    step: 1,
    project: null,        // { id, display, ... }
    location: null,       // { id, name, unit, modem }
    new_unit: null,       // { id, ... }
    modem_action: null,   // 'keep' | 'swap' | 'remove' | 'add' | 'none'
    new_modem: null,      // { id, ... }
    all_projects: [],
    all_units: [],
    all_modems: [],
    swap_result: null,
    photo_file: null,
    photo_preview_url: null,
};

function _esc(s) {
    if (s == null) return '';
    return String(s).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
}

function _badge(deployed) {
    return deployed
        ? '<span class="text-[10px] uppercase tracking-wider px-1.5 py-0.5 rounded bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-300">deployed</span>'
        : '<span class="text-[10px] uppercase tracking-wider px-1.5 py-0.5 rounded bg-amber-100 text-amber-800 dark:bg-amber-900/30 dark:text-amber-300">benched</span>';
}

function swapGoToStep(n) {
    _swap.step = n;
    for (let i = 1; i <= 5; i++) {
        const el = document.getElementById('swap-step-' + i);
        if (el) el.classList.toggle('hidden', i !== n);
        const pill = document.getElementById('swap-pill-' + i);
        if (!pill) continue;
        const dot = pill.querySelector('span');
        if (i === n) {
            pill.classList.remove('text-gray-500', 'dark:text-gray-400');
            pill.classList.add('text-seismo-orange', 'font-medium');
            dot.classList.remove('bg-gray-200', 'dark:bg-gray-700');
            dot.classList.add('bg-seismo-orange', 'text-white');
        } else if (i < n) {
            pill.classList.remove('text-gray-500', 'dark:text-gray-400');
            pill.classList.add('text-green-600', 'dark:text-green-400');
            dot.classList.remove('bg-gray-200', 'dark:bg-gray-700', 'bg-seismo-orange', 'text-white');
            dot.classList.add('bg-green-100', 'dark:bg-green-900/30', 'text-green-700', 'dark:text-green-300');
        } else {
            pill.classList.add('text-gray-500', 'dark:text-gray-400');
            pill.classList.remove('text-seismo-orange', 'font-medium', 'text-green-600', 'dark:text-green-400');
            dot.classList.add('bg-gray-200', 'dark:bg-gray-700');
            dot.classList.remove('bg-seismo-orange', 'text-white', 'bg-green-100', 'dark:bg-green-900/30', 'text-green-700', 'dark:text-green-300');
        }
    }
    document.getElementById('swap-step-done').classList.add('hidden');
}

// ── Step 1: project picker ──────────────────────────────────────────
async function _swapLoadProjects() {
    const list = document.getElementById('swap-project-list');
    list.innerHTML = '<p class="text-sm text-gray-500 dark:text-gray-400 px-3 py-2">Loading…</p>';
    try {
        const r = await fetch('/api/projects/search-json?limit=50');
        if (!r.ok) throw new Error('HTTP ' + r.status);
        _swap.all_projects = await r.json();
        _swapRenderProjects();
    } catch (e) {
        list.innerHTML = `<p class="text-sm text-red-500 px-3 py-2">Load failed: ${_esc(e.message)}</p>`;
    }
}

function _swapRenderProjects() {
    const q = document.getElementById('swap-project-search').value.trim().toLowerCase();
    const list = document.getElementById('swap-project-list');
    let items = _swap.all_projects;
    if (q) {
        items = items.filter(p => {
            const hay = [(p.project_number||''), (p.client_name||''), (p.name||''), (p.display||'')]
                .join(' ').toLowerCase();
            return hay.includes(q);
        });
    }
    if (items.length === 0) {
        list.innerHTML = '<p class="text-sm text-gray-500 dark:text-gray-400 px-3 py-2">No matching projects.</p>';
        return;
    }
    list.innerHTML = items.map(p => {
        const num = p.project_number ? `<span class="font-mono text-xs text-gray-500 dark:text-gray-400">${_esc(p.project_number)}</span>` : '';
        const client = p.client_name ? `<div class="text-xs text-gray-500 dark:text-gray-400 truncate">${_esc(p.client_name)}</div>` : '';
        return `<button onclick='swapPickProject(${JSON.stringify(p.id)})'
            class="w-full text-left px-3 py-3 rounded-lg border border-gray-200 dark:border-gray-700 hover:border-seismo-orange transition-colors">
            <div class="flex items-center justify-between gap-2">
                <span class="font-semibold text-gray-900 dark:text-white truncate">${_esc(p.name)}</span>
                ${num}
            </div>
            ${client}
        </button>`;
    }).join('');
}

function swapPickProject(projectId) {
    const p = _swap.all_projects.find(x => x.id === projectId);
    if (!p) return;
    _swap.project = p;
    document.getElementById('swap-project-label').textContent = p.name;
    _swapLoadLocations();
    swapGoToStep(2);
}

// ── Step 2: location picker ─────────────────────────────────────────
async function _swapLoadLocations() {
    const list = document.getElementById('swap-location-list');
    list.innerHTML = '<p class="text-sm text-gray-500 dark:text-gray-400 px-3 py-2">Loading…</p>';
    try {
        const r = await fetch(`/api/projects/${encodeURIComponent(_swap.project.id)}/locations-with-assignments?location_type=vibration`);
        if (!r.ok) throw new Error('HTTP ' + r.status);
        const data = await r.json();
        _swapRenderLocations(data);
    } catch (e) {
        list.innerHTML = `<p class="text-sm text-red-500 px-3 py-2">Load failed: ${_esc(e.message)}</p>`;
    }
}

function _swapRenderLocations(locations) {
    const list = document.getElementById('swap-location-list');
    if (!locations || locations.length === 0) {
        list.innerHTML = '<p class="text-sm text-gray-500 dark:text-gray-400 px-3 py-2">No vibration locations in this project.</p>';
        return;
    }
    list.innerHTML = locations.map(loc => {
        const unit = loc.unit;
        const modem = loc.modem;
        const unitLine = unit
            ? `<div class="text-xs text-gray-600 dark:text-gray-300 font-mono">${_esc(unit.id)}<span class="text-gray-400">${unit.unit_type ? ' · ' + _esc(unit.unit_type) : ''}</span></div>`
            : `<div class="text-xs italic text-gray-400">Empty — first assign</div>`;
        const modemLine = modem
            ? `<div class="text-[11px] text-gray-500 dark:text-gray-400 font-mono mt-0.5 flex items-center gap-2">
                 <span>+ modem ${_esc(modem.id)}</span>
                 ${_badge(modem.deployed)}
               </div>`
            : '';
        // Pass index for cleaner attribute escaping
        return `<button data-locidx="${locations.indexOf(loc)}" onclick="_swapPickLocationByIdx(this.dataset.locidx)"
            class="w-full text-left px-3 py-3 rounded-lg border border-gray-200 dark:border-gray-700 hover:border-seismo-orange transition-colors">
            <div class="flex items-center justify-between gap-2">
                <span class="font-semibold text-gray-900 dark:text-white truncate">${_esc(loc.name)}</span>
            </div>
            ${unitLine}
            ${modemLine}
        </button>`;
    }).join('');
    _swap._locations_cache = locations;
}

function _swapPickLocationByIdx(idxStr) {
    const idx = parseInt(idxStr, 10);
    const loc = _swap._locations_cache[idx];
    if (!loc) return;
    _swap.location = loc;
    document.getElementById('swap-location-label').textContent = loc.name;
    document.getElementById('swap-old-unit-label').textContent = loc.unit ? loc.unit.id : '(empty)';
    _swapLoadUnits();
    swapGoToStep(3);
}

// ── Step 3: incoming unit picker ────────────────────────────────────
async function _swapLoadUnits() {
    const list = document.getElementById('swap-unit-list');
    list.innerHTML = '<p class="text-sm text-gray-500 dark:text-gray-400 px-3 py-2">Loading…</p>';
    try {
        const r = await fetch(`/api/projects/${encodeURIComponent(_swap.project.id)}/available-units?location_type=vibration&include_benched=true`);
        if (!r.ok) throw new Error('HTTP ' + r.status);
        _swap.all_units = await r.json();
        _swapRenderUnits();
    } catch (e) {
        list.innerHTML = `<p class="text-sm text-red-500 px-3 py-2">Load failed: ${_esc(e.message)}</p>`;
    }
}

function _swapRenderUnits() {
    const q = document.getElementById('swap-unit-search').value.trim().toLowerCase();
    const list = document.getElementById('swap-unit-list');
    let items = _swap.all_units;
    if (q) {
        items = items.filter(u => {
            const hay = [(u.id||''), (u.model||''), (u.location||'')].join(' ').toLowerCase();
            return hay.includes(q);
        });
    }
    if (items.length === 0) {
        list.innerHTML = '<p class="text-sm text-gray-500 dark:text-gray-400 px-3 py-2">No available seismographs.</p>';
        return;
    }
    list.innerHTML = items.map(u => {
        const model = u.model ? `<span class="text-xs text-gray-500 dark:text-gray-400">${_esc(u.model)}</span>` : '';
        const loc = u.location ? `<div class="text-xs text-gray-500 dark:text-gray-400 truncate">${_esc(u.location)}</div>` : '';
        const badge = _badge(u.deployed);
        return `<button onclick='swapPickUnit(${JSON.stringify(u.id)})'
            class="w-full text-left px-3 py-3 rounded-lg border border-gray-200 dark:border-gray-700 hover:border-seismo-orange transition-colors">
            <div class="flex items-center justify-between gap-2">
                <span class="font-mono font-semibold text-gray-900 dark:text-white">${_esc(u.id)}</span>
                <div class="flex items-center gap-2">
                    ${badge}
                    ${model}
                </div>
            </div>
            ${loc}
        </button>`;
    }).join('');
}

function swapPickUnit(unitId) {
    const u = _swap.all_units.find(x => x.id === unitId);
    if (!u) return;
    _swap.new_unit = u;
    document.getElementById('swap-new-unit-label').textContent = u.id;
    _swapInitModemStep();
    swapGoToStep(4);
}

// ── Step 4: modem decision ──────────────────────────────────────────
function _swapInitModemStep() {
    _swap.modem_action = null;
    _swap.new_modem = null;
    document.getElementById('swap-modem-picker-wrap').classList.add('hidden');
    document.getElementById('swap-modem-next').disabled = true;

    const current = _swap.location && _swap.location.modem;
    const choices = document.getElementById('swap-modem-choice-list');
    const question = document.getElementById('swap-modem-question');

    if (current) {
        question.textContent = 'Modem at this location';
        choices.innerHTML = `
            <button data-action="keep" onclick="swapPickModemAction('keep')"
                class="swap-modem-choice w-full text-left px-3 py-3 rounded-lg border border-gray-200 dark:border-gray-700 hover:border-seismo-orange transition-colors">
                <div class="flex items-center justify-between gap-2">
                    <div class="font-medium text-gray-900 dark:text-white">Keep <span class="font-mono">${_esc(current.id)}</span></div>
                    ${_badge(current.deployed)}
                </div>
                <div class="text-xs text-gray-500 dark:text-gray-400">Re-pair the existing modem to the incoming unit.</div>
            </button>
            <button data-action="swap" onclick="swapPickModemAction('swap')"
                class="swap-modem-choice w-full text-left px-3 py-3 rounded-lg border border-gray-200 dark:border-gray-700 hover:border-seismo-orange transition-colors">
                <div class="font-medium text-gray-900 dark:text-white">Swap modem too</div>
                <div class="text-xs text-gray-500 dark:text-gray-400">Pick a different unassigned modem.</div>
            </button>
            <button data-action="remove" onclick="swapPickModemAction('remove')"
                class="swap-modem-choice w-full text-left px-3 py-3 rounded-lg border border-gray-200 dark:border-gray-700 hover:border-seismo-orange transition-colors">
                <div class="font-medium text-gray-900 dark:text-white">No modem</div>
                <div class="text-xs text-gray-500 dark:text-gray-400">Incoming unit goes solo (no cellular).</div>
            </button>`;
    } else {
        question.textContent = 'No modem at this location currently.';
        choices.innerHTML = `
            <button data-action="none" onclick="swapPickModemAction('none')"
                class="swap-modem-choice w-full text-left px-3 py-3 rounded-lg border border-gray-200 dark:border-gray-700 hover:border-seismo-orange transition-colors">
                <div class="font-medium text-gray-900 dark:text-white">No modem</div>
                <div class="text-xs text-gray-500 dark:text-gray-400">Standalone / manual download.</div>
            </button>
            <button data-action="add" onclick="swapPickModemAction('add')"
                class="swap-modem-choice w-full text-left px-3 py-3 rounded-lg border border-gray-200 dark:border-gray-700 hover:border-seismo-orange transition-colors">
                <div class="font-medium text-gray-900 dark:text-white">Add a modem</div>
                <div class="text-xs text-gray-500 dark:text-gray-400">Pair an unassigned modem with the incoming unit.</div>
            </button>`;
    }
}

function swapPickModemAction(action) {
    _swap.modem_action = action;
    _swap.new_modem = null;
    // Highlight the picked choice; dim the others.
    document.querySelectorAll('.swap-modem-choice').forEach(btn => {
        if (btn.dataset.action === action) {
            btn.classList.add('border-seismo-orange', 'bg-amber-50', 'dark:bg-amber-900/10');
        } else {
            btn.classList.remove('border-seismo-orange', 'bg-amber-50', 'dark:bg-amber-900/10');
        }
    });

    const pickerWrap = document.getElementById('swap-modem-picker-wrap');
    const nextBtn = document.getElementById('swap-modem-next');

    if (action === 'swap' || action === 'add') {
        pickerWrap.classList.remove('hidden');
        nextBtn.disabled = true;
        _swapLoadModems();
    } else {
        pickerWrap.classList.add('hidden');
        nextBtn.disabled = false;
    }
}

async function _swapLoadModems() {
    const list = document.getElementById('swap-modem-list');
    list.innerHTML = '<p class="text-sm text-gray-500 dark:text-gray-400 px-3 py-2">Loading…</p>';
    try {
        const r = await fetch(`/api/projects/${encodeURIComponent(_swap.project.id)}/available-modems?include_benched=true`);
        if (!r.ok) throw new Error('HTTP ' + r.status);
        // Filter out the modem that's currently at this location (it's the "keep" option, not "swap").
        let modems = await r.json();
        const currentModemId = _swap.location && _swap.location.modem ? _swap.location.modem.id : null;
        if (currentModemId) modems = modems.filter(m => m.id !== currentModemId);
        _swap.all_modems = modems;
        _swapRenderModems();
    } catch (e) {
        list.innerHTML = `<p class="text-sm text-red-500 px-3 py-2">Load failed: ${_esc(e.message)}</p>`;
    }
}

function _swapRenderModems() {
    const q = document.getElementById('swap-modem-search').value.trim().toLowerCase();
    const list = document.getElementById('swap-modem-list');
    let items = _swap.all_modems;
    if (q) {
        items = items.filter(m => {
            const hay = [(m.id||''), (m.hardware_model||''), (m.ip_address||'')].join(' ').toLowerCase();
            return hay.includes(q);
        });
    }
    if (items.length === 0) {
        list.innerHTML = '<p class="text-sm text-gray-500 dark:text-gray-400 px-3 py-2">No modems available.</p>';
        return;
    }
    list.innerHTML = items.map(m => {
        const hw = m.hardware_model ? `<span class="text-xs text-gray-500 dark:text-gray-400">${_esc(m.hardware_model)}</span>` : '';
        const ip = m.ip_address ? `<div class="text-xs text-gray-500 dark:text-gray-400 font-mono">${_esc(m.ip_address)}</div>` : '';
        const badge = _badge(m.deployed);
        return `<button onclick='swapPickModem(${JSON.stringify(m.id)})'
            class="swap-modem-pick w-full text-left px-3 py-3 rounded-lg border border-gray-200 dark:border-gray-700 hover:border-seismo-orange transition-colors"
            data-modem-id="${_esc(m.id)}">
            <div class="flex items-center justify-between gap-2">
                <span class="font-mono font-semibold text-gray-900 dark:text-white">${_esc(m.id)}</span>
                <div class="flex items-center gap-2">
                    ${badge}
                    ${hw}
                </div>
            </div>
            ${ip}
        </button>`;
    }).join('');
}

function swapPickModem(modemId) {
    const m = _swap.all_modems.find(x => x.id === modemId);
    if (!m) return;
    _swap.new_modem = m;
    document.querySelectorAll('.swap-modem-pick').forEach(btn => {
        if (btn.dataset.modemId === modemId) {
            btn.classList.add('border-seismo-orange', 'bg-amber-50', 'dark:bg-amber-900/10');
        } else {
            btn.classList.remove('border-seismo-orange', 'bg-amber-50', 'dark:bg-amber-900/10');
        }
    });
    document.getElementById('swap-modem-next').disabled = false;
}

function swapAfterModem() {
    // Populate review screen
    document.getElementById('swap-review-project').textContent = _swap.project.name;
    document.getElementById('swap-review-location').textContent = _swap.location.name;
    document.getElementById('swap-review-old-unit').textContent = _swap.location.unit ? _swap.location.unit.id : '(empty)';
    document.getElementById('swap-review-new-unit').textContent = _swap.new_unit.id;

    const oldModemEl = document.getElementById('swap-review-old-modem');
    if (_swap.location.modem) {
        oldModemEl.innerHTML = `${_esc(_swap.location.modem.id)} ${_badge(_swap.location.modem.deployed)}`;
    } else {
        oldModemEl.textContent = '(none)';
    }

    const newModemEl = document.getElementById('swap-review-new-modem');
    if (_swap.modem_action === 'keep' && _swap.location.modem) {
        newModemEl.innerHTML = `${_esc(_swap.location.modem.id)} <span class="text-xs text-gray-500">(kept)</span> ${_badge(_swap.location.modem.deployed)}`;
    } else if ((_swap.modem_action === 'swap' || _swap.modem_action === 'add') && _swap.new_modem) {
        newModemEl.innerHTML = `${_esc(_swap.new_modem.id)} ${_badge(_swap.new_modem.deployed)}`;
    } else {
        newModemEl.textContent = '(none)';
    }

    swapGoToStep(5);
}

// ── Step 5: confirm ─────────────────────────────────────────────────
async function swapConfirm() {
    const btn = document.getElementById('swap-confirm-btn');
    const err = document.getElementById('swap-error');
    err.classList.add('hidden');

    // Determine modem_id to send:
    //   'keep'   → current modem id  (re-pair to new unit)
    //   'swap'   → newly-picked modem id
    //   'add'    → newly-picked modem id
    //   'remove' → omit (endpoint clears new unit's pairing)
    //   'none'   → omit
    let modemIdToSend = null;
    if (_swap.modem_action === 'keep' && _swap.location.modem) {
        modemIdToSend = _swap.location.modem.id;
    } else if ((_swap.modem_action === 'swap' || _swap.modem_action === 'add') && _swap.new_modem) {
        modemIdToSend = _swap.new_modem.id;
    }

    btn.disabled = true;
    btn.textContent = 'Swapping…';

    const fd = new FormData();
    fd.append('unit_id', _swap.new_unit.id);
    if (modemIdToSend) fd.append('modem_id', modemIdToSend);
    const notes = document.getElementById('swap-notes').value.trim();
    if (notes) fd.append('notes', notes);

    try {
        const url = `/api/projects/${encodeURIComponent(_swap.project.id)}/locations/${encodeURIComponent(_swap.location.id)}/swap`;
        const r = await fetch(url, { method: 'POST', body: fd });
        if (!r.ok) {
            const e = await r.json().catch(() => ({detail: 'HTTP ' + r.status}));
            throw new Error(e.detail || 'HTTP ' + r.status);
        }
        _swap.swap_result = await r.json();
        _swapShowDone();
    } catch (e) {
        err.textContent = e.message;
        err.classList.remove('hidden');
        btn.disabled = false;
        btn.textContent = 'Confirm swap';
    }
}

function _swapShowDone() {
    for (let i = 1; i <= 5; i++) {
        document.getElementById('swap-step-' + i).classList.add('hidden');
    }
    document.getElementById('swap-step-done').classList.remove('hidden');
    const summary = `${_swap.new_unit.id} is now at ${_swap.location.name}` +
        (_swap.location.unit ? ` (replacing ${_swap.location.unit.id}).` : '.');
    document.getElementById('swap-done-summary').textContent = summary;
}

// ── Photo upload (optional) ─────────────────────────────────────────
function swapOnPhotoPicked(e) {
    const file = e.target.files && e.target.files[0];
    if (!file) return;
    _swap.photo_file = file;
    if (_swap.photo_preview_url) URL.revokeObjectURL(_swap.photo_preview_url);
    _swap.photo_preview_url = URL.createObjectURL(file);
    document.getElementById('swap-photo-preview').src = _swap.photo_preview_url;
    document.getElementById('swap-photo-preview-wrap').classList.remove('hidden');
    document.getElementById('swap-photo-upload-btn').disabled = false;
}

async function swapUploadPhoto() {
    if (!_swap.photo_file) return;
    const btn = document.getElementById('swap-photo-upload-btn');
    const err = document.getElementById('swap-photo-error');
    const ok  = document.getElementById('swap-photo-status');
    err.classList.add('hidden');
    ok.classList.add('hidden');
    btn.disabled = true;
    btn.textContent = 'Uploading…';

    const fd = new FormData();
    fd.append('photo', _swap.photo_file);

    try {
        const url = `/api/unit/${encodeURIComponent(_swap.new_unit.id)}/upload-photo?auto_populate_coords=true`;
        const r = await fetch(url, { method: 'POST', body: fd });
        if (!r.ok) {
            const e = await r.json().catch(() => ({detail: 'HTTP ' + r.status}));
            throw new Error(e.detail || 'HTTP ' + r.status);
        }
        const data = await r.json();
        const coords = data && data.metadata && data.metadata.coordinates;
        ok.textContent = coords ? `Uploaded. GPS: ${coords}` : 'Uploaded (no GPS in EXIF).';
        ok.classList.remove('hidden');
        btn.textContent = 'Uploaded';
    } catch (e) {
        err.textContent = e.message;
        err.classList.remove('hidden');
        btn.disabled = false;
        btn.textContent = 'Upload photo';
    }
}

function swapReset() {
    if (_swap.photo_preview_url) URL.revokeObjectURL(_swap.photo_preview_url);
    Object.assign(_swap, {
        project: null, location: null, new_unit: null,
        modem_action: null, new_modem: null,
        all_projects: [], all_units: [], all_modems: [],
        swap_result: null, photo_file: null, photo_preview_url: null,
    });
    document.getElementById('swap-project-search').value = '';
    document.getElementById('swap-unit-search').value = '';
    document.getElementById('swap-modem-search').value = '';
    document.getElementById('swap-notes').value = '';
    document.getElementById('swap-photo-input').value = '';
    document.getElementById('swap-photo-preview-wrap').classList.add('hidden');
    document.getElementById('swap-photo-error').classList.add('hidden');
    document.getElementById('swap-photo-status').classList.add('hidden');
    document.getElementById('swap-error').classList.add('hidden');
    const confirmBtn = document.getElementById('swap-confirm-btn');
    confirmBtn.disabled = false; confirmBtn.textContent = 'Confirm swap';
    const photoBtn = document.getElementById('swap-photo-upload-btn');
    photoBtn.disabled = true; photoBtn.textContent = 'Upload photo';
    swapGoToStep(1);
    _swapLoadProjects();
}

// Wire up live filtering inputs.
document.getElementById('swap-project-search').addEventListener('input', _swapRenderProjects);
document.getElementById('swap-unit-search').addEventListener('input', _swapRenderUnits);
document.getElementById('swap-modem-search').addEventListener('input', _swapRenderModems);

// Kick off.
_swapLoadProjects();
</script>
{% endblock %}
