modules = []; // Modules that have been added to the stage
directions = []; // History of directions. Mainly for undo function
connect_x_history = []; // History of connections for undo
connect_y_history = []; // History of connections for undo
last_mod_history = []; // Easier to keep the last mod index in separate array

let layer = new Konva.Layer();
let bgLayer = new Konva.Layer();
let measureLayer = new Konva.Layer();

let stage = new Konva.Stage({
    container: 'container',
    width: window.innerWidth - 50,
    height: window.innerHeight,
});

let group = false;
let actual_slope = false;
let actualSlope = false;
let currentRise = 0;

let background = new Konva.Rect({
    x: 0,
    y: 0,
    width: stage.width(),
    height: stage.height(),
    fill: "white"
});

let measure = new Konva.Text({
    x: stage.width() / 2,
    y: 75,
    text: '',
    fontSize: 20,
    fontFamily: 'Calibri',
    fill: 'black'
});

let measure_bkg = new Konva.Rect({
    x: 0,
    y: 0,
    width: 0,
    height: 0,
    fill: 'white',
    stroke: 'white',
    strokeWidth: 0,
    draggable: false
});

bgLayer.add(background);
measureLayer.add(measure);

stage.add(bgLayer);
stage.add(layer);
stage.add(measureLayer);

let group_id = 0;
let last_x = 10;
let last_y = 10;
let last_mod = null;
let connect_x = 50;
let connect_y = 50;

let connect_dir = "S"; // Initial connection direction.  Need to start with one

let horizontal_dimension_selected = false;
let vertical_dimension_selected = false;
let restoringFromStorage = false;

// Guidance messages keyed by module type. Add new entries here to extend.
const GUIDANCE_MESSAGES = {
    empty:    'Begin with an entry module — Mod 6 is most commonly used for transitioning from the doorway to the ramp system.',
    entry:    'Select the next MOD based on the options listed below. To remove a MOD from your design, simply double click it.',
    section:  'Select the next MOD based on the options listed below. To remove a MOD from your design, simply double click it.',
    bridge:   'Select the next MOD based on the options listed below. To remove a MOD from your design, simply double click it.',
    platform: 'Select the next MOD based on the options listed below. To remove a MOD from your design, simply double click it.',
};

function updateGuidanceMessage() {
    var header = document.getElementById('guidance-message');
    var el     = document.getElementById('guidance-text');
    var hint   = document.getElementById('canvas-empty-hint');

    if (!last_mod || modules.length === 0) {
        if (header) header.style.display = 'none';
        if (hint)   hint.style.display   = 'block';
        return;
    }

    if (hint)   hint.style.display   = 'none';
    if (header) header.style.display = '';
    if (!el) return;

    var modId  = last_mod.replace(/^Module/, '').slice(0, -1);
    var modDef = MODULE_DEFS.find(function(m) { return m.id === modId; });
    el.textContent = (modDef && GUIDANCE_MESSAGES[modDef.type]) || GUIDANCE_MESSAGES.empty;
}

function toggleCompatibleModules() {
    if (typeof mod_name == "undefined") {
        mod_name = null;
    }

    document.querySelectorAll('.module-tab img').forEach(function(el) {
        let comp = isCompatible(el.id, mod_name, connect_dir);
        if (comp) { el.classList.add('compatible'); el.style.display = ''; }
        else { el.classList.remove('compatible'); el.style.display = 'none'; }
    });

    if (typeof adaCompliant !== 'undefined' && adaCompliant) {
        document.querySelectorAll('.module-tab img').forEach(function(el) {
            if (['3', '4', '9'].includes(el.dataset.modId)) {
                el.style.display = 'none';
                el.classList.remove('compatible');
            }
        });
        document.querySelectorAll('#tabs ul li[data-ada="non-compliant"]').forEach(function(li) {
            li.style.display = 'none';
        });
    }

    let tabsEl = document.getElementById('tabs');
    document.querySelectorAll('.module-tab').forEach(function(tab) {
        let menu = tabsEl.querySelector('li[data-mod="' + tab.id + '"]');
        if (!menu) return;
        if (tab.querySelectorAll('.compatible').length === 0) {
            menu.style.display = 'none';
        } else if (rampHasMod4v2() && tab.id === 'module-4v2') {
            menu.style.display = 'none';
        } else if (rampHasMod6() && tab.id === 'module-6') {
            menu.style.display = 'none';
        } else {
            menu.style.display = '';
        }
    });

    checkRampComplete();
    updateGuidanceMessage();
}

function checkRampComplete() {
    var banner = document.getElementById('ramp-complete-banner');
    var tabs   = document.getElementById('tabs');
    if (!banner) return;
    var noModsLeft = modules.length > 0 && Array.from(document.querySelectorAll('#tabs > ul > li')).every(function(li) {
        return li.style.display === 'none';
    });
    if (noModsLeft) {
        banner.classList.remove('dn');
        if (tabs) tabs.style.display = 'none';
    } else {
        banner.classList.add('dn');
        if (tabs) tabs.style.display = 'block';
    }
}

let moduleList = [];
function updateModuleList() {
    moduleList = [];
    window.modules.forEach(mod => {
        moduleList.push(mod['attrs']['name']);
    });
    localStorage.setItem('modules', JSON.stringify(moduleList));
}

function buildTabBar() {
    const tabs = document.getElementById('tabs');
    const ul   = document.createElement('ul');
    ul.className = 'bg-blue';

    MODULE_DEFS.forEach(function(mod) {
        const li = document.createElement('li');
        li.dataset.mod     = mod.tabId;
        li.dataset.modType = mod.type;
        if (mod.tooltip) li.dataset.tooltip = mod.tooltip;
        if (mod.ada)     li.dataset.ada     = mod.ada;

        const a         = document.createElement('a');
        a.href           = '#' + mod.tabId;
        const numSpan    = document.createElement('span');
        numSpan.className   = 'mod-num';
        numSpan.textContent = mod.num;
        const typeSpan   = document.createElement('span');
        typeSpan.className   = 'mod-type';
        typeSpan.textContent = mod.label;
        a.appendChild(numSpan);
        a.appendChild(typeSpan);
        if (mod.ada !== 'non-compliant') {
            const adaTag = document.createElement('span');
            adaTag.className = 'mod-ada-tag';
            adaTag.textContent = 'ADA';
            a.appendChild(adaTag);
        }
        li.appendChild(a);
        ul.appendChild(li);
    });

    tabs.appendChild(ul);

    MODULE_DEFS.forEach(function(mod) {
        const panel   = document.createElement('div');
        panel.className = 'tab module-tab';
        panel.id        = mod.tabId;

        const prefix = mod.imagePrefix || mod.id;

        mod.orientations.forEach(function(ori) {
            const img               = document.createElement('img');
            img.src                  = 'images/modules/' + prefix + ori.key + '.webp';
            img.alt                  = 'Module ' + mod.id + ori.key;
            img.id                   = 'Module' + mod.id + ori.key;
            img.className            = 'module-toolbar-image';
            img.dataset.modId        = mod.id;
            img.dataset.modType      = mod.type;
            img.dataset.modOrientation = ori.key;
            img.loading              = 'eager';
            img.width                = ori.width;
            img.height               = ori.height;
            panel.appendChild(img);
        });

        const hint = document.createElement('p');
        hint.className = 'f6 blue ma0 pa2 i';
        hint.style.gridColumn = '1 / -1';
        hint.textContent = 'Click on MOD to add to your design. Double click on a MOD in your design to remove it.';
        panel.appendChild(hint);

        tabs.appendChild(panel);
    });
}

document.getElementById('tabs').addEventListener('click', function(e) {
    const imgEl = e.target.closest('img.module-toolbar-image');
    if (!imgEl) return;

    const mod_name  = imgEl.id;
    const mod_image = imgEl.src;

    function doAdd() {
        var module = addModule(mod_name, mod_image, layer);
        if (module) {
            layer.add(module);
            toggleCompatibleModules();
            if (!restoringFromStorage) {
                drawRamp();
            }
            updateModuleList();
        }
    }

    if (imgEl.naturalWidth > 0) {
        doAdd();
    } else {
        imgEl.decode().catch(function() {}).then(doAdd);
    }
});

function initTabs(containerId, activeIndex) {
    const container = document.getElementById(containerId);
    const ul = container.querySelector(':scope > ul');
    const tabItems = Array.from(ul.querySelectorAll(':scope > li'));
    const panels = Array.from(container.querySelectorAll(':scope > .tab'));

    ul.classList.add('ui-tabs-nav');
    panels.forEach(p => p.classList.add('ui-tabs-panel'));

    function activateTab(index) {
        tabItems.forEach((item, i) => item.classList.toggle('ui-state-active', i === index));
        panels.forEach((panel, i) => { panel.style.display = i === index ? 'grid' : 'none'; });
    }

    tabItems.forEach((item, i) => {
        const link = item.querySelector('a');
        if (link) {
            link.addEventListener('click', e => {
                e.preventDefault();
                activateTab(i);
            });
        }
    });

    activateTab(activeIndex);
}

document.addEventListener('DOMContentLoaded', function() {
    var hint = document.createElement('div');
    hint.id = 'canvas-empty-hint';
    hint.textContent = GUIDANCE_MESSAGES.empty;
    document.getElementById('container').appendChild(hint);

    buildTabBar();
    document.getElementById('tabs').style.display = 'block';

    // Hide all tabs except "entry" units to start
    document.querySelectorAll('#tabs li').forEach(function(tab) {
        if (tab.dataset.modType && tab.dataset.modType !== 'entry') {
            tab.style.display = 'none';
        }
    });

    // active: 3 = module-4 (the default entry module)
    initTabs('tabs', 3);

    toggleCompatibleModules();
    checkRampLength();

    // Restore from localStorage — wait for each image to decode before replaying
    if (localStorage.getItem('modules')) {
        moduleList = JSON.parse(localStorage.getItem('modules'));

        const decodePromises = moduleList.map(mod => {
            const img = document.getElementById(mod);
            return img ? img.decode().catch(() => {}) : Promise.resolve();
        });

        Promise.all(decodePromises).then(() => {
            restoringFromStorage = true;
            moduleList.forEach(mod => {
                document.getElementById(mod).click();
            });
            restoringFromStorage = false;
            drawRamp();
        });
    }
});

let resizeTimer;
window.addEventListener('resize', function () {
    clearTimeout(resizeTimer);
    resizeTimer = setTimeout(function () {
        const w = window.innerWidth;
        const h = window.innerHeight;
        stage.width(w);
        stage.height(h);
        background.width(w);
        background.height(h);
        drawRamp();
    }, 150);
}, { passive: true });
