<template>
    <div class="bm-container-style">
        <BreakpointSwitcher :value="breakpoint" @input="(b) => (breakpoint = b)" />

        <!-- Display mode -->
        <div class="bm-prop-panel">
            <div class="bm-prop-panel__title">Display</div>
            <div class="bm-cs-segmented">
                <button
                    v-for="mode in displayModes"
                    :key="mode.value"
                    type="button"
                    class="bm-rail-tab"
                    :class="{ 'is-active': effectiveDisplay === mode.value }"
                    @click="setDisplay(mode.value)"
                >{{ mode.label }}</button>
            </div>
        </div>

        <!-- Flex options -->
        <div v-if="effectiveDisplay === 'flex'" class="bm-prop-panel">
            <div class="bm-prop-panel__title">Flex</div>
            <div v-for="row in flexRows" :key="row.prop" class="bm-prop-row">
                <label class="bm-prop-row__label">{{ row.label }}</label>
                <TokenValueInput
                    :value="getProp('layout', row.prop)"
                    :tokens="tokens"
                    :token-types="row.tokenTypes || []"
                    :input="row.input"
                    :options="row.options || []"
                    @input="(v) => setProp('layout', row.prop, v)"
                />
            </div>
        </div>

        <!-- Grid options -->
        <div v-else-if="effectiveDisplay === 'grid'" class="bm-prop-panel">
            <div class="bm-prop-panel__title">Grid</div>
            <div v-for="row in gridRows" :key="row.prop" class="bm-prop-row">
                <label class="bm-prop-row__label">{{ row.label }}</label>
                <TokenValueInput
                    :value="getProp('layout', row.prop)"
                    :tokens="tokens"
                    :token-types="row.tokenTypes || []"
                    :input="row.input"
                    :options="row.options || []"
                    @input="(v) => setProp('layout', row.prop, v)"
                />
            </div>
        </div>

        <!-- Box, border, background, text — always shown -->
        <div v-for="group in boxGroups" :key="group.panel + group.title" class="bm-prop-panel">
            <div class="bm-prop-panel__title">{{ group.title }}</div>
            <div v-for="row in group.rows" :key="group.panel + row.prop" class="bm-prop-row">
                <label class="bm-prop-row__label">{{ row.label }}</label>
                <TokenValueInput
                    :value="getProp(group.panel, row.prop)"
                    :tokens="tokens"
                    :token-types="row.tokenTypes || []"
                    :input="row.input"
                    :options="row.options || []"
                    @input="(v) => setProp(group.panel, row.prop, v)"
                />
            </div>
        </div>
    </div>
</template>

<script>
import BreakpointSwitcher from '../designer/BreakpointSwitcher.vue';
import TokenValueInput from '../designer/TokenValueInput.vue';

export default {
    name: 'ContainerStylePanel',
    components: { BreakpointSwitcher, TokenValueInput },
    props: {
        // The instance's `style_props`: { base: { default: { [bp]: { [panel]: { [prop]: {token|raw} } } } } }
        value:  { type: Object, default: () => ({}) },
        tokens: { type: Array, default: () => [] },
    },
    data() {
        return {
            breakpoint: 'desktop',
            displayModes: [
                { label: 'Normal', value: 'block' },
                { label: 'Flex',   value: 'flex' },
                { label: 'Grid',   value: 'grid' },
            ],
            flexRows: [
                { prop: 'flex_direction',  label: 'Direction', input: 'select', options: ['row', 'column', 'row-reverse', 'column-reverse'] },
                { prop: 'flex_wrap',       label: 'Wrap',      input: 'select', options: ['nowrap', 'wrap', 'wrap-reverse'] },
                { prop: 'justify_content', label: 'Justify',   input: 'select', options: ['flex-start', 'center', 'flex-end', 'space-between', 'space-around', 'space-evenly'] },
                { prop: 'align_items',     label: 'Align',     input: 'select', options: ['stretch', 'flex-start', 'center', 'flex-end', 'baseline'] },
                { prop: 'align_content',   label: 'Align Content', input: 'select', options: ['stretch', 'flex-start', 'center', 'flex-end', 'space-between', 'space-around'] },
                { prop: 'gap',             label: 'Gap',       input: 'length+token', tokenTypes: ['length'] },
            ],
            gridRows: [
                { prop: 'columns',        label: 'Columns',       input: 'text' },
                { prop: 'gap',            label: 'Gap',           input: 'length+token', tokenTypes: ['length'] },
                { prop: 'grid_auto_flow', label: 'Flow',          input: 'select', options: ['row', 'column', 'dense'] },
                { prop: 'justify_items',  label: 'Justify Items', input: 'select', options: ['stretch', 'start', 'center', 'end'] },
                { prop: 'align_items',    label: 'Align Items',   input: 'select', options: ['stretch', 'start', 'center', 'end'] },
            ],
            boxGroups: [
                {
                    panel: 'box', title: 'Box', rows: [
                        { prop: 'width',     label: 'Width',     input: 'length+token', tokenTypes: ['length'] },
                        { prop: 'height',    label: 'Height',    input: 'length+token', tokenTypes: ['length'] },
                        { prop: 'padding_x', label: 'Padding X', input: 'length+token', tokenTypes: ['length'] },
                        { prop: 'padding_y', label: 'Padding Y', input: 'length+token', tokenTypes: ['length'] },
                        { prop: 'margin_x',  label: 'Margin X',  input: 'length+token', tokenTypes: ['length'] },
                        { prop: 'margin_y',  label: 'Margin Y',  input: 'length+token', tokenTypes: ['length'] },
                    ],
                },
                {
                    panel: 'border', title: 'Border', rows: [
                        { prop: 'border_width',  label: 'Width',  input: 'length+token', tokenTypes: ['length'] },
                        { prop: 'border_style',  label: 'Style',  input: 'select', options: ['none', 'solid', 'dashed', 'dotted'] },
                        { prop: 'border_color',  label: 'Color',  input: 'color+token', tokenTypes: ['color'] },
                        { prop: 'border_radius', label: 'Radius', input: 'length+token', tokenTypes: ['length'] },
                    ],
                },
                {
                    panel: 'background', title: 'Background', rows: [
                        { prop: 'color', label: 'Color', input: 'color+token', tokenTypes: ['color'] },
                    ],
                },
                {
                    panel: 'typography', title: 'Text', rows: [
                        { prop: 'color', label: 'Text Color', input: 'color+token', tokenTypes: ['color'] },
                    ],
                },
            ],
        };
    },
    computed: {
        // Display drives which layout group renders. Falls back to the desktop
        // value when the active breakpoint hasn't overridden it, then to Normal.
        effectiveDisplay() {
            const here = this.getPropAt(this.breakpoint, 'layout', 'display');
            if (here && here.raw) return here.raw;
            const desk = this.getPropAt('desktop', 'layout', 'display');
            if (desk && desk.raw) return desk.raw;
            return 'block';
        },
    },
    methods: {
        cellAt(bp) {
            const base = this.value && this.value.base ? this.value.base : {};
            const dflt = base.default || {};
            return dflt[bp] || {};
        },
        getPropAt(bp, panel, prop) {
            const cell = this.cellAt(bp);
            const p = cell[panel] || {};
            return p[prop] || {};
        },
        getProp(panel, prop) {
            return this.getPropAt(this.breakpoint, panel, prop);
        },
        setDisplay(mode) {
            this.setProp('layout', 'display', { raw: mode });
        },
        // Immutable nested write back to style_props, scoped to the active breakpoint.
        setProp(panel, prop, val) {
            const bp = this.breakpoint;
            const base = this.value && this.value.base ? { ...this.value.base } : {};
            const dflt = base.default ? { ...base.default } : {};
            const cell = dflt[bp] ? { ...dflt[bp] } : {};
            const panelObj = cell[panel] ? { ...cell[panel] } : {};

            if (val === null || val === undefined) {
                delete panelObj[prop];
            } else {
                panelObj[prop] = val;
            }

            if (Object.keys(panelObj).length === 0) {
                delete cell[panel];
            } else {
                cell[panel] = panelObj;
            }
            dflt[bp] = cell;
            base.default = dflt;

            this.$emit('input', { ...this.value, base });
        },
    },
};
</script>
