/**
 * ImportMarksStore - Persists per-item import marks (skip / include) to localStorage.
 * Keyed by connectionId + platformType. Later will wire to DB.
 */
const ImportMarksStore = {
    getStorageKey(connectionId, platformType) {
        return `chameleonImportMarks_${platformType || 'Unknown'}_${connectionId || 0}`;
    },
    _readRaw(connectionId, platformType) {
        try {
            const key = this.getStorageKey(connectionId, platformType);
            const raw = localStorage.getItem(key);
            if (!raw) return { excluded: [], included: [] };
            const parsed = JSON.parse(raw);
            if (parsed && Array.isArray(parsed.excluded) && Array.isArray(parsed.included)) {
                return parsed;
            }
            if (Array.isArray(parsed)) {
                return { excluded: parsed, included: [] };
            }
            return { excluded: [], included: [] };
        } catch (e) {
            console.warn('ImportMarksStore._readRaw:', e);
            return { excluded: [], included: [] };
        }
    },
    _writeRaw(connectionId, platformType, data) {
        const key = this.getStorageKey(connectionId, platformType);
        localStorage.setItem(key, JSON.stringify({
            excluded: [...(data.excluded || [])],
            included: [...(data.included || [])]
        }));
    },
    getExcludedIds(connectionId, platformType) {
        const raw = this._readRaw(connectionId, platformType);
        return new Set(Array.isArray(raw.excluded) ? raw.excluded : []);
    },
    getIncludedIds(connectionId, platformType) {
        const raw = this._readRaw(connectionId, platformType);
        return new Set(Array.isArray(raw.included) ? raw.included : []);
    },
    getMarkState(connectionId, platformType, nodeId) {
        const id = String(nodeId || '');
        if (!id) return 'none';
        if (this.getExcludedIds(connectionId, platformType).has(id)) return 'excluded';
        if (this.getIncludedIds(connectionId, platformType).has(id)) return 'included';
        return 'none';
    },
    isExcluded(connectionId, platformType, nodeId) {
        return this.getMarkState(connectionId, platformType, nodeId) === 'excluded';
    },
    isIncluded(connectionId, platformType, nodeId) {
        return this.getMarkState(connectionId, platformType, nodeId) === 'included';
    },
    clearMark(connectionId, platformType, nodeId) {
        const id = String(nodeId || '');
        if (!id) return;
        const raw = this._readRaw(connectionId, platformType);
        const excluded = new Set(raw.excluded || []);
        const included = new Set(raw.included || []);
        excluded.delete(id);
        included.delete(id);
        this._writeRaw(connectionId, platformType, { excluded: [...excluded], included: [...included] });
    },
    setExcluded(connectionId, platformType, nodeId, excluded) {
        const id = String(nodeId || '');
        if (!id) return;
        const raw = this._readRaw(connectionId, platformType);
        const ex = new Set(raw.excluded || []);
        const inc = new Set(raw.included || []);
        if (excluded) {
            ex.add(id);
            inc.delete(id);
        } else {
            ex.delete(id);
        }
        this._writeRaw(connectionId, platformType, { excluded: [...ex], included: [...inc] });
    },
    setIncluded(connectionId, platformType, nodeId, included) {
        const id = String(nodeId || '');
        if (!id) return;
        const raw = this._readRaw(connectionId, platformType);
        const ex = new Set(raw.excluded || []);
        const inc = new Set(raw.included || []);
        if (included) {
            inc.add(id);
            ex.delete(id);
        } else {
            inc.delete(id);
        }
        this._writeRaw(connectionId, platformType, { excluded: [...ex], included: [...inc] });
    },
    toggleExcluded(connectionId, platformType, nodeId) {
        const id = String(nodeId || '');
        if (!id) return this.getExcludedIds(connectionId, platformType);
        const state = this.getMarkState(connectionId, platformType, id);
        if (state === 'excluded') this.setExcluded(connectionId, platformType, id, false);
        else this.setExcluded(connectionId, platformType, id, true);
        return this.getExcludedIds(connectionId, platformType);
    },
    toggleIncluded(connectionId, platformType, nodeId) {
        const id = String(nodeId || '');
        if (!id) return this.getIncludedIds(connectionId, platformType);
        const state = this.getMarkState(connectionId, platformType, id);
        if (state === 'included') this.setIncluded(connectionId, platformType, id, false);
        else this.setIncluded(connectionId, platformType, id, true);
        return this.getIncludedIds(connectionId, platformType);
    },
    getExcludedCount(connectionId, platformType) {
        return this.getExcludedIds(connectionId, platformType).size;
    },
    getIncludedCount(connectionId, platformType) {
        return this.getIncludedIds(connectionId, platformType).size;
    },
    /** After a Custom JSON file is removed from disk: drop marks for that file and virtual JSON tree nodes under it. */
    removeStaleAfterCustomJsonFileDeleted(connectionId, platformType, physicalFileNodeId) {
        const nid = String(physicalFileNodeId || '');
        if (!nid.startsWith('f|')) return;
        const rel = nid.slice(2);
        if (!rel) return;
        const raw = this._readRaw(connectionId, platformType);
        const jPrefix = 'j|' + rel + '|';
        const strip = function(set) {
            let changed = false;
            for (const id of [...set]) {
                const s = String(id);
                if (s === nid || s.startsWith(jPrefix)) {
                    set.delete(id);
                    changed = true;
                }
            }
            return changed;
        };
        const excluded = new Set(raw.excluded || []);
        const included = new Set(raw.included || []);
        const changed = strip(excluded) | strip(included);
        if (changed) {
            this._writeRaw(connectionId, platformType, { excluded: [...excluded], included: [...included] });
        }
    },
    emitUpdated(vueRoot) {
        if (vueRoot && vueRoot.$emit) {
            vueRoot.$emit('import-marks-updated');
            vueRoot.$emit('excluded-updated');
        }
    }
};

/** Back-compat alias used across the app. */
const ExcludedStore = {
    getStorageKey: function(c, p) { return ImportMarksStore.getStorageKey(c, p); },
    getExcludedIds: function(c, p) { return ImportMarksStore.getExcludedIds(c, p); },
    setExcluded: function(c, p, id, ex) { return ImportMarksStore.setExcluded(c, p, id, ex); },
    toggleExcluded: function(c, p, id) { return ImportMarksStore.toggleExcluded(c, p, id); },
    isExcluded: function(c, p, id) { return ImportMarksStore.isExcluded(c, p, id); },
    getExcludedCount: function(c, p) { return ImportMarksStore.getExcludedCount(c, p); },
    removeStaleAfterCustomJsonFileDeleted: function(c, p, id) {
        return ImportMarksStore.removeStaleAfterCustomJsonFileDeleted(c, p, id);
    }
};
