<template>
  <BasePopup
    ref="basePopup"
    id="element-popup"
    :display-css="displayedCss"
    :editable-css="elementCss"
    :popup-width="800"
    :popup-height="600"
    :show-inheritance="false"
    @close="close"
    @css-input="handleCssInput"
  >
    <template #header-left>
      <span class="element-label">{{ selector || '' }}</span>
      <span class="instance-count">{{ elementInstanceCount }} instances</span>
    </template>

    <template #controls>
      <!-- Font Family -->
      <div class="settings-subsection" :class="{ 'setting-disabled': !settingEnabled.font }">
        <input type="checkbox" class="toggle-setting" :checked="settingEnabled.font" @change="onToggleSetting('font', $event.target.checked)" />
        <div class="field field-font">
          <label class="label-with-tooltip" data-css="font-family">Police</label>
          <div class="field-font__options">
            <select v-model="fontFamily">
              <option v-for="f in fonts" :key="f" :value="f">{{ f }}</option>
            </select>
            <div class="field-checkbox">
              <input type="checkbox" v-model="italic" />
              <label class="label-with-tooltip" data-css="font-style">Italique</label>
            </div>
            <div class="field-checkbox">
              <input type="checkbox" v-model="bold" />
              <label class="label-with-tooltip" data-css="font-weight">Gras</label>
            </div>
          </div>
        </div>
      </div>

      <!-- Font Size -->
      <div class="settings-subsection" :class="{ 'setting-disabled': !settingEnabled.fontSize }">
        <input type="checkbox" class="toggle-setting" :checked="settingEnabled.fontSize" @change="onToggleSetting('fontSize', $event.target.checked)" />
        <div class="field field-text-size">
          <label class="label-with-tooltip" data-css="font-size">Taille du texte</label>
          <InputWithUnit
            v-model="fontSizeModel"
            :units="['px']"
            :min="6"
            :max="72"
            showRange
          />
        </div>
      </div>

      <!-- LineHeight -->
      <div class="settings-subsection" :class="{ 'setting-disabled': !settingEnabled.lineHeight }">
        <input type="checkbox" class="toggle-setting" :checked="settingEnabled.lineHeight" @change="onToggleSetting('lineHeight', $event.target.checked)" />
        <div class="field field-text-size">
          <label class="label-with-tooltip" data-css="line-height">Interlignage</label>
          <InputWithUnit
            v-model="lineHeightModel"
            :units="['px']"
            :min="0"
            :max="72"
            showRange
          />
        </div>
      </div>

      <!-- Text Alignment -->
      <div class="settings-subsection" :class="{ 'setting-disabled': !settingEnabled.textAlign }">
        <input type="checkbox" class="toggle-setting" :checked="settingEnabled.textAlign" @change="onToggleSetting('textAlign', $event.target.checked)" />
        <div class="field">
          <label class="label-with-tooltip" data-css="text-align">Alignement</label>
          <select v-model="textAlign">
            <option value="left">Gauche</option>
            <option value="center">Centre</option>
            <option value="right">Droite</option>
            <option value="justify">Justifié</option>
          </select>
        </div>
      </div>

      <!-- Color -->
      <div class="settings-subsection" :class="{ 'setting-disabled': !settingEnabled.color }">
        <input type="checkbox" class="toggle-setting" :checked="settingEnabled.color" @change="onToggleSetting('color', $event.target.checked)" />
        <div class="field field-simple">
          <label class="label-with-tooltip" data-css="color">Couleur du texte</label>
          <div class="input-with-color">
            <input
              ref="colorInput"
              type="text"
              v-model="color"
              data-coloris
            />
          </div>
        </div>
      </div>

      <!-- Background -->
      <div class="settings-subsection" :class="{ 'setting-disabled': !settingEnabled.background }">
        <input type="checkbox" class="toggle-setting" :checked="settingEnabled.background" @change="onToggleSetting('background', $event.target.checked)" />
        <div class="field field-simple">
          <label class="label-with-tooltip" data-css="background">Arrière-plan</label>
          <div class="input-with-color">
            <input
              ref="backgroundInput"
              type="text"
              v-model="background"
              data-coloris
            />
          </div>
        </div>
      </div>

      <!-- Bordure -->
      <div class="settings-subsection" :class="{ 'setting-disabled': !settingEnabled.border }">
        <input type="checkbox" class="toggle-setting" :checked="settingEnabled.border" @change="onToggleSetting('border', $event.target.checked)" />
        <div class="field field-border">
          <div class="settings-subsection-header">
            <label class="label-with-tooltip" data-css="border">Bordure</label>
          </div>
          <div class="field-border__options">
            <div class="field-border__option">
              <label class="label-with-tooltip" data-css="border-width">Épaisseur</label>
              <div class="input-with-unit">
                <NumberInput
                  v-model="borderWidth.value"
                  :min="0"
                  :step="1"
                />
                <div class="unit-toggle">
                  <button type="button" class="active">px</button>
                </div>
              </div>
            </div>
            <div class="field-border__option">
              <label class="label-with-tooltip" data-css="border-style">Style</label>
              <select v-model="borderStyle">
                <option value="solid">Plein</option>
                <option value="dotted">Pointillés</option>
                <option value="dashed">Tirets</option>
                <option value="double">Double</option>
              </select>
            </div>
            <div class="field-border__option">
              <label class="label-with-tooltip" data-css="border-color">Couleur</label>
              <div class="input-with-color">
                <input
                  ref="borderColorInput"
                  type="text"
                  v-model="borderColor"
                  data-coloris
                />
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- Outer Margins -->
      <div class="settings-subsection" :class="{ 'setting-disabled': !settingEnabled.margin }">
        <input type="checkbox" class="toggle-setting" :checked="settingEnabled.margin" @change="onToggleSetting('margin', $event.target.checked)" />
        <div class="settings-subsection-header">
          <span class="label-with-tooltip" data-css="margin">Marges extérieures</span>
          <button
            type="button"
            class="lock-toggle"
            :class="{ locked: marginLocked }"
            @click="marginLocked = !marginLocked"
            :title="marginLocked ? 'Déverrouiller (modifier indépendamment)' : 'Verrouiller (modifier ensemble)'"
          >
            <svg v-if="marginLocked" width="11" height="13" viewBox="0 0 11 13" fill="none">
              <rect x="1" y="5.5" width="9" height="7" rx="1" fill="currentColor"/>
              <path d="M2.5 5.5V3.5a3 3 0 0 1 6 0v2" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
            </svg>
            <svg v-else width="11" height="13" viewBox="0 0 11 13" fill="none">
              <rect x="1" y="5.5" width="9" height="7" rx="1" fill="currentColor"/>
              <path d="M2.5 5.5V3.5a3 3 0 0 1 6 0" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
            </svg>
          </button>
        </div>
        <div
          v-for="side in sides"
          :key="side.key"
          class="field field-margin"
        >
          <label class="label-with-tooltip" :data-css="`margin-${side.key}`">{{ side.label }}</label>
          <div class="input-with-unit">
            <NumberInput
              :modelValue="margin[side.key].value"
              :min="0"
              :step="1"
              @update:modelValue="(v) => updateMarginValue(side.key, v)"
            />
            <div class="unit-toggle">
              <button
                type="button"
                :class="{ active: margin[side.key].unit === 'mm' }"
                @click="updateMarginUnit(side.key, 'mm')"
              >mm</button>
              <button
                type="button"
                :class="{ active: margin[side.key].unit === 'px' }"
                @click="updateMarginUnit(side.key, 'px')"
              >px</button>
            </div>
          </div>
        </div>
      </div>

      <!-- Inner Margins (Padding) -->
      <div class="settings-subsection" :class="{ 'setting-disabled': !settingEnabled.padding }">
        <input type="checkbox" class="toggle-setting" :checked="settingEnabled.padding" @change="onToggleSetting('padding', $event.target.checked)" />
        <div class="settings-subsection-header">
          <span class="label-with-tooltip" data-css="padding">Marges intérieures</span>
          <button
            type="button"
            class="lock-toggle"
            :class="{ locked: paddingLocked }"
            @click="paddingLocked = !paddingLocked"
            :title="paddingLocked ? 'Déverrouiller (modifier indépendamment)' : 'Verrouiller (modifier ensemble)'"
          >
            <svg v-if="paddingLocked" width="11" height="13" viewBox="0 0 11 13" fill="none">
              <rect x="1" y="5.5" width="9" height="7" rx="1" fill="currentColor"/>
              <path d="M2.5 5.5V3.5a3 3 0 0 1 6 0v2" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
            </svg>
            <svg v-else width="11" height="13" viewBox="0 0 11 13" fill="none">
              <rect x="1" y="5.5" width="9" height="7" rx="1" fill="currentColor"/>
              <path d="M2.5 5.5V3.5a3 3 0 0 1 6 0" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
            </svg>
          </button>
        </div>
        <div
          v-for="side in sides"
          :key="side.key"
          class="field field-margin"
        >
          <label class="label-with-tooltip" :data-css="`padding-${side.key}`">{{ side.label }}</label>
          <div class="input-with-unit">
            <NumberInput
              :modelValue="padding[side.key].value"
              :min="0"
              :step="1"
              @update:modelValue="(v) => updatePaddingValue(side.key, v)"
            />
            <div class="unit-toggle">
              <button
                type="button"
                :class="{ active: padding[side.key].unit === 'mm' }"
                @click="updatePaddingUnit(side.key, 'mm')"
              >mm</button>
              <button
                type="button"
                :class="{ active: padding[side.key].unit === 'px' }"
                @click="updatePaddingUnit(side.key, 'px')"
              >px</button>
            </div>
          </div>
        </div>
      </div>
    </template>
  </BasePopup>
</template>

<script setup>
import { ref, reactive, computed, watch, nextTick } from 'vue';
import { useStylesheetStore } from '../stores/stylesheet';
import { useDebounce } from '../composables/useDebounce';
import { useCssSync } from '../composables/useCssSync';
import { useTextDefaults } from '../composables/useTextDefaults';
import NumberInput from './ui/NumberInput.vue';
import InputWithUnit from './ui/InputWithUnit.vue';
import BasePopup from './ui/BasePopup.vue';
import { convertUnit } from '../utils/unit-conversion';

const stylesheetStore = useStylesheetStore();
const { extractValue: cssExtractValue, extractNumericValue } = useCssSync();
const textDefaults = useTextDefaults();

const props = defineProps({
  iframeRef: Object,
});

const emit = defineEmits(['close']);

const basePopup = ref(null);

const visible = computed(() => basePopup.value?.visible ?? false);

const selector = ref('');
const selectedElement = ref(null);
const elementInstanceCount = ref(0);
const colorInput = ref(null);
const backgroundInput = ref(null);
const borderColorInput = ref(null);

let isUpdatingFromStore = false;
const { debouncedUpdate } = useDebounce(500);

// Style properties — flat refs for simple values, reactive for value+unit
const fontFamily = ref('Alegreya Sans');
const italic = ref(false);
const bold = ref(false);
const textAlign = ref('left');
const color = ref('rgb(0, 0, 0)');
const background = ref('transparent');
const fontSize = reactive({ value: 23, unit: 'px' });
const fontSizeModel = computed({
  get: () => {
    if (!settingEnabled.fontSize) {
      // When disabled, display TextSettings' current value reactively
      return { ...textDefaults.fontSize };
    }
    return { value: fontSize.value, unit: fontSize.unit };
  },
  set: (v) => { fontSize.value = v.value; fontSize.unit = v.unit; },
});
const lineHeight = reactive({ value: 28, unit: 'px' });
const lineHeightModel = computed({
  get: () => ({ value: lineHeight.value, unit: lineHeight.unit }),
  set: (v) => { lineHeight.value = v.value; lineHeight.unit = v.unit; },
});
const borderWidth = reactive({ value: 1, unit: 'px' });
const borderStyle = ref('solid');
const borderColor = ref('#000000');

const marginLocked = ref(true);
const margin = reactive({
  top: { value: 0, unit: 'mm' },
  right: { value: 0, unit: 'mm' },
  bottom: { value: 0, unit: 'mm' },
  left: { value: 0, unit: 'mm' },
});

const paddingLocked = ref(true);
const padding = reactive({
  top: { value: 0, unit: 'mm' },
  right: { value: 0, unit: 'mm' },
  bottom: { value: 0, unit: 'mm' },
  left: { value: 0, unit: 'mm' },
});

// Cache for special groups values when unchecked (to restore on re-check)
const settingCache = reactive({
  font: null,     // { fontFamily, italic, bold }
  fontSize: null, // { value, unit }
  color: null,    // string
});

// Per-subsection toggle state
// Special groups (font, fontSize, color): checked by default
// Other groups: unchecked by default
const settingEnabled = reactive({
  font: true,
  fontSize: true,
  lineHeight: false,
  textAlign: false,
  color: true,
  background: false,
  border: false,
  margin: false,
  padding: false,
});

// Constants
const fonts = ['Alegreya Sans', 'Alegreya', 'Arial', 'Georgia', 'Times New Roman'];

// Style property descriptors (with group field)
const styleProps = [
  { css: 'font-family', group: 'font', get: () => fontFamily.value, set: v => fontFamily.value = v.replace(/['"]/g, ''), debounce: false },
  { css: 'font-style', group: 'font', get: () => italic.value ? 'italic' : 'normal', set: v => italic.value = v === 'italic', debounce: false, skipWhenDefault: v => v !== 'italic' },
  { css: 'font-weight', group: 'font', get: () => bold.value ? 'bold' : 'normal', set: v => bold.value = v === 'bold' || parseInt(v) >= 700, debounce: false, skipWhenDefault: v => v === 'normal' },
  { css: 'text-align', group: 'textAlign', get: () => textAlign.value, set: v => textAlign.value = v, debounce: false },
  { css: 'color', group: 'color', get: () => color.value, set: v => color.value = v, debounce: true },
  { css: 'background', group: 'background', get: () => background.value, set: v => background.value = v, debounce: true },
  { css: 'border-style', group: 'border', get: () => borderStyle.value, set: v => borderStyle.value = v || 'solid', debounce: false },
  { css: 'border-color', group: 'border', get: () => borderColor.value, set: v => borderColor.value = v, debounce: true },
];

const unitProps = [
  { css: 'font-size', group: 'fontSize', ref: fontSize, debounce: true },
  { css: 'line-height', group: 'lineHeight', ref: lineHeight, debounce: true },
  { css: 'border-width', group: 'border', ref: borderWidth, debounce: true },
];

const sides = [
  { key: 'top', label: 'Haut' },
  { key: 'bottom', label: 'Bas' },
  { key: 'left', label: 'Gauche' },
  { key: 'right', label: 'Droite' },
];

const updateMarginValue = (side, value) => {
  if (marginLocked.value) {
    for (const s of ['top', 'right', 'bottom', 'left']) margin[s].value = value;
  } else {
    margin[side].value = value;
  }
};

const updateMarginUnit = (side, unit) => {
  if (marginLocked.value) {
    for (const s of ['top', 'right', 'bottom', 'left']) {
      margin[s].value = convertUnit(margin[s].value, margin[s].unit, unit);
      margin[s].unit = unit;
    }
  } else {
    margin[side].value = convertUnit(margin[side].value, margin[side].unit, unit);
    margin[side].unit = unit;
  }
};

const updatePaddingValue = (side, value) => {
  if (paddingLocked.value) {
    for (const s of ['top', 'right', 'bottom', 'left']) padding[s].value = value;
  } else {
    padding[side].value = value;
  }
};

const updatePaddingUnit = (side, unit) => {
  if (paddingLocked.value) {
    for (const s of ['top', 'right', 'bottom', 'left']) {
      padding[s].value = convertUnit(padding[s].value, padding[s].unit, unit);
      padding[s].unit = unit;
    }
  } else {
    padding[side].value = convertUnit(padding[side].value, padding[side].unit, unit);
    padding[side].unit = unit;
  }
};

// CSS properties covered by each group
const settingGroups = {
  font:      ['font-family', 'font-style', 'font-weight'],
  fontSize:  ['font-size'],
  lineHeight:['line-height'],
  textAlign: ['text-align'],
  color:     ['color'],
  background:['background'],
  border:    ['border-width', 'border-style', 'border-color'],
  margin:    ['margin-top', 'margin-right', 'margin-bottom', 'margin-left'],
  padding:   ['padding-top', 'padding-right', 'padding-bottom', 'padding-left'],
};

// Remove CSS properties from the element's custom CSS block
const removeProps = (cssProps) => {
  if (!selector.value) return;

  const block = stylesheetStore.extractBlock(selector.value);
  if (!block || !stylesheetStore.customCss.includes(block)) return;

  let newBlock = block;
  for (const prop of cssProps) {
    const escaped = prop.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
    newBlock = newBlock.replace(
      new RegExp('[ \\t]*' + escaped + '\\s*:[^;]*;[ \\t]*\\n?', 'g'),
      ''
    );
  }

  // If the block is now empty, remove it entirely
  const inner = newBlock.replace(/^[^{]*\{/, '').replace(/\}[^}]*$/, '');
  if (!inner.trim()) {
    stylesheetStore.replaceInCustomCss(block, '');
  } else {
    stylesheetStore.replaceBlock(block, newBlock);
  }
};

// Generic update: push a single property to the stylesheet store
const updateProp = (cssProp, value, unit) => {
  if (!selector.value) return;
  stylesheetStore.updateProperty(selector.value, cssProp, value, unit);
};

const getSelectorFromElement = (element) => {
  if (element.id) {
    return `#${element.id}`;
  }

  const tagName = element.tagName.toLowerCase();

  const classes = Array.from(element.classList).filter(
    (cls) => !['element-hovered', 'element-selected', 'page-hovered', 'page-selected'].includes(cls)
  );
  if (classes.length > 0) {
    return `${tagName}.${classes[0]}`;
  }

  return tagName;
};

const getInstanceCount = (sel) => {
  if (!props.iframeRef || !props.iframeRef.contentDocument) return 0;

  try {
    return props.iframeRef.contentDocument.querySelectorAll(sel).length;
  } catch (e) {
    return 0;
  }
};

const elementCss = computed(() => {
  if (!selector.value) return '';
  return stylesheetStore.extractBlock(selector.value) || '';
});

const generatePreviewCss = () => {
  if (!selector.value) return '';

  const properties = [];

  for (const prop of styleProps) {
    if (!settingEnabled[prop.group]) continue;
    const val = prop.get();
    if (!val) continue;
    if (prop.css === 'font-style' && val !== 'italic') continue;
    if (prop.css === 'font-weight' && val === 'normal') continue;
    if ((prop.css === 'border-style' || prop.css === 'border-color') && borderWidth.value === 0) continue;
    properties.push(`  ${prop.css}: ${val};`);
  }

  for (const prop of unitProps) {
    if (!settingEnabled[prop.group]) continue;
    if (prop.ref.value !== undefined && prop.ref.value !== null) {
      properties.push(`  ${prop.css}: ${prop.ref.value}${prop.ref.unit};`);
    }
  }

  if (settingEnabled.margin) {
    for (const side of ['top', 'right', 'bottom', 'left']) {
      if (margin[side].value !== undefined && margin[side].value !== null) {
        properties.push(`  margin-${side}: ${margin[side].value}${margin[side].unit};`);
      }
    }
  }

  if (settingEnabled.padding) {
    for (const side of ['top', 'right', 'bottom', 'left']) {
      if (padding[side].value !== undefined && padding[side].value !== null) {
        properties.push(`  padding-${side}: ${padding[side].value}${padding[side].unit};`);
      }
    }
  }

  if (properties.length === 0) return '';

  return `${selector.value} {\n${properties.join('\n')}\n}`;
};

const displayedCss = computed(() => {
  if (!selector.value) return '';
  return elementCss.value || generatePreviewCss();
});

// Apply all properties for a given group to the stylesheet
const applyGroup = (group) => {
  if (!selector.value) return;

  for (const prop of styleProps) {
    if (prop.group !== group) continue;
    if (prop.skipWhenDefault && prop.skipWhenDefault(prop.get())) continue;
    updateProp(prop.css, prop.get());
  }
  for (const prop of unitProps) {
    if (prop.group === group) updateProp(prop.css, prop.ref.value, prop.ref.unit);
  }
  if (group === 'margin') {
    for (const side of ['top', 'right', 'bottom', 'left']) {
      updateProp(`margin-${side}`, margin[side].value, margin[side].unit);
    }
  }
  if (group === 'padding') {
    for (const side of ['top', 'right', 'bottom', 'left']) {
      updateProp(`padding-${side}`, padding[side].value, padding[side].unit);
    }
  }
};

// Apply all currently-enabled groups to keep the CSS block consistent
const applyAllEnabledGroups = () => {
  for (const group of Object.keys(settingEnabled)) {
    if (settingEnabled[group]) applyGroup(group);
  }
};

// When unchecking a special group: save element value, load TextSettings fallback for display
const saveToCacheAndLoadFallback = (group) => {
  if (group === 'fontSize') {
    settingCache.fontSize = { value: fontSize.value, unit: fontSize.unit };
    // Display is handled reactively by fontSizeModel computed
  } else if (group === 'font') {
    settingCache.font = { fontFamily: fontFamily.value, italic: italic.value, bold: bold.value };
    const ff = cssExtractValue('body', 'font-family');
    if (ff) fontFamily.value = ff.replace(/['"]/g, '');
    const fs = cssExtractValue('p', 'font-style');
    if (fs) italic.value = fs === 'italic';
    const fw = cssExtractValue('p', 'font-weight');
    if (fw) bold.value = fw === 'bold' || parseInt(fw) >= 700;
  } else if (group === 'color') {
    settingCache.color = color.value;
    const c = cssExtractValue('body', 'color');
    if (c) color.value = c;
  }
};

// When re-checking a special group: restore cached element value
const restoreFromCache = (group) => {
  if (group === 'fontSize' && settingCache.fontSize) {
    fontSize.value = settingCache.fontSize.value;
    fontSize.unit = settingCache.fontSize.unit;
    settingCache.fontSize = null;
  } else if (group === 'font' && settingCache.font) {
    fontFamily.value = settingCache.font.fontFamily;
    italic.value = settingCache.font.italic;
    bold.value = settingCache.font.bold;
    settingCache.font = null;
  } else if (group === 'color' && settingCache.color !== null) {
    color.value = settingCache.color;
    settingCache.color = null;
  }
};

// Toggle a setting group on/off
const onToggleSetting = (group, enabled) => {
  settingEnabled[group] = enabled;
  if (enabled) {
    isUpdatingFromStore = true;
    restoreFromCache(group);
    isUpdatingFromStore = false;
    applyAllEnabledGroups();
  } else {
    saveToCacheAndLoadFallback(group);
    removeProps(settingGroups[group]);
  }
};

// Watchers — simple props (with group guard)
for (const prop of styleProps) {
  watch(prop.get, () => {
    if (isUpdatingFromStore) return;
    if (!settingEnabled[prop.group]) return;
    const fn = () => updateProp(prop.css, prop.get());
    prop.debounce ? debouncedUpdate(fn) : fn();
  });
}

// Watchers — unit props (with group guard)
for (const prop of unitProps) {
  watch(() => prop.ref.value, () => {
    if (isUpdatingFromStore) return;
    if (!settingEnabled[prop.group]) return;
    const fn = () => updateProp(prop.css, prop.ref.value, prop.ref.unit);
    prop.debounce ? debouncedUpdate(fn) : fn();
  });
  watch(() => prop.ref.unit, () => {
    if (isUpdatingFromStore) return;
    if (!settingEnabled[prop.group]) return;
    updateProp(prop.css, prop.ref.value, prop.ref.unit);
  });
}

// Watchers — margin sides
watch(
  () => [margin.top.value, margin.right.value, margin.bottom.value, margin.left.value],
  () => {
    if (isUpdatingFromStore) return;
    if (!settingEnabled.margin) return;
    debouncedUpdate(() => {
      for (const side of ['top', 'right', 'bottom', 'left']) {
        updateProp(`margin-${side}`, margin[side].value, margin[side].unit);
      }
    });
  }
);
watch(
  () => [margin.top.unit, margin.right.unit, margin.bottom.unit, margin.left.unit],
  () => {
    if (isUpdatingFromStore) return;
    if (!settingEnabled.margin) return;
    for (const side of ['top', 'right', 'bottom', 'left']) {
      updateProp(`margin-${side}`, margin[side].value, margin[side].unit);
    }
  }
);

// Watchers — padding sides
watch(
  () => [padding.top.value, padding.right.value, padding.bottom.value, padding.left.value],
  () => {
    if (isUpdatingFromStore) return;
    if (!settingEnabled.padding) return;
    debouncedUpdate(() => {
      for (const side of ['top', 'right', 'bottom', 'left']) {
        updateProp(`padding-${side}`, padding[side].value, padding[side].unit);
      }
    });
  }
);
watch(
  () => [padding.top.unit, padding.right.unit, padding.bottom.unit, padding.left.unit],
  () => {
    if (isUpdatingFromStore) return;
    if (!settingEnabled.padding) return;
    for (const side of ['top', 'right', 'bottom', 'left']) {
      updateProp(`padding-${side}`, padding[side].value, padding[side].unit);
    }
  }
);

const handleCssInput = (newCss) => {
  const oldBlock = elementCss.value;
  if (oldBlock) {
    stylesheetStore.replaceInCustomCss(oldBlock, newCss);
  }
};

// Watch stylesheet changes to sync values
watch(
  () => stylesheetStore.customCss,
  () => {
    if (basePopup.value?.visible && !isUpdatingFromStore) {
      isUpdatingFromStore = true;
      loadValuesFromStylesheet();
      nextTick(() => { isUpdatingFromStore = false; });
    }
  }
);

// Also watch when exiting edit mode
watch(
  () => stylesheetStore.isEditing,
  (isEditing, wasEditing) => {
    if (basePopup.value?.visible && wasEditing && !isEditing && !isUpdatingFromStore) {
      isUpdatingFromStore = true;
      loadValuesFromStylesheet();
      nextTick(() => { isUpdatingFromStore = false; });
    }
  }
);

const loadValuesFromStylesheet = (isInitialLoad = false) => {
  if (!selector.value) return;

  if (isInitialLoad) {
    // Reset settingEnabled to defaults only on initial open
    settingEnabled.font = true;
    settingEnabled.fontSize = true;
    settingEnabled.lineHeight = false;
    settingEnabled.textAlign = false;
    settingEnabled.color = true;
    settingEnabled.background = false;
    settingEnabled.border = false;
    settingEnabled.margin = false;
    settingEnabled.padding = false;
  }

  const groupsFound = new Set();

  // Only detect settingEnabled from the custom CSS block (not baseCss fallback)
  const customCssBlock = (() => {
    const css = stylesheetStore.customCss;
    if (!css) return '';
    const escaped = selector.value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
    const match = new RegExp(escaped + '\\s*\\{([^}]*)\\}').exec(css);
    return match ? match[1] : '';
  })();
  const isInCustomCss = (cssProp) =>
    customCssBlock.includes(cssProp + ':') || customCssBlock.includes(cssProp + ' :');

  try {
    // Simple props
    for (const prop of styleProps) {
      const data = stylesheetStore.extractValue(selector.value, prop.css);
      if (data) {
        if (isInCustomCss(prop.css)) groupsFound.add(prop.group);
        // During live sync, don't overwrite refs for disabled groups (they show cached/fallback values)
        if (isInitialLoad || settingEnabled[prop.group]) {
          const value = typeof data === 'string' ? data : data.value;
          prop.set(value);
        }
      }
    }

    // Unit props
    for (const prop of unitProps) {
      const data = stylesheetStore.extractValue(selector.value, prop.css);
      if (data && data.value !== undefined) {
        if (isInCustomCss(prop.css)) groupsFound.add(prop.group);
        if (isInitialLoad || settingEnabled[prop.group]) {
          prop.ref.value = data.value;
          prop.ref.unit = data.unit;
        }
      }
    }

    // Margin sides — try individual first, fallback to shorthand
    const spacingSides = ['top', 'right', 'bottom', 'left'];
    let anyMarginFound = false;
    for (const side of spacingSides) {
      const data = stylesheetStore.extractValue(selector.value, `margin-${side}`);
      if (data && data.value !== undefined) {
        margin[side].value = data.value;
        margin[side].unit = data.unit;
        if (isInCustomCss(`margin-${side}`)) anyMarginFound = true;
      }
    }
    if (!anyMarginFound && isInCustomCss('margin')) {
      const data = stylesheetStore.extractValue(selector.value, 'margin');
      if (data && data.value !== undefined) {
        for (const side of spacingSides) {
          margin[side].value = data.value;
          margin[side].unit = data.unit;
        }
        anyMarginFound = true;
      }
    }
    if (anyMarginFound) groupsFound.add('margin');

    // Padding sides — try individual first, fallback to shorthand
    let anyPaddingFound = false;
    for (const side of spacingSides) {
      const data = stylesheetStore.extractValue(selector.value, `padding-${side}`);
      if (data && data.value !== undefined) {
        padding[side].value = data.value;
        padding[side].unit = data.unit;
        if (isInCustomCss(`padding-${side}`)) anyPaddingFound = true;
      }
    }
    if (!anyPaddingFound && isInCustomCss('padding')) {
      const data = stylesheetStore.extractValue(selector.value, 'padding');
      if (data && data.value !== undefined) {
        for (const side of spacingSides) {
          padding[side].value = data.value;
          padding[side].unit = data.unit;
        }
        anyPaddingFound = true;
      }
    }
    if (anyPaddingFound) groupsFound.add('padding');

    // Update settingEnabled based on what was found in the element's CSS
    if (isInitialLoad) {
      for (const group of ['lineHeight', 'textAlign', 'background', 'border', 'margin', 'padding']) {
        settingEnabled[group] = groupsFound.has(group);
      }
    } else {
      // During live sync: only enable groups newly found in CSS, never override user's manual toggles
      for (const group of Object.keys(settingEnabled)) {
        if (groupsFound.has(group)) settingEnabled[group] = true;
      }
    }

    // Special groups: font, fontSize, color — always enabled
    // If not found in element CSS, load fallback values from TextSettings selectors
    // Only on initial open — during live sync, ElementPopup is independent from TextSettings
    if (isInitialLoad) {
      if (!groupsFound.has('font')) {
        const ff = stylesheetStore.extractValue('body', 'font-family');
        if (ff) fontFamily.value = (typeof ff === 'string' ? ff : ff.value).replace(/['"]/g, '');
        const fs = stylesheetStore.extractValue('p', 'font-style');
        if (fs) italic.value = (typeof fs === 'string' ? fs : fs.value) === 'italic';
        const fw = stylesheetStore.extractValue('p', 'font-weight');
        if (fw) { const v = typeof fw === 'string' ? fw : fw.value; bold.value = v === 'bold' || parseInt(v) >= 700; }
      }

      if (!groupsFound.has('fontSize')) {
        const data = stylesheetStore.extractValue('p', 'font-size');
        if (data && data.value !== undefined) {
          fontSize.value = data.value;
          fontSize.unit = data.unit;
        }
      }

      if (!groupsFound.has('color')) {
        const c = stylesheetStore.extractValue('body', 'color');
        if (c) color.value = typeof c === 'string' ? c : c.value;
      }
    }

  } catch (error) {
    console.error('Error loading values from stylesheet:', error);
  }
};

const open = (element, event, count = null) => {
  // Clear cache from any previous element
  settingCache.font = null;
  settingCache.fontSize = null;
  settingCache.color = null;

  isUpdatingFromStore = true;

  selectedElement.value = element;
  selector.value = getSelectorFromElement(element);

  elementInstanceCount.value = count !== null ? count : getInstanceCount(selector.value);

  loadValuesFromStylesheet(true);
  basePopup.value.open(event);

  nextTick(() => { isUpdatingFromStore = false; });
};

const close = () => {
  basePopup.value?.close();
  selector.value = '';
  selectedElement.value = null;
  emit('close');
};

const handleIframeClick = (event, targetElement = null, elementCount = null) => {
  const element = targetElement || event.target;

  if (element.tagName === 'BODY' || element.tagName === 'HTML') {
    close();
    return;
  }

  if (basePopup.value?.visible) {
    close();
    return;
  }

  open(element, event, elementCount);
};

defineExpose({ handleIframeClick, close, visible });
</script>

<style scoped>
/* ElementPopup-specific styles (purple theme) */
.element-label {
  background: var(--color-purple);
  color: white;
  padding: 0.25rem 0.5rem;
  border-radius: 4px;
  font-size: 0.875rem;
  font-weight: 600;
}

.instance-count {
  color: var(--color-purple);
  font-size: 0.875rem;
}

.settings-subsection-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 0.25rem;
}

/* Toggle setting checkbox */
.toggle-setting {
  display: block;
  margin-bottom: 0.25rem;
  cursor: pointer;
  accent-color: var(--color-purple, #7c3aed);
}

/* Disabled state: grey out fields but keep checkbox interactive */
.setting-disabled .field,
.setting-disabled .settings-subsection-header {
  opacity: 0.4;
  pointer-events: none;
}

.lock-toggle {
  display: flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: 1px solid transparent;
  border-radius: 3px;
  cursor: pointer;
  padding: 2px 4px;
  color: var(--color-text-muted, #999);
  transition: color 0.15s, border-color 0.15s;
}

.lock-toggle:hover:not(:disabled) {
  color: var(--color-text, #333);
  border-color: var(--color-border, #ccc);
}

.lock-toggle.locked {
  color: var(--color-purple, #7c3aed);
}

.lock-toggle:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}
</style>
