<template>
    <div class="avs">

        <!-- Toggle bar -->
        <div class="avs-toggle" :class="{ 'avs-toggle-open': expanded }" @click="togglePanel">
            <div class="avs-toggle-left">
                <span class="avs-toggle-icon">
                    <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-slideshow"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M15 6l.01 0" /><path d="M3 6a3 3 0 0 1 3 -3h12a3 3 0 0 1 3 3v8a3 3 0 0 1 -3 3h-12a3 3 0 0 1 -3 -3l0 -8" /><path d="M3 13l4 -4a3 5 0 0 1 3 0l4 4" /><path d="M13 12l2 -2a3 5 0 0 1 3 0l3 3" /><path d="M8 21l.01 0" /><path d="M12 21l.01 0" /><path d="M16 21l.01 0" /></svg>
                </span>
                <span class="avs-toggle-label">{{ headerLabel }}</span>
                <span v-if="activeCount > 0" class="avs-badge" :style="{ backgroundColor: color }">{{ activeCount }}</span>
            </div>
            <div class="avs-toggle-right">
                <button v-if="activeCount > 0" type="button" class="avs-btn-reset" @click.stop="resetAll" title="Resetear">
                    <svg xmlns="http://www.w3.org/2000/svg" width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 11a8.1 8.1 0 0 0 -15.5 -2m-.5 -4v4h4"/><path d="M4 13a8.1 8.1 0 0 0 15.5 2m.5 4v-4h-4"/></svg>
                </button>
                <svg class="avs-toggle-arrow" :class="{ 'avs-toggle-arrow-open': expanded }" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M6 9l6 6l6-6"/></svg>
            </div>
        </div>

        <!-- Panel -->
        <div v-if="rendered" v-show="expanded" class="avs-panel">

            <!-- Modo: Normal / Fade -->
            <div class="avs-mode-toggle">
                <button type="button" class="avs-mode-btn" :class="{ 'avs-mode-active': mode === 'normal' }" :style="mode === 'normal' ? { backgroundColor: color, borderColor: color } : {}" @click="setMode('normal')">
                    <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M5 12h2"/><path d="M17 12h2"/><path d="M11 12h2"/></svg>
                    Normal
                </button>
                <button type="button" class="avs-mode-btn" :class="{ 'avs-mode-active': mode === 'fade' }" :style="mode === 'fade' ? { backgroundColor: color, borderColor: color } : {}" @click="setMode('fade')">
                    <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M12 12m-3 0a3 3 0 1 0 6 0a3 3 0 1 0 -6 0"/><path d="M12 5l0 .5"/><path d="M12 18.5l0 .5"/><path d="M6.1 6.1l.35 .35"/><path d="M17.55 17.55l.35 .35"/><path d="M5 12l.5 0"/><path d="M18.5 12l.5 0"/><path d="M6.1 17.9l.35 -.35"/><path d="M17.55 6.45l.35 -.35"/></svg>
                    Fade
                </button>
            </div>

            <!-- PREVIEW VISUAL -->
            <div class="avs-preview">
                <div class="avs-preview-grid" :style="previewGridStyle">
                    <div v-for="i in previewCols" :key="i" class="avs-preview-block">
                        <div class="avs-preview-inner"></div>
                    </div>
                </div>
                <div class="avs-preview-dots">
                    <span v-for="i in 4" :key="i" class="avs-preview-dot" :style="i === 1 ? { backgroundColor: color } : {}"></span>
                </div>
            </div>

            <!-- COLUMNAS (solo normal) -->
            <div v-if="mode === 'normal'" class="avs-section">
                <span class="avs-section-label">Columnas en desktop</span>
                <div class="avs-row-buttons">
                    <button type="button" v-for="n in 4" :key="n" class="avs-btn" :class="{ 'avs-active': currentCols === n }" :style="currentCols === n ? { backgroundColor: color, color: '#fff', borderColor: color } : {}" @click="setCols(n)">
                        <span class="avs-btn-grid-icon">
                            <span v-for="c in n" :key="c" class="avs-col-pill"></span>
                        </span>
                        <span class="avs-btn-label">{{ n }}</span>
                    </button>
                </div>
            </div>

            <!-- GAP HORIZONTAL (solo normal) -->
            <div v-if="mode === 'normal'" class="avs-section">
                <span class="avs-section-label">Gap horizontal</span>
                <div class="avs-row-buttons">
                    <button type="button" class="avs-btn avs-btn-compact" :class="{ 'avs-active': !customGap && currentGap === 0 }" :style="!customGap && currentGap === 0 ? { backgroundColor: color, color: '#fff', borderColor: color } : {}" @click="setGap(0)">
                        <span class="avs-btn-label">Sin</span>
                    </button>
                    <button type="button" v-for="g in gapOpts" :key="g.value" class="avs-btn avs-btn-compact" :class="{ 'avs-active': !customGap && currentGap === g.value }" :style="!customGap && currentGap === g.value ? { backgroundColor: color, color: '#fff', borderColor: color } : {}" @click="setGap(g.value)">
                        <span class="avs-btn-label">{{ g.label }}</span>
                    </button>
                    <template v-if="editingCustomGap">
                        <input ref="inputGap" type="number" min="0" max="200" class="avs-inline-input" v-model.number="customGapValue" @keydown.enter.prevent="blurInputGap" @blur="confirmCustomGap" placeholder="px" />
                    </template>
                    <button v-else type="button" class="avs-btn avs-btn-compact" :class="{ 'avs-active': customGap }" :style="customGap ? { backgroundColor: color, color: '#fff', borderColor: color } : {}" @click="clickCustomGap">
                        <span class="avs-btn-label">{{ customGap ? customGapValue + 'px' : 'Custom' }}</span>
                    </button>
                </div>
            </div>

            <!-- ── DESPLEGABLE 1: AJUSTES AVANZADOS ── -->
            <button type="button" class="avs-advanced-toggle" @click="showAdvanced = !showAdvanced">
                <span>Ajustes avanzados</span>
                <svg class="avs-adv-arrow" :class="{ 'avs-adv-arrow-open': showAdvanced }" xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M6 9l6 6l6-6"/></svg>
            </button>

            <div v-if="showAdvanced" class="avs-advanced">

                <!-- AVANCE POR GRUPO (solo normal) -->
                <div v-if="mode === 'normal'" class="avs-section">
                    <span class="avs-section-label">Avance por</span>
                    <div class="avs-row-buttons">
                        <button type="button"
                            class="avs-btn avs-btn-compact"
                            :class="{ 'avs-active': currentPerGroup === currentCols, 'avs-disabled': false }"
                            :style="currentPerGroup === currentCols ? { backgroundColor: color, color: '#fff', borderColor: color } : {}"
                            @click="setPerGroup(currentCols)">
                            <span class="avs-btn-label">Paginas</span>
                        </button>
                        <button type="button" v-for="n in 4" :key="n"
                            class="avs-btn avs-btn-compact"
                            :class="{ 'avs-active': currentPerGroup === n && currentPerGroup !== currentCols, 'avs-disabled': n > currentCols }"
                            :style="currentPerGroup === n && currentPerGroup !== currentCols ? { backgroundColor: color, color: '#fff', borderColor: color } : {}"
                            :disabled="n > currentCols"
                            @click="n <= currentCols && setPerGroup(n)">
                            <span class="avs-btn-label">{{ n }} en {{ n }}</span>
                        </button>
                    </div>
                </div>

                <!-- LOOP + AUTOPLAY + PAUSA + REVERSE en fila flex-wrap -->
                <div class="avs-section">
                    <span class="avs-section-label">Opciones</span>
                    <div class="avs-toggles-row">
                        <div class="avs-toggle-item" v-if="mode === 'normal'">
                            <span class="avs-toggle-item-label">Loop</span>
                            <div class="avs-row-buttons">
                                <button type="button" class="avs-btn avs-btn-compact" :class="{ 'avs-active': !currentLoop, 'avs-disabled': currentPagination === 'scrollbar' }" :style="!currentLoop ? { backgroundColor: color, color: '#fff', borderColor: color } : {}" :disabled="currentPagination === 'scrollbar'" @click="currentPagination !== 'scrollbar' && setLoop(false)">
                                    <span class="avs-btn-label">No</span>
                                </button>
                                <button type="button" class="avs-btn avs-btn-compact" :class="{ 'avs-active': currentLoop, 'avs-disabled': currentPagination === 'scrollbar' }" :style="currentLoop ? { backgroundColor: color, color: '#fff', borderColor: color } : {}" :disabled="currentPagination === 'scrollbar'" @click="currentPagination !== 'scrollbar' && setLoop(true)">
                                    <span class="avs-btn-label">Si</span>
                                </button>
                            </div>
                        </div>
                        <div class="avs-toggle-item">
                            <span class="avs-toggle-item-label">Autoplay</span>
                            <div class="avs-row-buttons">
                                <button type="button" class="avs-btn avs-btn-compact" :class="{ 'avs-active': !currentAutoplay }" :style="!currentAutoplay ? { backgroundColor: color, color: '#fff', borderColor: color } : {}" @click="setAutoplay(false)">
                                    <span class="avs-btn-label">No</span>
                                </button>
                                <button type="button" class="avs-btn avs-btn-compact" :class="{ 'avs-active': currentAutoplay }" :style="currentAutoplay ? { backgroundColor: color, color: '#fff', borderColor: color } : {}" @click="setAutoplay(true)">
                                    <span class="avs-btn-label">Si</span>
                                </button>
                            </div>
                        </div>
                        <div class="avs-toggle-item" v-if="currentAutoplay">
                            <span class="avs-toggle-item-label">Pausa hover</span>
                            <div class="avs-row-buttons">
                                <button type="button" class="avs-btn avs-btn-compact" :class="{ 'avs-active': !currentAutoplayPause }" :style="!currentAutoplayPause ? { backgroundColor: color, color: '#fff', borderColor: color } : {}" @click="setAutoplayPause(false)">
                                    <span class="avs-btn-label">No</span>
                                </button>
                                <button type="button" class="avs-btn avs-btn-compact" :class="{ 'avs-active': currentAutoplayPause }" :style="currentAutoplayPause ? { backgroundColor: color, color: '#fff', borderColor: color } : {}" @click="setAutoplayPause(true)">
                                    <span class="avs-btn-label">Si</span>
                                </button>
                            </div>
                        </div>
                        <div class="avs-toggle-item" v-if="currentAutoplay">
                            <span class="avs-toggle-item-label">Al reves</span>
                            <div class="avs-row-buttons">
                                <button type="button" class="avs-btn avs-btn-compact" :class="{ 'avs-active': !currentAutoplayRev }" :style="!currentAutoplayRev ? { backgroundColor: color, color: '#fff', borderColor: color } : {}" @click="setAutoplayReverse(false)">
                                    <span class="avs-btn-label">No</span>
                                </button>
                                <button type="button" class="avs-btn avs-btn-compact" :class="{ 'avs-active': currentAutoplayRev }" :style="currentAutoplayRev ? { backgroundColor: color, color: '#fff', borderColor: color } : {}" @click="setAutoplayReverse(true)">
                                    <span class="avs-btn-label">Si</span>
                                </button>
                            </div>
                        </div>
                    </div>
                </div>

                <!-- INTERVALO AUTOPLAY (solo si autoplay activo) -->
                <div v-if="currentAutoplay" class="avs-section">
                    <span class="avs-section-label">Intervalo autoplay</span>
                    <div class="avs-row-buttons">
                        <button type="button" v-for="t in timeoutOpts" :key="t.value" class="avs-btn avs-btn-compact" :class="{ 'avs-active': !customTimeout && currentTimeout === t.value }" :style="!customTimeout && currentTimeout === t.value ? { backgroundColor: color, color: '#fff', borderColor: color } : {}" @click="setTimeout(t.value)">
                            <span class="avs-btn-label">{{ t.label }}</span>
                        </button>
                        <template v-if="editingCustomTimeout">
                            <input ref="inputTimeout" type="number" min="500" max="30000" step="500" class="avs-inline-input" v-model.number="customTimeoutValue" @keydown.enter.prevent="blurInputTimeout" @blur="confirmCustomTimeout" placeholder="ms" />
                        </template>
                        <button v-else type="button" class="avs-btn avs-btn-compact" :class="{ 'avs-active': customTimeout }" :style="customTimeout ? { backgroundColor: color, color: '#fff', borderColor: color } : {}" @click="clickCustomTimeout">
                            <span class="avs-btn-label">{{ customTimeout ? customTimeoutValue + 'ms' : 'Custom' }}</span>
                        </button>
                    </div>
                </div>

                <!-- VELOCIDAD -->
                <div class="avs-section">
                    <span class="avs-section-label">Velocidad transición (ms)</span>
                    <div class="avs-row-buttons">
                        <button type="button" v-for="s in speedOpts" :key="s.value" class="avs-btn avs-btn-compact" :class="{ 'avs-active': currentSpeed === s.value }" :style="currentSpeed === s.value ? { backgroundColor: color, color: '#fff', borderColor: color } : {}" @click="setSpeed(s.value)">
                            <span class="avs-btn-label">{{ s.label }}</span>
                        </button>
                    </div>
                </div>

                <!-- FLECHAS -->
                <div class="avs-section">
                    <span class="avs-section-label">Flechas de navegación</span>
                    <div class="avs-row-buttons">
                        <button type="button" class="avs-btn avs-btn-compact" :class="{ 'avs-active': !currentNav }" :style="!currentNav ? { backgroundColor: color, color: '#fff', borderColor: color } : {}" @click="setNav(false)">
                            <span class="avs-btn-label">No</span>
                        </button>
                        <button type="button" class="avs-btn avs-btn-compact" :class="{ 'avs-active': currentNav }" :style="currentNav ? { backgroundColor: color, color: '#fff', borderColor: color } : {}" @click="setNav(true)">
                            <span class="avs-btn-label">Si</span>
                        </button>
                    </div>
                </div>

                <!-- PAGINACION -->
                <div class="avs-section">
                    <span class="avs-section-label">Paginación</span>
                    <div class="avs-row-buttons">
                        <button type="button" v-for="p in paginationOpts" :key="p.value" class="avs-btn" :class="{ 'avs-active': currentPagination === p.value }" :style="currentPagination === p.value ? { backgroundColor: color, color: '#fff', borderColor: color } : {}" @click="setPagination(p.value)" :title="p.label">
                            <span v-html="p.icon"></span>
                            <span class="avs-btn-label">{{ p.label }}</span>
                        </button>
                    </div>
                </div>

                <!-- SCROLLBAR HIDE (solo scrollbar y modo normal) -->
                <div v-if="mode === 'normal' && currentPagination === 'scrollbar'" class="avs-section">
                    <span class="avs-section-label">Ocultar scrollbar al no interactuar</span>
                    <div class="avs-row-buttons">
                        <button type="button" class="avs-btn avs-btn-compact" :class="{ 'avs-active': !currentScrollbarHide }" :style="!currentScrollbarHide ? { backgroundColor: color, color: '#fff', borderColor: color } : {}" @click="setScrollbarHide(false)">
                            <span class="avs-btn-label">No</span>
                        </button>
                        <button type="button" class="avs-btn avs-btn-compact" :class="{ 'avs-active': currentScrollbarHide }" :style="currentScrollbarHide ? { backgroundColor: color, color: '#fff', borderColor: color } : {}" @click="setScrollbarHide(true)">
                            <span class="avs-btn-label">Si</span>
                        </button>
                    </div>
                </div>

            </div>

            <!-- ── DESPLEGABLE 2: BREAKPOINTS (solo normal) ── -->
            <template v-if="mode === 'normal'">
                <button type="button" class="avs-advanced-toggle" @click="showBreakpoints = !showBreakpoints">
                    <span>Breakpoints</span>
                    <svg class="avs-adv-arrow" :class="{ 'avs-adv-arrow-open': showBreakpoints }" xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M6 9l6 6l6-6"/></svg>
                </button>
                <div v-if="showBreakpoints" class="avs-advanced">
                    <p class="avs-advanced-hint">Auto usa el preset. Un breakpoint fijado manualmente es heredado por los superiores en Auto.</p>
                    <div v-for="bp in breakpoints" :key="bp.key" class="avs-section">
                        <span class="avs-section-label">{{ bp.label }}</span>
                        <div class="avs-row-buttons">
                            <button type="button" class="avs-btn avs-btn-compact" :class="{ 'avs-active': currentAdvanced[bp.key] === 0 }" :style="currentAdvanced[bp.key] === 0 ? { backgroundColor: color, color: '#fff', borderColor: color } : {}" @click="setAdvanced(bp.key, 0)">
                                <span class="avs-btn-label">Auto</span>
                            </button>
                            <button type="button" v-for="n in bp.max" :key="n" class="avs-btn avs-btn-compact" :class="{ 'avs-active': currentAdvanced[bp.key] === n }" :style="currentAdvanced[bp.key] === n ? { backgroundColor: color, color: '#fff', borderColor: color } : {}" @click="setAdvanced(bp.key, n)">
                                <span class="avs-btn-label">{{ n }}</span>
                            </button>
                        </div>
                    </div>
                </div>
            </template>

        </div>
    </div>
</template>

<script>
module.exports = {
    name: 'acai-vue-slider',
    props: {
        builder:              { default: null },
        data:                 { default: null },
        field:                { type: String, default: 'slider' },
        label:                { type: String, default: '' },
        color:                { type: String, default: '#3b82f6' },
        jsonField:            { type: String, default: '' },
        defaultCols:          { type: Number, default: 2 },
        defaultGap:           { type: Number, default: 2 },
        defaultPerGroup:      { type: Number, default: 1 },
        defaultLoop:          { type: Boolean, default: true },
        defaultAutoplay:      { type: Boolean, default: true },
        defaultTimeout:       { type: Number, default: 5000 },
        defaultAutoplayPause: { type: Boolean, default: true },
        defaultAutoplayRev:   { type: Boolean, default: false },
        defaultSpeed:         { type: Number, default: 600 },
        defaultNav:           { type: Boolean, default: true },
        defaultPagination:    { type: String, default: 'bullets' },
        defaultScrollbarHide: { type: Boolean, default: false },
    },
    data: function() {
        return {
            expanded:             false,
            rendered:             false,
            showAdvanced:         false,
            showBreakpoints:      false,
            mode:                 'normal',
            _skipWatch:           false,
            _saveTimer:           null,
            normal:               null,
            fade:                 null,
            customGap:            false,
            customGapValue:       0,
            editingCustomGap:     false,
            customTimeout:        false,
            customTimeoutValue:   5000,
            editingCustomTimeout: false,
            gapOpts: [
                { value: 1, label: 'XS' },
                { value: 2, label: 'SM' },
                { value: 3, label: 'MD' },
                { value: 4, label: 'LG' },
                { value: 5, label: 'XL' },
                { value: 6, label: '2XL' }
            ],
            timeoutOpts: [
                { value: 2000,  label: '2s' },
                { value: 3000,  label: '3s' },
                { value: 5000,  label: '5s' },
                { value: 8000,  label: '8s' },
                { value: 10000, label: '10s' }
            ],
            speedOpts: [
                { value: 200,  label: '200' },
                { value: 400,  label: '400' },
                { value: 600,  label: '600' },
                { value: 800,  label: '800' },
                { value: 1000, label: '1000' }
            ],
            paginationOpts: [
                {
                    value: 'none',
                    label: 'Ninguna',
                    icon: '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M3 3l18 18"/><path d="M3 21l18 -18"/></svg>'
                },
                {
                    value: 'bullets',
                    label: 'Dots',
                    icon: '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="6" cy="12" r="2" fill="currentColor"/><circle cx="12" cy="12" r="2" fill="currentColor"/><circle cx="18" cy="12" r="2" fill="currentColor"/></svg>'
                },
                {
                    value: 'fraction',
                    label: 'Fracción',
                    icon: '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-math-1-divide-3"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M10 15.5a.5 .5 0 0 1 .5 -.5h2a1.5 1.5 0 0 1 0 3h-1.167h1.167a1.5 1.5 0 0 1 0 3h-2a.5 .5 0 0 1 -.5 -.5" /><path d="M5 12h14" /><path d="M10 5l2 -2v6" /></svg>'
                },
                {
                    value: 'progressbar',
                    label: 'Barra',
                    icon: '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-percentage"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M16 17a1 1 0 1 0 2 0a1 1 0 1 0 -2 0" /><path d="M6 7a1 1 0 1 0 2 0a1 1 0 1 0 -2 0" /><path d="M6 18l12 -12" /></svg>'
                },
                {
                    value: 'scrollbar',
                    label: 'Scroll',
                    icon: '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-source-code"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M14.5 4h2.5a3 3 0 0 1 3 3v10a3 3 0 0 1 -3 3h-10a3 3 0 0 1 -3 -3v-5" /><path d="M6 5l-2 2l2 2" /><path d="M10 9l2 -2l-2 -2" /></svg>'
                }
            ],

            breakpoints: [
                { key: 'base', label: 'Móvil (base)', max: 2 },
                { key: 'sm',   label: 'SM - 640px',   max: 3 },
                { key: 'md',   label: 'MD - 768px',   max: 4 },
                { key: 'lg',   label: 'LG - 1024px',  max: 4 },
                { key: 'xl',   label: 'XL - 1280px',  max: 4 }
            ]
        };
    },
    computed: {
        defs: function() {
            return {
                normal: {
                    cols:          this.defaultCols,
                    gap:           this.defaultGap,
                    gapCustom:     0,
                    perGroup:      this.defaultPerGroup,
                    loop:          this.defaultLoop,
                    autoplay:      this.defaultAutoplay,
                    timeout:       this.defaultTimeout,
                    autoplayPause: this.defaultAutoplayPause,
                    autoplayRev:   this.defaultAutoplayRev,
                    speed:         this.defaultSpeed,
                    nav:           this.defaultNav,
                    pagination:    this.defaultPagination,
                    scrollbarHide: this.defaultScrollbarHide,
                    base: 0, sm: 0, md: 0, lg: 0, xl: 0
                },
                fade: {
                    autoplay:      this.defaultAutoplay,
                    timeout:       this.defaultTimeout,
                    autoplayPause: this.defaultAutoplayPause,
                    autoplayRev:   this.defaultAutoplayRev,
                    speed:         this.defaultSpeed,
                    nav:           this.defaultNav,
                    pagination:    this.defaultPagination
                }
            };
        },
        currentMode: function() {
            return this.mode === 'normal' ? this.normal : this.fade;
        },
        currentCols:          function() { return this.normal ? this.normal.cols          : this.defaultCols; },
        currentGap:           function() { return this.normal ? this.normal.gap           : this.defaultGap; },
        currentPerGroup:      function() { return this.normal ? (this.normal.perGroup || this.defaultPerGroup) : this.defaultPerGroup; },
        currentLoop:          function() { return this.normal ? this.normal.loop          : this.defaultLoop; },
        currentAutoplay:      function() { var m = this.currentMode; return m ? m.autoplay      : this.defaultAutoplay; },
        currentTimeout:       function() { var m = this.currentMode; return m ? m.timeout       : this.defaultTimeout; },
        currentAutoplayPause: function() { var m = this.currentMode; return m ? m.autoplayPause : this.defaultAutoplayPause; },
        currentAutoplayRev:   function() { var m = this.currentMode; return m ? m.autoplayRev   : this.defaultAutoplayRev; },
        currentSpeed:         function() { var m = this.currentMode; return m ? m.speed         : this.defaultSpeed; },
        currentNav:           function() { var m = this.currentMode; return m ? m.nav           : this.defaultNav; },
        currentPagination:    function() { var m = this.currentMode; return m ? m.pagination    : this.defaultPagination; },
        currentScrollbarHide: function() { return this.normal ? this.normal.scrollbarHide : this.defaultScrollbarHide; },
        currentAdvanced: function() {
            var m = this.normal || {};
            return { base: m.base || 0, sm: m.sm || 0, md: m.md || 0, lg: m.lg || 0, xl: m.xl || 0 };
        },
        activeCount: function() {
            if (!this.normal && !this.fade) return 0;
            var c = 0;
            var d = this.defs;
            var m = this.currentMode;
            if (!m) return 0;
            if (this.mode === 'normal') {
                var n = this.normal;
                if (n.cols !== d.normal.cols) c++;
                if (n.gapCustom > 0 || n.gap !== d.normal.gap) c++;
                if ((n.perGroup || 1) !== d.normal.perGroup) c++;
                if (n.loop !== d.normal.loop) c++;
            }
            if (m.autoplay !== (this.mode === 'normal' ? d.normal.autoplay : d.fade.autoplay)) c++;
            if (m.autoplay && m.timeout !== (this.mode === 'normal' ? d.normal.timeout : d.fade.timeout)) c++;
            if (m.speed !== (this.mode === 'normal' ? d.normal.speed : d.fade.speed)) c++;
            if (m.nav !== (this.mode === 'normal' ? d.normal.nav : d.fade.nav)) c++;
            if (m.pagination !== (this.mode === 'normal' ? d.normal.pagination : d.fade.pagination)) c++;
            if (this.mode === 'normal') {
                var bps = ['base', 'sm', 'md', 'lg', 'xl'];
                for (var i = 0; i < bps.length; i++) {
                    if ((this.normal[bps[i]] || 0) > 0) { c++; break; }
                }
            }
            return c;
        },
        headerLabel: function() {
            return this.label ? 'Slider: ' + this.label : 'Slider';
        },
        previewCols: function() {
            return this.mode === 'fade' ? 1 : Math.min(this.currentCols, 4);
        },
        previewGridStyle: function() {
            var gapPx = (this.customGap && this.customGapValue > 0)
                ? (this.customGapValue * 2) + 'px'
                : (this.currentGap * 8) + 'px';
            return { display: 'grid', gridTemplateColumns: 'repeat(' + this.previewCols + ', 1fr)', gap: gapPx };
        },
        fieldReady: function() {
            if (this.jsonField) return !!this.data && !!this.data[this.jsonField];
            var f = this.data && this.data[this.field];
            return f && f.newValues && f.newValues.builder_custom;
        }
    },
    watch: {
        data: {
            handler: function() { if (!this._skipWatch) this.loadData(); },
            deep: true, immediate: true
        }
    },
    beforeDestroy: function() {
        if (this._saveTimer) clearTimeout(this._saveTimer);
    },
    methods: {
        _makeNormal: function(overrides) {
            return Object.assign({}, this.defs.normal, overrides || {});
        },
        _makeFade: function(overrides) {
            return Object.assign({}, this.defs.fade, overrides || {});
        },
        _ensureMode: function() {
            if (!this.normal) this.normal = this._makeNormal();
            if (!this.fade)   this.fade   = this._makeFade();
        },
        setMode: function(m) {
            this.mode = m;
            this._syncCustomUI();
            this.save();
        },
        setCols: function(n) {
            this._ensureMode();
            this.normal.cols = n;
            // Si perGroup supera las nuevas columnas, resetear a 1
            if ((this.normal.perGroup || 1) > n) {
                this.normal.perGroup = 1;
            }
            this.save();
        },
        setGap: function(v) {
            this._ensureMode();
            this.customGap = false;
            this.editingCustomGap = false;
            this.normal.gap = v;
            this.normal.gapCustom = 0;
            this.save();
        },
        clickCustomGap: function() {
            this._ensureMode();
            if (this.customGap) {
                this.customGap = false;
                this.customGapValue = 0;
                this.normal.gapCustom = 0;
                this.save();
            } else {
                this.editingCustomGap = true;
                this.customGapValue = this.normal.gapCustom || 0;
                var self = this;
                this.$nextTick(function() {
                    if (self.$refs.inputGap) self.$refs.inputGap.focus();
                });
            }
        },
        blurInputGap: function() {
            if (this.$refs.inputGap) this.$refs.inputGap.blur();
        },
        confirmCustomGap: function() {
            if (!this.editingCustomGap) return;
            this.editingCustomGap = false;
            var v = parseInt(this.customGapValue) || 0;
            if (v > 0) {
                this.customGap = true;
                this.customGapValue = v;
                this.normal.gapCustom = v;
                this.save();
            } else {
                this.customGap = false;
                this.customGapValue = 0;
                this.normal.gapCustom = 0;
            }
        },
        setPerGroup: function(v) {
            this._ensureMode();
            this.normal.perGroup = v;
            this.save();
        },
        setLoop: function(v) {
            this._ensureMode();
            this.normal.loop = v;
            this.save();
        },
        setAutoplay: function(v) {
            this._ensureMode();
            this.currentMode.autoplay = v;
            this.save();
        },
        setTimeout: function(v) {
            this._ensureMode();
            this.customTimeout = false;
            this.editingCustomTimeout = false;
            this.currentMode.timeout = v;
            this.save();
        },
        clickCustomTimeout: function() {
            this._ensureMode();
            if (this.customTimeout) {
                this.customTimeout = false;
                this.customTimeoutValue = 5000;
                this.currentMode.timeout = 5000;
                this.save();
            } else {
                this.editingCustomTimeout = true;
                this.customTimeoutValue = this.currentMode.timeout || 5000;
                var self = this;
                this.$nextTick(function() {
                    if (self.$refs.inputTimeout) self.$refs.inputTimeout.focus();
                });
            }
        },
        blurInputTimeout: function() {
            if (this.$refs.inputTimeout) this.$refs.inputTimeout.blur();
        },
        confirmCustomTimeout: function() {
            if (!this.editingCustomTimeout) return;
            this.editingCustomTimeout = false;
            var v = parseInt(this.customTimeoutValue) || 5000;
            if (v >= 500) {
                this.customTimeout = true;
                this.customTimeoutValue = v;
                this.currentMode.timeout = v;
                this.save();
            } else {
                this.customTimeout = false;
                this.customTimeoutValue = 5000;
                this.currentMode.timeout = 5000;
            }
        },
        setAutoplayPause: function(v) {
            this._ensureMode();
            this.currentMode.autoplayPause = v;
            this.save();
        },
        setAutoplayReverse: function(v) {
            this._ensureMode();
            this.currentMode.autoplayRev = v;
            this.save();
        },
        setSpeed: function(v) {
            this._ensureMode();
            this.currentMode.speed = v;
            this.save();
        },
        setNav: function(v) {
            this._ensureMode();
            this.currentMode.nav = v;
            this.save();
        },
        setPagination: function(v) {
            this._ensureMode();
            this.currentMode.pagination = v;
            if (v === 'scrollbar' && this.mode === 'normal') {
                this.normal.loop = false;
            }
            this.save();
        },
        setScrollbarHide: function(v) {
            this._ensureMode();
            this.normal.scrollbarHide = v;
            this.save();
        },
        setAdvanced: function(bp, v) {
            this._ensureMode();
            this.normal[bp] = v;
            this.save();
        },
        _syncCustomUI: function() {
            if (this.mode === 'normal' && this.normal) {
                this.editingCustomGap = false;
                this.customGap = (this.normal.gapCustom || 0) > 0;
                this.customGapValue = this.normal.gapCustom || 0;
            }

            var m = this.currentMode;
            if (m) {
                this.editingCustomTimeout = false;
                var isPreset = this.timeoutOpts.some(function(t) { return t.value === m.timeout; });
                this.customTimeout = !isPreset;
                this.customTimeoutValue = m.timeout || 5000;
            }
        },
        loadData: function() {
            if (!this.fieldReady) return;
            var raw = '';
            if (this.jsonField) {
                var json = this._readJson();
                if (json[this.field]) raw = json[this.field];
            } else {
                raw = this.data[this.field].newValues.builder_custom.value || '';
            }
            if (!raw) return;
            try {
                var parsed = JSON.parse(raw);
                if (parsed.modo)   this.mode   = parsed.modo;
                if (parsed.normal) this.normal  = this._makeNormal(parsed.normal);
                if (parsed.fade)   this.fade    = this._makeFade(parsed.fade);
                this._syncCustomUI();
            } catch(e) {}
        },
        _initField: function() {
            // Si el campo no tiene newValues lo inicializa para poder guardar
            if (!this.data || !this.field) return;
            var f = this.data[this.field];
            if (!f) return;
            if (!f.newValues) {
                f.newValues = { builder_custom: { tableName: 'builder_custom', recordNum: null, value: '' } };
            } else if (!f.newValues.builder_custom) {
                f.newValues.builder_custom = { tableName: 'builder_custom', recordNum: null, value: '' };
            }
        },
        _doSave: function() {
            if (!this.fieldReady) this._initField();
            if (!this.fieldReady) return;
            this._ensureMode();
            var output = { modo: this.mode, normal: this.normal, fade: this.fade };
            var jsonStr = JSON.stringify(output);
            this._skipWatch = true;
            if (this.jsonField) {
                var json = this._readJson();
                json[this.field] = jsonStr;
                this._writeJson(json);
            } else {
                this.data[this.field].newValues.builder_custom.value = jsonStr;
            }
            this.$emit('save-data');
            if (typeof needToSave === 'function') needToSave();
            var self = this;
            this.$nextTick(function() { self._skipWatch = false; });
        },
        save: function() {
            this._ensureMode();
            var self = this;
            if (self._saveTimer) clearTimeout(self._saveTimer);
            self._saveTimer = setTimeout(function() {
                self._saveTimer = null;
                self._doSave();
            }, 180);
        },
        resetAll: function() {
            if (this.mode === 'normal') {
                this.normal = this._makeNormal();
            } else {
                this.fade = this._makeFade();
            }
            this.showAdvanced = false;
            this.showBreakpoints = false;
            this._syncCustomUI();
            this.save();
        },
        togglePanel: function() {
            if (this.expanded) { this.expanded = false; return; }
            if (!this.rendered) {
                this._ensureMode();
                this.rendered = true;
            }
            this.expanded = true;
        },
        _readJson: function() {
            if (!this.data || !this.jsonField) return {};
            var fd = this.data[this.jsonField];
            var raw = '';
            if (!fd) return {};
            if (typeof fd === 'string') raw = fd;
            else if (fd.newValues && fd.newValues.builder_custom) raw = fd.newValues.builder_custom.value || '';
            else if (fd.value) raw = fd.value;
            if (!raw) return {};
            try { return JSON.parse(raw); } catch(e) { return {}; }
        },
        _writeJson: function(json) {
            if (!this.data || !this.jsonField) return;
            var s = JSON.stringify(json);
            var fd = this.data[this.jsonField];
            if (fd && typeof fd === 'object') {
                fd.value = s;
                if (fd.newValues && fd.newValues.builder_custom) fd.newValues.builder_custom.value = s;
            }
        }
    }
};
</script>

<style scoped>
.avs { position: relative; width: 100%; }

.avs-toggle {
    display: flex; align-items: center; justify-content: space-between;
    width: 100%; padding: 10px 12px;
    background: #f3f4f6; border: 2px solid #4b5563; border-radius: 10px;
    cursor: pointer; transition: background 0.15s ease;
    min-height: 48px; box-sizing: border-box;
}
.avs-toggle:hover { background: #e5e7eb; }
.avs-toggle-open { border-radius: 10px 10px 0 0; }
.avs-toggle-left { display: flex; align-items: center; gap: 10px; }
.avs-toggle-icon { display: flex; align-items: center; color: #4b5563; }
.avs-toggle-label { font-size: 13px; font-weight: 700; color: #374151; letter-spacing: 0.03em; user-select: none; }
.avs-badge { font-size: 9px; font-weight: 700; color: #fff; padding: 2px 6px; border-radius: 10px; }
.avs-toggle-right { display: flex; align-items: center; gap: 6px; }
.avs-toggle-arrow { color: #6b7280; transition: transform 0.2s ease; }
.avs-toggle-arrow-open { transform: rotate(180deg); }
.avs-btn-reset { display: flex; align-items: center; justify-content: center; width: 28px; height: 28px; border: none; background: transparent; color: #ce5f5f; cursor: pointer; padding: 0; border-radius: 6px; }
.avs-btn-reset:hover { color: #dc2626; }

.avs-panel { border: 2px solid #4b5563; border-top: none; border-radius: 0 0 10px 10px; background: #f3f4f6; padding: 12px 0 0 0; overflow: hidden; }

.avs-mode-toggle { display: flex; gap: 0; margin: 0 12px 8px 12px; border: 1px solid #d1d5db; border-radius: 8px; overflow: hidden; }
.avs-mode-btn { flex: 1; display: flex; align-items: center; justify-content: center; gap: 6px; padding: 8px; border: none; background: #e5e7eb; cursor: pointer; font-size: 12px; font-weight: 600; color: #6b7280; transition: all 0.15s ease; }
.avs-mode-btn:hover { background: #d1d5db; }
.avs-mode-active { color: #ffffff !important; }

.avs-preview { margin: 0 12px 8px 12px; padding: 10px; background: #ffffff; border: 1px solid #d1d5db; border-radius: 8px; }
.avs-preview-grid { width: 100%; display: grid; gap: 4px; }
.avs-preview-inner { height: 28px; background: #e5e7eb; border-radius: 4px; }
.avs-preview-dots { display: flex; align-items: center; justify-content: center; gap: 4px; margin-top: 8px; }
.avs-preview-dot { width: 6px; height: 6px; border-radius: 50%; background: #d1d5db; display: inline-block; }

.avs-section { padding: 0px 12px; }
.avs-section-label { display: block; font-size: 10px; font-weight: 600; color: #6b7280; letter-spacing: 0.04em; text-transform: uppercase; margin-bottom: 6px; user-select: none; }

.avs-row-buttons { display: flex; gap: 0; border: 1px solid #d1d5db; border-radius: 6px; overflow: hidden; margin-bottom: 10px; }
.avs-btn { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px; padding: 8px 0; flex: 1; border: none; background: #e5e7eb; cursor: pointer; transition: background 0.15s ease; border-right: 1px solid #d1d5db; min-height: 46px; }
.avs-btn:last-child { border-right: none; }
.avs-btn:hover:not(.avs-active) { background: #d1d5db; }
.avs-btn-compact { min-height: 32px; padding: 6px 0; }
.avs-btn-label { font-size: 8px; font-weight: 600; color: #6b7280; line-height: 1; letter-spacing: 0.02em; user-select: none; }
.avs-active .avs-btn-label { color: #ffffff; }
.avs-active svg { stroke: #ffffff; }

.avs-btn-grid-icon { display: flex; gap: 2px; align-items: center; justify-content: center; height: 16px; }
.avs-col-pill { display: block; width: 4px; height: 14px; background: currentColor; border-radius: 2px; opacity: 0.7; }
.avs-active .avs-col-pill { background: #ffffff; opacity: 1; }

.avs-inline-input { flex: 1; border: none; border-left: 1px solid #d1d5db; background: #fff; outline: none; font-size: 11px; font-weight: 700; color: #374151; text-align: center; min-height: 32px; padding: 0 4px; min-width: 0; }

/* Fila flex-wrap para toggles compactos */
.avs-toggles-row { display: flex; flex-wrap: wrap; gap: 6px; }
.avs-toggle-item { flex: 1; min-width: 90px; }
.avs-toggle-item-label { display: block; font-size: 9px; font-weight: 600; color: #9ca3af; letter-spacing: 0.04em; text-transform: uppercase; margin-bottom: 4px; user-select: none; }

.avs-advanced-toggle { display: flex; align-items: center; justify-content: center; gap: 6px; width: 100%; padding: 8px 12px; margin: 2px 0 0 0; background: #4b5563; border: none; cursor: pointer; font-size: 11px; font-weight: 600; color: #ffffff; transition: background 0.15s ease; }
.avs-advanced-toggle:hover { background: #374151; }
.avs-adv-arrow { color: #ffffff; transition: transform 0.2s ease; }
.avs-adv-arrow-open { transform: rotate(180deg); }
.avs-advanced { padding-top: 8px; padding-bottom: 8px; }
.avs-advanced-hint { font-size: 10px; color: #9ca3af; text-align: center; padding: 0 12px 6px 12px; margin: 0; }
.avs-disabled { opacity: 0.35; cursor: not-allowed !important; }
.avs-disabled:hover { background: #e5e7eb !important; }
</style>