<template>
  <BasePopup
    ref="basePopup"
    id="element-popup"
    :display-css="displayedCss"
    :editable-css="elementCss"
    :popup-width="800"
    :popup-height="600"
    @close="close"
    @css-input="handleCssInput"
    @toggle-inheritance="toggleInheritance"
  >
    <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">
        <div class="field field-font" :class="{ 'field--view-only': inheritanceLocked }">
          <label class="label-with-tooltip" data-css="font-family">Police</label>
          <div class="field-with-option">
            <select v-model="fontFamily" :disabled="inheritanceLocked">
              <option v-for="f in fonts" :key="f" :value="f">{{ f }}</option>
            </select>
            <div class="field-checkbox">
              <input type="checkbox" v-model="italic" :disabled="inheritanceLocked" />
              <label class="label-with-tooltip" data-css="font-style">Italique</label>
            </div>
          </div>
        </div>
      </div>

      <!-- Font Weight -->
      <div class="settings-subsection">
        <div class="field" :class="{ 'field--view-only': inheritanceLocked }">
          <label class="label-with-tooltip" data-css="font-weight">Graisse</label>
          <UnitToggle v-model="fontWeightString" :units="weights" :disabled="inheritanceLocked" />
        </div>
      </div>

      <!-- Font Size -->
      <div class="settings-subsection">
        <div class="field" :class="{ 'field--view-only': inheritanceLocked }">
          <label class="label-with-tooltip" data-css="font-size">Taille du texte</label>
          <div class="input-with-unit">
            <NumberInput
              v-model="fontSize.value"
              :min="6"
              :step="1"
              :disabled="inheritanceLocked"
            />
            <div class="unit-toggle">
              <button
                type="button"
                :class="{ active: fontSize.unit === 'px' }"
                :disabled="inheritanceLocked"
                @click="updateUnitPropUnit(fontSize, 'px')"
              >
                px
              </button>
            </div>
          </div>
        </div>
      </div>


      <!-- LineHeight -->
      <div class="settings-subsection">
        <div class="field" :class="{ 'field--view-only': inheritanceLocked }">
          <label class="label-with-tooltip" data-css="line-height">Interlignage</label>
          <div class="input-with-unit">
            <NumberInput
              v-model="lineHeight.value"
              :min="0"
              :step="1"
              :disabled="inheritanceLocked"
            />
            <div class="unit-toggle">
              <button
                type="button"
                :class="{ active: lineHeight.unit === 'px' }"
                :disabled="inheritanceLocked"
                @click="updateUnitPropUnit(lineHeight, 'px')"
              >
                px
              </button>
            </div>
          </div>
        </div>
      </div>


      <!-- Text Alignment -->
      <div class="settings-subsection">
        <div class="field" :class="{ 'field--view-only': inheritanceLocked }">
          <label class="label-with-tooltip" data-css="text-align">Alignement</label>
          <select v-model="textAlign" :disabled="inheritanceLocked">
            <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">
        <div class="field field-simple" :class="{ 'field--view-only': inheritanceLocked }">
          <label class="label-with-tooltip" data-css="color">Couleur</label>
          <div class="input-with-color">
            <input
              ref="colorInput"
              type="text"
              v-model="color"
              :disabled="inheritanceLocked"
              data-coloris
            />
          </div>
        </div>
      </div>

      <!-- Background -->
      <div class="settings-subsection">
        <div class="field field-simple" :class="{ 'field--view-only': inheritanceLocked }">
          <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"
              :disabled="inheritanceLocked"
              data-coloris
            />
          </div>
        </div>
      </div>

      <!-- Outer Margins -->
      <div class="settings-subsection">
        <div class="field" :class="{ 'field--view-only': inheritanceLocked }">
          <label class="label-with-tooltip" data-css="margin">Marges extérieures</label>
          <div class="input-with-unit">
            <NumberInput
              v-model="marginOuter.value"
              :min="0"
              :step="1"
              :disabled="inheritanceLocked"
            />
            <div class="unit-toggle">
              <button
                type="button"
                :class="{ active: marginOuter.unit === 'mm' }"
                :disabled="inheritanceLocked"
                @click="updateUnitPropUnit(marginOuter, 'mm')"
              >
                mm
              </button>
              <button
                type="button"
                :class="{ active: marginOuter.unit === 'px' }"
                :disabled="inheritanceLocked"
                @click="updateUnitPropUnit(marginOuter, 'px')"
              >
                px
              </button>
            </div>
          </div>
        </div>
      </div>

      <!-- Inner Margins (Padding) -->
      <div class="settings-subsection">
        <div class="field" :class="{ 'field--view-only': inheritanceLocked }">
          <label class="label-with-tooltip" data-css="padding">Marges intérieures</label>
          <div class="input-with-unit">
            <NumberInput
              v-model="paddingInner.value"
              :min="0"
              :step="1"
              :disabled="inheritanceLocked"
            />
            <div class="unit-toggle">
              <button
                type="button"
                :class="{ active: paddingInner.unit === 'mm' }"
                :disabled="inheritanceLocked"
                @click="updateUnitPropUnit(paddingInner, 'mm')"
              >
                mm
              </button>
              <button
                type="button"
                :class="{ active: paddingInner.unit === 'px' }"
                :disabled="inheritanceLocked"
                @click="updateUnitPropUnit(paddingInner, '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 NumberInput from './ui/NumberInput.vue';
import UnitToggle from './ui/UnitToggle.vue';
import BasePopup from './ui/BasePopup.vue';
import { convertUnit } from '../utils/unit-conversion';

const stylesheetStore = useStylesheetStore();

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

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

const basePopup = ref(null);

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

const selector = ref('');
const selectedElement = ref(null);
const elementInstanceCount = ref(0);
const colorInput = ref(null);
const backgroundInput = 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 fontWeight = ref(400);
const textAlign = ref('left');
const color = ref('rgb(0, 0, 0)');
const background = ref('transparent');
const fontSize = reactive({ value: 23, unit: 'px' });
const lineHeight = reactive({ value: 28, unit: 'px' });
const marginOuter = reactive({ value: 0, unit: 'mm' });
const paddingInner = reactive({ value: 0, unit: 'mm' });

// Constants
const fonts = ['Alegreya Sans', 'Alegreya', 'Arial', 'Georgia', 'Times New Roman'];
const weights = ['200', '300', '400', '600', '800'];

const fontWeightString = computed({
  get: () => String(fontWeight.value),
  set: (val) => { fontWeight.value = parseInt(val); }
});

// Style property descriptors
const styleProps = [
  { css: 'font-family', get: () => fontFamily.value, set: v => fontFamily.value = v.replace(/['"]/g, ''), debounce: false },
  { css: 'font-style', get: () => italic.value ? 'italic' : 'normal', set: v => italic.value = v === 'italic', debounce: false },
  { css: 'font-weight', get: () => fontWeight.value, set: v => fontWeight.value = parseInt(v), debounce: false },
  { css: 'text-align', get: () => textAlign.value, set: v => textAlign.value = v, debounce: false },
  { css: 'color', get: () => color.value, set: v => color.value = v, debounce: true },
  { css: 'background', get: () => background.value, set: v => background.value = v, debounce: true },
];

const unitProps = [
  { css: 'font-size', ref: fontSize, debounce: true },
  { css: 'line-height', ref: lineHeight, debounce: true },
  { css: 'margin', ref: marginOuter, debounce: true },
  { css: 'padding', ref: paddingInner, debounce: true },
];

// 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 updateUnitPropUnit = (prop, newUnit) => {
  prop.value = convertUnit(prop.value, prop.unit, newUnit);
  prop.unit = newUnit;
};

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) {
    const val = prop.get();
    if (val && (prop.css !== 'font-style' || val === 'italic')) {
      properties.push(`  ${prop.css}: ${val};`);
    }
  }

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

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

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

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

  if (!inheritanceLocked.value) {
    return elementCss.value || generatePreviewCss();
  }

  const preview = generatePreviewCss();
  if (!preview) return '';

  return '/* Héritage verrouillé - déverrouiller pour appliquer */\n/* ' +
         preview.split('\n').join('\n   ') +
         ' */';
});

const applyAllStyles = () => {
  if (!selector.value) return;
  for (const prop of styleProps) {
    updateProp(prop.css, prop.get());
  }
  for (const prop of unitProps) {
    updateProp(prop.css, prop.ref.value, prop.ref.unit);
  }
};

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

// Watchers — unit props (watch both value and unit)
for (const prop of unitProps) {
  watch(() => prop.ref.value, () => {
    if (isUpdatingFromStore) return;
    const fn = () => updateProp(prop.css, prop.ref.value, prop.ref.unit);
    prop.debounce ? debouncedUpdate(fn) : fn();
  });
  watch(() => prop.ref.unit, () => {
    if (isUpdatingFromStore) return;
    updateProp(prop.css, prop.ref.value, prop.ref.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 = () => {
  if (!selector.value) return;

  try {
    // Simple props
    for (const prop of styleProps) {
      const data = stylesheetStore.extractValue(selector.value, prop.css);
      if (data) {
        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) {
        prop.ref.value = data.value;
        prop.ref.unit = data.unit;
      }
    }
  } catch (error) {
    console.error('Error loading values from stylesheet:', error);
  }
};

const open = (element, event, count = null) => {
  isUpdatingFromStore = true;

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

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

  const blockState = stylesheetStore.getBlockState(selector.value);
  basePopup.value.inheritanceLocked = blockState !== 'active';

  loadValuesFromStylesheet();
  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);
};

const toggleInheritance = () => {
  const blockState = stylesheetStore.getBlockState(selector.value);

  if (basePopup.value.inheritanceLocked && blockState === 'commented') {
    stylesheetStore.uncommentCssBlock(selector.value);
    basePopup.value.inheritanceLocked = false;
  } else if (basePopup.value.inheritanceLocked && blockState === 'none') {
    if (selectedElement.value && props.iframeRef && props.iframeRef.contentWindow) {
      const cs = props.iframeRef.contentWindow.getComputedStyle(selectedElement.value);

      isUpdatingFromStore = true;

      fontFamily.value = cs.fontFamily.replace(/['"]/g, '').split(',')[0].trim();
      italic.value = cs.fontStyle === 'italic';
      fontWeight.value = parseInt(cs.fontWeight);

      const fontSizeMatch = cs.fontSize.match(/([\d.]+)(px|rem|em|pt)/);
      if (fontSizeMatch) {
        fontSize.value = parseFloat(fontSizeMatch[1]);
        fontSize.unit = fontSizeMatch[2];
      }

      const lineHeightMatch = cs.lineHeight.match(/([\d.]+)(px|rem|em|pt)/);
      if (lineHeightMatch) {
        lineHeight.value = parseFloat(lineHeightMatch[1]);
        lineHeight.unit = lineHeightMatch[2];
      }

      textAlign.value = cs.textAlign;
      color.value = cs.color;
      background.value = cs.backgroundColor;

      const marginMatch = cs.marginTop.match(/([\d.]+)(px|mm|pt)/);
      if (marginMatch) {
        marginOuter.value = parseFloat(marginMatch[1]);
        marginOuter.unit = marginMatch[2];
      }

      const paddingMatch = cs.paddingTop.match(/([\d.]+)(px|mm|pt)/);
      if (paddingMatch) {
        paddingInner.value = parseFloat(paddingMatch[1]);
        paddingInner.unit = paddingMatch[2];
      }

      isUpdatingFromStore = false;
    }

    applyAllStyles();
    basePopup.value.inheritanceLocked = false;
  } else if (!basePopup.value.inheritanceLocked && blockState === 'active') {
    stylesheetStore.commentCssBlock(selector.value);
    basePopup.value.inheritanceLocked = true;
  }
};

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;
}
</style>
