/**
 * Shared mutable state — all global variables live here.
 *
 * ES module `export let` creates live bindings: importers always see
 * the latest value.  But importers cannot reassign, so every variable
 * gets a setter function.
 */

import { DataCache } from './cache.js';

export let apiKey = null;
export function setApiKey(v) { apiKey = v; }

export let refreshInterval = null;
export function setRefreshInterval(v) { refreshInterval = v; }

export let kcTestAutoRefresh = null;
export function setKcTestAutoRefresh(v) { kcTestAutoRefresh = v; }

export let kcTestTargetId = null;
export function setKcTestTargetId(v) { kcTestTargetId = v; }

export let kcTestWs = null;
export function setKcTestWs(v) { kcTestWs = v; }

export let kcTestFps = 3;
export function setKcTestFps(v) { kcTestFps = v; }

export let _cachedDisplays = null;

export let _displayPickerCallback = null;
export function set_displayPickerCallback(v) { _displayPickerCallback = v; }

export let _displayPickerSelectedIndex = null;
export function set_displayPickerSelectedIndex(v) { _displayPickerSelectedIndex = v; }

// Calibration
export const calibrationTestState = {};

export const EDGE_TEST_COLORS = {
    top: [255, 0, 0],
    right: [0, 255, 0],
    bottom: [0, 100, 255],
    left: [255, 255, 0]
};

// Track logged errors to avoid console spam
export const loggedErrors = new Map();

// Device brightness cache
export let _deviceBrightnessCache = {};
export function set_deviceBrightnessCache(v) { _deviceBrightnessCache = v; }
export function updateDeviceBrightness(deviceId, value) {
    _deviceBrightnessCache = { ..._deviceBrightnessCache, [deviceId]: value };
}

// Discovery state
export let _discoveryScanRunning = false;
export function set_discoveryScanRunning(v) { _discoveryScanRunning = v; }

export let _discoveryCache = {};
export function set_discoveryCache(v) { _discoveryCache = v; }

// Streams / templates state
export let _cachedStreams = [];
export let _cachedPPTemplates = [];
export let _cachedCaptureTemplates = [];
export let _availableFilters = [];

export let availableEngines = [];
export function setAvailableEngines(v) { availableEngines = v; }

export let currentEditingTemplateId = null;
export function setCurrentEditingTemplateId(v) { currentEditingTemplateId = v; }

export let _streamNameManuallyEdited = false;
export function set_streamNameManuallyEdited(v) { _streamNameManuallyEdited = v; }

export let _streamModalPPTemplates = [];
export function set_streamModalPPTemplates(v) { _streamModalPPTemplates = v; }

export let _templateNameManuallyEdited = false;
export function set_templateNameManuallyEdited(v) { _templateNameManuallyEdited = v; }

// PP template state
export let _modalFilters = [];
export function set_modalFilters(v) { _modalFilters = v; }

export let _ppTemplateNameManuallyEdited = false;
export function set_ppTemplateNameManuallyEdited(v) { _ppTemplateNameManuallyEdited = v; }

// CSPT (Color Strip Processing Template) state
export let _csptModalFilters = [];
export function set_csptModalFilters(v) { _csptModalFilters = v; }

export let _csptNameManuallyEdited = false;
export function set_csptNameManuallyEdited(v) { _csptNameManuallyEdited = v; }

export let _stripFilters = [];

export let _cachedCSPTemplates = [];

// Stream test state
export let currentTestingTemplate = null;
export function setCurrentTestingTemplate(v) { currentTestingTemplate = v; }

export let _currentTestStreamId = null;
export function set_currentTestStreamId(v) { _currentTestStreamId = v; }

export let _currentTestPPTemplateId = null;
export function set_currentTestPPTemplateId(v) { _currentTestPPTemplateId = v; }

export let _lastValidatedImageSource = '';
export function set_lastValidatedImageSource(v) { _lastValidatedImageSource = v; }

// Target editor state
export let _targetEditorDevices = [];
export function set_targetEditorDevices(v) { _targetEditorDevices = v; }

// KC editor state
export let _kcNameManuallyEdited = false;
export function set_kcNameManuallyEdited(v) { _kcNameManuallyEdited = v; }

// KC WebSockets
export const kcWebSockets = {};

// LED Preview WebSockets
export const ledPreviewWebSockets = {};

// Tutorial state
export let activeTutorial = null;
export function setActiveTutorial(v) { activeTutorial = v; }

// Confirm modal
export let confirmResolve = null;
export function setConfirmResolve(v) { confirmResolve = v; }

// Loading guards
export let _dashboardLoading = false;
export function set_dashboardLoading(v) { _dashboardLoading = v; }

export let _sourcesLoading = false;
export function set_sourcesLoading(v) { _sourcesLoading = v; }

export let _automationsLoading = false;
export function set_automationsLoading(v) { _automationsLoading = v; }

// Dashboard poll interval (ms), persisted in localStorage
const _POLL_KEY = 'dashboard_poll_interval';
const _POLL_DEFAULT = 2000;
export let dashboardPollInterval = parseInt(localStorage.getItem(_POLL_KEY), 10) || _POLL_DEFAULT;
export function setDashboardPollInterval(v) {
    dashboardPollInterval = v;
    localStorage.setItem(_POLL_KEY, String(v));
}

// Pattern template editor state
export let patternEditorRects = [];
export function setPatternEditorRects(v) { patternEditorRects = v; }

export let patternEditorSelectedIdx = -1;
export function setPatternEditorSelectedIdx(v) { patternEditorSelectedIdx = v; }

export let patternEditorBgImage = null;
export function setPatternEditorBgImage(v) { patternEditorBgImage = v; }

export let patternCanvasDragMode = null;
export function setPatternCanvasDragMode(v) { patternCanvasDragMode = v; }

export let patternCanvasDragStart = null;
export function setPatternCanvasDragStart(v) { patternCanvasDragStart = v; }

export let patternCanvasDragOrigRect = null;
export function setPatternCanvasDragOrigRect(v) { patternCanvasDragOrigRect = v; }

export let patternEditorHoveredIdx = -1;
export function setPatternEditorHoveredIdx(v) { patternEditorHoveredIdx = v; }

export let patternEditorHoverHit = null;
export function setPatternEditorHoverHit(v) { patternEditorHoverHit = v; }

export const PATTERN_RECT_COLORS = [
    'rgba(76,175,80,0.35)', 'rgba(33,150,243,0.35)', 'rgba(255,152,0,0.35)',
    'rgba(156,39,176,0.35)', 'rgba(0,188,212,0.35)', 'rgba(244,67,54,0.35)',
    'rgba(255,235,59,0.35)', 'rgba(121,85,72,0.35)',
];
export const PATTERN_RECT_BORDERS = [
    '#4CAF50', '#2196F3', '#FF9800', '#9C27B0', '#00BCD4', '#F44336', '#FFEB3B', '#795548',
];

// Audio sources
export let _cachedAudioSources = [];
export let _cachedAudioTemplates = [];

export let availableAudioEngines = [];
export function setAvailableAudioEngines(v) { availableAudioEngines = v; }

export let currentEditingAudioTemplateId = null;
export function setCurrentEditingAudioTemplateId(v) { currentEditingAudioTemplateId = v; }

export let _audioTemplateNameManuallyEdited = false;
export function set_audioTemplateNameManuallyEdited(v) { _audioTemplateNameManuallyEdited = v; }

// Value sources
export let _cachedValueSources = [];

// Sync clocks
export let _cachedSyncClocks = [];

// Automations
export let _automationsCache = null;

// ─── DataCache instances ───────────────────────────────────────────
// Each cache syncs its data into the existing `export let` variable
// via a subscriber, preserving backward compatibility.

export const displaysCache = new DataCache({
    endpoint: '/config/displays',
    extractData: json => json.displays || [],
    defaultValue: null,
});
displaysCache.subscribe(v => { _cachedDisplays = v; });

export const streamsCache = new DataCache({
    endpoint: '/picture-sources',
    extractData: json => json.streams || [],
});
streamsCache.subscribe(v => { _cachedStreams = v; });

export const ppTemplatesCache = new DataCache({
    endpoint: '/postprocessing-templates',
    extractData: json => json.templates || [],
});
ppTemplatesCache.subscribe(v => { _cachedPPTemplates = v; });

export const captureTemplatesCache = new DataCache({
    endpoint: '/capture-templates',
    extractData: json => json.templates || [],
});
captureTemplatesCache.subscribe(v => { _cachedCaptureTemplates = v; });

export const audioSourcesCache = new DataCache({
    endpoint: '/audio-sources',
    extractData: json => json.sources || [],
});
audioSourcesCache.subscribe(v => { _cachedAudioSources = v; });

export const audioTemplatesCache = new DataCache({
    endpoint: '/audio-templates',
    extractData: json => json.templates || [],
});
audioTemplatesCache.subscribe(v => { _cachedAudioTemplates = v; });

export const valueSourcesCache = new DataCache({
    endpoint: '/value-sources',
    extractData: json => json.sources || [],
});
valueSourcesCache.subscribe(v => { _cachedValueSources = v; });

export const syncClocksCache = new DataCache({
    endpoint: '/sync-clocks',
    extractData: json => json.clocks || [],
});
syncClocksCache.subscribe(v => { _cachedSyncClocks = v; });

export const filtersCache = new DataCache({
    endpoint: '/filters',
    extractData: json => json.filters || [],
});
filtersCache.subscribe(v => { _availableFilters = v; });

export const automationsCacheObj = new DataCache({
    endpoint: '/automations',
    extractData: json => json.automations || [],
});
automationsCacheObj.subscribe(v => { _automationsCache = v; });

export const colorStripSourcesCache = new DataCache({
    endpoint: '/color-strip-sources',
    extractData: json => json.sources || [],
});

export const csptCache = new DataCache({
    endpoint: '/color-strip-processing-templates',
    extractData: json => json.templates || [],
});
csptCache.subscribe(v => { _cachedCSPTemplates = v; });

export const stripFiltersCache = new DataCache({
    endpoint: '/strip-filters',
    extractData: json => json.filters || [],
});
stripFiltersCache.subscribe(v => { _stripFilters = v; });

export const devicesCache = new DataCache({
    endpoint: '/devices',
    extractData: json => json.devices || [],
});

export const outputTargetsCache = new DataCache({
    endpoint: '/output-targets',
    extractData: json => json.targets || [],
});

export const patternTemplatesCache = new DataCache({
    endpoint: '/pattern-templates',
    extractData: json => json.templates || [],
});

export const scenePresetsCache = new DataCache({
    endpoint: '/scene-presets',
    extractData: json => json.presets || [],
});
