import { TYPE_KEYS, WIDGET_DEFAULTS } from './constants';

export function typeKeyFor(type) {
    return TYPE_KEYS[type] || 'label';
}

export function invertLightness(hex) {
    const r = parseInt(hex.slice(1, 3), 16) / 255;
    const g = parseInt(hex.slice(3, 5), 16) / 255;
    const b = parseInt(hex.slice(5, 7), 16) / 255;
    const maxC = Math.max(r, g, b);
    const minC = Math.min(r, g, b);
    const delta = maxC - minC;
    let L = (maxC + minC) * 0.5;
    let S = 0, H = 0;
    if (delta > 0.0001) {
        S = L < 0.5 ? delta / (maxC + minC) : delta / (2 - maxC - minC);
        if (maxC === r)      H = ((g - b) / delta + (g < b ? 6 : 0)) / 6;
        else if (maxC === g) H = ((b - r) / delta + 2) / 6;
        else                 H = ((r - g) / delta + 4) / 6;
    }
    L = 1 - L;
    const hue2rgb = (p, q, t) => {
        if (t < 0) t += 1;
        if (t > 1) t -= 1;
        if (t < 1/6) return p + (q - p) * 6 * t;
        if (t < 1/2) return q;
        if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;
        return p;
    };
    let ro, go, bo;
    if (S < 0.0001) {
        ro = go = bo = L;
    } else {
        const q = L < 0.5 ? L * (1 + S) : L + S - L * S;
        const p = 2 * L - q;
        ro = hue2rgb(p, q, H + 1/3);
        go = hue2rgb(p, q, H);
        bo = hue2rgb(p, q, H - 1/3);
    }
    const toHex = v => Math.round(Math.max(0, Math.min(1, v)) * 255).toString(16).padStart(2, '0');
    return `#${toHex(ro)}${toHex(go)}${toHex(bo)}`;
}

export function clamp(value, min, max) {
    if (Number.isNaN(value)) return min;
    return Math.max(min, Math.min(max, value));
}

export function minSizeFor(widget) {
    const key = typeKeyFor(widget.type);
    if (key === 'button') return { w: 60, h: 30 };
    if (key === 'led') return { w: 20, h: 20 };
    if (key === 'icon') return { w: 24, h: 24 };
    if (key === 'tabview') return { w: 100, h: 100 };
    if (key === 'powerflow') return { w: 240, h: 180 };
    if (key === 'powernode') return { w: 70, h: 70 };
    if (key === 'powerlink') return { w: 1, h: 1 };
    if (key === 'chart') return { w: 160, h: 120 };
    if (key === 'roomcard') return { w: 120, h: 120 };
    if (key === 'rectangle') return { w: 40, h: 30 };
    if (key === 'arc') return { w: 80, h: 80 };
    if (key === 'buttonmatrix') return { w: 120, h: 60 };
    return { w: 40, h: 20 };
}

export function hexToRgba(hex, alpha) {
    const r = parseInt(hex.slice(1, 3), 16);
    const g = parseInt(hex.slice(3, 5), 16);
    const b = parseInt(hex.slice(5, 7), 16);
    return `rgba(${r},${g},${b},${alpha})`;
}

export function normalizeWidget(w, nextWidgetIdRef) {
    const key = typeKeyFor(w.type);
    const defaults = WIDGET_DEFAULTS[key];

    Object.keys(defaults).forEach((prop) => {
        if (prop === 'shadow' || prop === 'conditions') return;
        if (w[prop] === undefined || w[prop] === null) {
            w[prop] = defaults[prop];
        }
    });

    // Conditions: ensure each widget has its own array
    if (defaults.conditions !== undefined) {
        if (!Array.isArray(w.conditions)) {
            w.conditions = [];
        }
    }

    // SubButtons: ensure each widget has its own array
    if (defaults.subButtons !== undefined) {
        if (!Array.isArray(w.subButtons)) {
            w.subButtons = [];
        }
        // Ensure subButtonSize has a default
        if (w.subButtonSize === undefined || w.subButtonSize === null) {
            w.subButtonSize = defaults.subButtonSize || 40;
        }
        // Ensure subButtonDistance has a default
        if (w.subButtonDistance === undefined || w.subButtonDistance === null) {
            w.subButtonDistance = defaults.subButtonDistance || 80;
        }
        // Ensure subButtonOpacity has a default
        if (w.subButtonOpacity === undefined || w.subButtonOpacity === null) {
            w.subButtonOpacity = defaults.subButtonOpacity || 255;
        }
        // Ensure cardStyle has a default
        if (w.cardStyle === undefined || w.cardStyle === null) {
            w.cardStyle = defaults.cardStyle || 0;
        }
    }

    // TextLines: ensure each widget has its own array and each line has fontSize
    if (defaults.textLines !== undefined) {
        if (!Array.isArray(w.textLines)) {
            w.textLines = [];
        }
        // Ensure each textLine has a fontSize
        w.textLines.forEach(tl => {
            if (tl.fontSize === undefined || tl.fontSize === null) {
                tl.fontSize = 1;  // Default 18px
            }
        });
    }

    if (!w.shadow) {
        w.shadow = { ...defaults.shadow };
    } else {
        Object.keys(defaults.shadow).forEach((prop) => {
            if (w.shadow[prop] === undefined || w.shadow[prop] === null) {
                w.shadow[prop] = defaults.shadow[prop];
            }
        });
    }

    // Border style defaults (used by rectangle widget, harmless for others)
    if (w.borderWidth === undefined || w.borderWidth === null) {
        w.borderWidth = defaults.borderWidth ?? 0;
    }
    if (!w.borderColor) {
        w.borderColor = defaults.borderColor || '#ffffff';
    }
    if (w.borderOpacity === undefined || w.borderOpacity === null) {
        w.borderOpacity = defaults.borderOpacity ?? 0;
    }

    if (defaults.chart) {
        const maxSeries = 3;
        if (!w.chart) {
            w.chart = {
                period: defaults.chart.period ?? 0,
                series: (defaults.chart.series || []).map(s => ({ ...s }))
            };
        } else {
            if (w.chart.period === undefined || w.chart.period === null) {
                w.chart.period = defaults.chart.period ?? 0;
            }
            if (!Array.isArray(w.chart.series)) {
                w.chart.series = [];
            }
            if (w.chart.series.length === 0 && defaults.chart.series) {
                w.chart.series = defaults.chart.series.map(s => ({ ...s }));
            }
            for (let i = 0; i < w.chart.series.length && i < maxSeries; i++) {
                const fallback = (defaults.chart.series && defaults.chart.series[i]) || defaults.chart.series?.[0] || { knxAddr: 0, textSrc: 1, color: '#EF6351' };
                const entry = w.chart.series[i];
                if (entry.knxAddr === undefined || entry.knxAddr === null) entry.knxAddr = fallback.knxAddr;
                if (entry.textSrc === undefined || entry.textSrc === null) entry.textSrc = fallback.textSrc;
                if (!entry.color) entry.color = fallback.color;
            }
            if (w.chart.series.length > maxSeries) {
                w.chart.series = w.chart.series.slice(0, maxSeries);
            }
        }
    }

    if (w.visible === undefined || w.visible === null) w.visible = true;
    if (w.x === undefined || w.x === null) w.x = 100;
    if (w.y === undefined || w.y === null) w.y = 100;
    if (w.id === undefined || w.id === null) {
         if (nextWidgetIdRef) w.id = nextWidgetIdRef.value++;
    }
    // Action defaults
    if (w.action === undefined) w.action = 0; // BUTTON_ACTIONS.KNX
    if (w.targetScreen === undefined) w.targetScreen = 0;

    // Icon defaults
    if (w.iconCodepoint === undefined) w.iconCodepoint = defaults.iconCodepoint || 0;
    if (w.iconPosition === undefined) w.iconPosition = defaults.iconPosition || 0;
    if (w.iconSize === undefined) w.iconSize = defaults.iconSize || 1;
    if (w.iconGap === undefined) w.iconGap = defaults.iconGap || 8;
    if (w.iconPositionX === undefined) w.iconPositionX = defaults.iconPositionX || 0;
    if (w.iconPositionY === undefined) w.iconPositionY = defaults.iconPositionY || 0;
    
    // Hierarchy
    if (w.parentId === undefined) w.parentId = -1;

    if (key === 'button' && (w.isContainer === undefined || w.isContainer === null)) {
        w.isContainer = defaults.isContainer ?? false;
    }
}

export function normalizeScreen(screen, nextScreenIdRef, nextWidgetIdRef) {
    if (screen.id === undefined || screen.id === null) {
         if (nextScreenIdRef) screen.id = nextScreenIdRef.value++;
    }
    if (!screen.name) screen.name = `Screen ${screen.id}`;
    if (screen.mode === undefined || screen.mode === null) screen.mode = 0;
    if (!screen.bgColor) screen.bgColor = '#1A1A2E';
    if (!screen.nightBgColor) screen.nightBgColor = '#0E1217';
    if (screen.bgImage === undefined) screen.bgImage = '';
    if (screen.bgImageMode === undefined) screen.bgImageMode = 1;
    if (!Array.isArray(screen.widgets)) screen.widgets = [];

    // Modal defaults
    if (!screen.modal) {
        screen.modal = { x: 0, y: 0, w: 0, h: 0, radius: 12, dim: true };
    } else {
        if (screen.modal.x === undefined) screen.modal.x = 0;
        if (screen.modal.y === undefined) screen.modal.y = 0;
        if (screen.modal.w === undefined) screen.modal.w = 0;
        if (screen.modal.h === undefined) screen.modal.h = 0;
        if (screen.modal.radius === undefined) screen.modal.radius = 12;
        if (screen.modal.dim === undefined) screen.modal.dim = true;
    }

    screen.widgets.forEach(w => normalizeWidget(w, nextWidgetIdRef));
}
