<script setup>
import PagedJsWrapper from './components/PagedJsWrapper.vue';
import EditorPanel from './components/EditorPanel.vue';
import StylesheetViewer from './components/StylesheetViewer.vue';
import ElementPopup from './components/ElementPopup.vue';
import { onMounted, ref, watch } from 'vue';

// Main state
const previewFrame = ref(null);
const stylesheetContent = ref('');
const aboutFontSize = ref(2);
const aboutFontSizeUnit = ref('rem');

// Popup state
const popupVisible = ref(false);
const popupPosition = ref({ x: 0, y: 0 });
const popupSelector = ref('');
const popupElementCss = ref('');
const popupFontSize = ref(null);
const popupFontSizeUnit = ref('rem');

// PagedJS print rules
const printStyles = `
h2 { break-before: page; }

@page {
  size: A4;
  margin: 20mm 15mm 26mm 15mm;
}

@page {
  @bottom-center { content: string(title); }
}

.chapter > h2 { string-set: title content(text); }
`;

// CSS parsing utilities
const extractCssBlock = (css, selector) => {
  const escaped = selector.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
  const match = css.match(new RegExp(`${escaped}\\s*{[^}]*}`, 'gi'));
  return match ? match[0] : '';
};

const extractCssValue = (css, selector, property) => {
  const regex = new RegExp(`${selector}\\s*{[^}]*${property}:\\s*([\\d.]+)(px|rem|em)`, 'i');
  const match = css.match(regex);
  return match ? { value: parseFloat(match[1]), unit: match[2] } : null;
};

const updateCssValue = (selector, property, value, unit) => {
  const regex = new RegExp(`(${selector}\\s*{[^}]*${property}:\\s*)[\\d.]+(px|rem|em)`, 'gi');
  stylesheetContent.value = stylesheetContent.value.replace(regex, `$1${value}${unit}`);
};

// Iframe style injection
const injectStylesToIframe = () => {
  const iframe = previewFrame.value;
  if (!iframe?.contentDocument) return;

  let styleElement = iframe.contentDocument.getElementById('dynamic-styles');
  if (!styleElement) {
    styleElement = iframe.contentDocument.createElement('style');
    styleElement.id = 'dynamic-styles';
    iframe.contentDocument.head.appendChild(styleElement);
  }
  styleElement.textContent = stylesheetContent.value;
};

// Popup handlers
const handleIframeClick = (event) => {
  const element = event.target;

  if (element.tagName === 'BODY' || element.tagName === 'HTML') {
    popupVisible.value = false;
    return;
  }

  const selector = element.id
    ? `#${element.id}`
    : `.${element.className.split(' ')[0]}`;

  popupSelector.value = selector;
  popupElementCss.value = extractCssBlock(stylesheetContent.value, selector);

  const fontSizeData = extractCssValue(stylesheetContent.value, selector, 'font-size');
  popupFontSize.value = fontSizeData?.value ?? null;
  popupFontSizeUnit.value = fontSizeData?.unit ?? 'rem';

  const rect = element.getBoundingClientRect();
  const iframeRect = previewFrame.value.getBoundingClientRect();
  popupPosition.value = {
    x: iframeRect.left + rect.left,
    y: iframeRect.top + rect.bottom + 5
  };

  popupVisible.value = true;
};

const closePopup = () => {
  popupVisible.value = false;
};

const updatePopupFontSize = (newValue) => {
  updateCssValue(popupSelector.value, 'font-size', newValue, popupFontSizeUnit.value);
  popupFontSize.value = newValue;
  popupElementCss.value = extractCssBlock(stylesheetContent.value, popupSelector.value);
};

// Watchers
watch(aboutFontSize, (newVal) => {
  updateCssValue('.about', 'font-size', newVal, aboutFontSizeUnit.value);
});

watch(stylesheetContent, injectStylesToIframe);

// Initial render
const renderPreview = async () => {
  const iframe = previewFrame.value;
  if (!iframe) return;

  const response = await fetch('/assets/css/stylesheet.css');
  stylesheetContent.value = await response.text();

  const initialFontSize = extractCssValue(stylesheetContent.value, '.about', 'font-size');
  if (initialFontSize) {
    aboutFontSize.value = initialFontSize.value;
    aboutFontSizeUnit.value = initialFontSize.unit;
  }

  const contentSource = document.getElementById('content-source');
  const iframeDoc = iframe.contentDocument;

  iframeDoc.open();
  iframeDoc.write(`
    <!DOCTYPE html>
    <html>
    <head>
      <link rel="stylesheet" href="/assets/css/pagedjs-interface.css">
      <style id="dynamic-styles">${stylesheetContent.value}</style>
      <style>${printStyles}</style>
      <script src="https://unpkg.com/pagedjs/dist/paged.polyfill.js"><\/script>
    </head>
    <body>${contentSource.innerHTML}</body>
    </html>
  `);
  iframeDoc.close();

  iframe.onload = () => {
    iframe.contentDocument.addEventListener('click', handleIframeClick);
  };
};

onMounted(renderPreview);
</script>

<template>
  <div id="content-source" style="display: none">
    <PagedJsWrapper />
  </div>

  <EditorPanel
    :fontSize="aboutFontSize"
    :unit="aboutFontSizeUnit"
    @update:fontSize="aboutFontSize = $event"
  />

  <iframe ref="previewFrame" id="preview-frame"></iframe>

  <StylesheetViewer :stylesheet="stylesheetContent" />

  <ElementPopup
    :visible="popupVisible"
    :position="popupPosition"
    :selector="popupSelector"
    :elementCss="popupElementCss"
    :currentFontSize="popupFontSize"
    :fontSizeUnit="popupFontSizeUnit"
    @close="closePopup"
    @update:fontSize="updatePopupFontSize"
  />
</template>

<style>
#preview-frame {
  position: fixed;
  top: 0;
  left: 250px;
  width: calc(100% - 600px);
  height: 100vh;
  border: none;
}
</style>
