<template>
  <section class="settings-section">
    <h2>Réglage des pages</h2>

    <div class="settings-subsection">
      <div class="field">
        <label for="page-format">Format d'impression</label>
        <select id="page-format" v-model="pageFormat">
          <option value="A4">A4</option>
          <option value="A5">A5</option>
          <option value="A3">A3</option>
          <option value="letter">Letter</option>
          <option value="legal">Legal</option>
        </select>
      </div>
    </div>

    <div class="settings-subsection">
      <div class="field field--view-only">
        <label for="page-width">Largeur</label>
        <input
          id="page-width"
          type="number"
          :value="parseInt(pageWidth)"
          disabled
        />
        <button type="button" disabled>mm</button>
      </div>

      <div class="field field--view-only">
        <label for="page-height">Hauteur</label>
        <input
          id="page-height"
          type="number"
          :value="parseInt(pageHeight)"
          disabled
        />
        <button type="button" disabled>mm</button>
      </div>
    </div>

    <div class="settings-subsection margins">
      <h3>Marges</h3>

      <div class="field">
        <label for="margin-top">Haut</label>
        <div class="input-with-unit">
          <input
            id="margin-top"
            type="number"
            v-model.number="margins.top.value"
            min="0"
          />
          <div class="unit-toggle">
            <button
              type="button"
              :class="{ active: margins.top.unit === 'mm' }"
              @click="margins.top.unit = 'mm'"
            >
              mm
            </button>
            <button
              type="button"
              :class="{ active: margins.top.unit === 'px' }"
              @click="margins.top.unit = 'px'"
            >
              px
            </button>
          </div>
        </div>
      </div>

      <div class="field">
        <label for="margin-bottom">Bas</label>
        <div class="input-with-unit">
          <input
            id="margin-bottom"
            type="number"
            v-model.number="margins.bottom.value"
            min="0"
          />
          <div class="unit-toggle">
            <button
              type="button"
              :class="{ active: margins.bottom.unit === 'mm' }"
              @click="margins.bottom.unit = 'mm'"
            >
              mm
            </button>
            <button
              type="button"
              :class="{ active: margins.bottom.unit === 'px' }"
              @click="margins.bottom.unit = 'px'"
            >
              px
            </button>
          </div>
        </div>
      </div>

      <div class="field">
        <label for="margin-left">Gauche</label>
        <div class="input-with-unit">
          <input
            id="margin-left"
            type="number"
            v-model.number="margins.left.value"
            min="0"
          />
          <div class="unit-toggle">
            <button
              type="button"
              :class="{ active: margins.left.unit === 'mm' }"
              @click="margins.left.unit = 'mm'"
            >
              mm
            </button>
            <button
              type="button"
              :class="{ active: margins.left.unit === 'px' }"
              @click="margins.left.unit = 'px'"
            >
              px
            </button>
          </div>
        </div>
      </div>

      <div class="field">
        <label for="margin-right">Droite</label>
        <div class="input-with-unit">
          <input
            id="margin-right"
            type="number"
            v-model.number="margins.right.value"
            min="0"
          />
          <div class="unit-toggle">
            <button
              type="button"
              :class="{ active: margins.right.unit === 'mm' }"
              @click="margins.right.unit = 'mm'"
            >
              mm
            </button>
            <button
              type="button"
              :class="{ active: margins.right.unit === 'px' }"
              @click="margins.right.unit = 'px'"
            >
              px
            </button>
          </div>
        </div>
      </div>
    </div>

    <div class="settings-subsection">
      <div class="field">
        <label for="background">Arrière-plan</label>
        <div class="input-with-color">
          <input
            ref="backgroundColorInput"
            type="text"
            id="background"
            v-model="background.value"
            data-coloris
          />
          <!-- Temporarily commented out
          <div class="unit-toggle">
            <button
              type="button"
              :class="{ active: background.format === 'rgb' }"
              @click="background.format = 'rgb'"
            >
              rgb
            </button>
            <button
              type="button"
              :class="{ active: background.format === 'hex' }"
              @click="background.format = 'hex'"
            >
              hex
            </button>
          </div>
          -->
        </div>
      </div>
    </div>

    <div class="settings-subsection">
      <div class="field">
        <label for="pattern">Motif</label>
        <select id="pattern" v-model="pattern">
          <option value="">Choisissez</option>
          <option value="dots">Points</option>
          <option value="lines">Lignes</option>
          <option value="grid">Grille</option>
        </select>
      </div>
    </div>

    <div class="settings-subsection">
      <div class="field checkbox-field">
        <input id="page-numbers" type="checkbox" v-model="pageNumbers" />
        <label for="page-numbers">Numéro de page</label>
      </div>

      <div class="field checkbox-field">
        <input id="running-title" type="checkbox" v-model="runningTitle" />
        <label for="running-title">Titre courant</label>
      </div>
    </div>
  </section>
</template>

<script setup>
import { ref, computed, watch, onMounted, inject } from 'vue';
import { useStylesheetStore } from '../../stores/stylesheet';
import Coloris from '@melloware/coloris';
import '@melloware/coloris/dist/coloris.css';

const stylesheetStore = useStylesheetStore();
const backgroundColorInput = ref(null);
const activeTab = inject('activeTab', ref('document'));

let isUpdatingFromStore = false;
let updateTimer = null;

const pageFormat = ref('A4');

const pageFormats = {
  A4: { width: '210mm', height: '297mm' },
  A5: { width: '148mm', height: '210mm' },
  A3: { width: '297mm', height: '420mm' },
  letter: { width: '8.5in', height: '11in' },
  legal: { width: '8.5in', height: '14in' },
};

const pageWidth = computed(() => pageFormats[pageFormat.value].width);
const pageHeight = computed(() => pageFormats[pageFormat.value].height);

const margins = ref({
  top: { value: 20, unit: 'mm' },
  bottom: { value: 20, unit: 'mm' },
  left: { value: 20, unit: 'mm' },
  right: { value: 20, unit: 'mm' },
});

const background = ref({
  value: '',
  format: 'hex',
});

const pattern = ref('');
const pageNumbers = ref(false);
const runningTitle = ref(false);

const debouncedUpdate = (callback) => {
  clearTimeout(updateTimer);
  updateTimer = setTimeout(callback, 1000);
};

const immediateUpdate = (callback) => {
  callback();
};

watch(pageFormat, (newFormat) => {
  if (isUpdatingFromStore) return;

  immediateUpdate(() => {
    stylesheetStore.updateProperty('@page', 'size', newFormat, '');
  });
});

const updateMargins = () => {
  const marginValue = `${margins.value.top.value}${margins.value.top.unit} ${margins.value.right.value}${margins.value.right.unit} ${margins.value.bottom.value}${margins.value.bottom.unit} ${margins.value.left.value}${margins.value.left.unit}`;

  const currentBlock = stylesheetStore.extractBlock('@page');
  const updatedBlock = currentBlock.replace(
    /(margin:\s*)[^;]+/,
    `$1${marginValue}`
  );

  stylesheetStore.content = stylesheetStore.content.replace(
    currentBlock,
    updatedBlock
  );
};

// Watch margin values (number inputs) with debounce
watch(
  () => [
    margins.value.top.value,
    margins.value.bottom.value,
    margins.value.left.value,
    margins.value.right.value,
  ],
  () => {
    if (isUpdatingFromStore) return;
    debouncedUpdate(updateMargins);
  }
);

// Watch margin units (button clicks) without debounce
watch(
  () => [
    margins.value.top.unit,
    margins.value.bottom.unit,
    margins.value.left.unit,
    margins.value.right.unit,
  ],
  () => {
    if (isUpdatingFromStore) return;
    immediateUpdate(updateMargins);
  }
);

const updateBackground = () => {
  if (!background.value.value) return;

  const currentBlock = stylesheetStore.extractBlock('@page');

  if (currentBlock.includes('background:')) {
    const updatedBlock = currentBlock.replace(
      /(background:\s*)[^;]+/,
      `$1${background.value.value}`
    );
    stylesheetStore.content = stylesheetStore.content.replace(
      currentBlock,
      updatedBlock
    );
  } else {
    const updatedBlock = currentBlock.replace(
      /(\s*})$/,
      `  background: ${background.value.value};\n$1`
    );
    stylesheetStore.content = stylesheetStore.content.replace(
      currentBlock,
      updatedBlock
    );
  }
};

// Watch background value (text input) with debounce
watch(
  () => background.value.value,
  () => {
    if (isUpdatingFromStore) return;
    debouncedUpdate(updateBackground);
  }
);

// Watch background format (button clicks) without debounce
watch(
  () => background.value.format,
  () => {
    if (isUpdatingFromStore) return;
    immediateUpdate(updateBackground);
  }
);

watch(pattern, (newPattern) => {
  if (!newPattern || isUpdatingFromStore) return;

  immediateUpdate(() => {
    // TODO: implement pattern application
  });
});

watch(pageNumbers, (enabled) => {
  if (isUpdatingFromStore) return;

  immediateUpdate(() => {
    updatePageFooters();
  });
});

watch(runningTitle, (enabled) => {
  if (isUpdatingFromStore) return;

  immediateUpdate(() => {
    updatePageFooters();
  });
});

const updatePageFooters = () => {
  let currentCss = stylesheetStore.content;

  // Remove existing @page:left and @page:right rules
  currentCss = currentCss.replace(/@page:left\s*\{[^}]*\}/g, '');
  currentCss = currentCss.replace(/@page:right\s*\{[^}]*\}/g, '');

  // Remove old @page @bottom-center rule if exists
  currentCss = currentCss.replace(/@page\s*\{[^}]*@bottom-center[^}]*\}/g, (match) => {
    return match.replace(/@bottom-center\s*\{[^}]*\}/g, '');
  });

  // Remove string-set rule if running title is disabled
  if (!runningTitle.value) {
    currentCss = currentCss.replace(/\.chapter\s*>\s*h2\s*\{[^}]*string-set:[^}]*\}\s*/g, '');
  } else if (!currentCss.includes('string-set: title')) {
    // Add the string-set rule for h2 titles if running title is enabled
    const stringSetRule = '\n.chapter > h2 {\n  string-set: title content(text);\n}\n';
    currentCss += stringSetRule;
  }

  // Build new rules based on checkboxes
  let leftPageRule = '';
  let rightPageRule = '';

  if (pageNumbers.value || runningTitle.value) {
    // Left pages: page number bottom-left, running title right next to it (bottom-left-corner)
    let leftBottomLeft = '';
    let leftBottomCenter = '';

    if (pageNumbers.value && runningTitle.value) {
      // Page number on the left, title right next to it
      leftBottomLeft = '  @bottom-left {\n    content: counter(page) " " string(title);\n  }\n';
    } else if (pageNumbers.value) {
      leftBottomLeft = '  @bottom-left {\n    content: counter(page);\n  }\n';
    } else if (runningTitle.value) {
      leftBottomLeft = '  @bottom-left {\n    content: string(title);\n  }\n';
    }

    if (leftBottomLeft || leftBottomCenter) {
      leftPageRule = `@page:left {\n${leftBottomLeft}${leftBottomCenter}}\n\n`;
    }

    // Right pages: title on the left, page number on the right (next to it)
    let rightBottomRight = '';

    if (pageNumbers.value && runningTitle.value) {
      // Title on the left of page number
      rightBottomRight = '  @bottom-right {\n    content: string(title) " " counter(page);\n  }\n';
    } else if (pageNumbers.value) {
      rightBottomRight = '  @bottom-right {\n    content: counter(page);\n  }\n';
    } else if (runningTitle.value) {
      rightBottomRight = '  @bottom-right {\n    content: string(title);\n  }\n';
    }

    if (rightBottomRight) {
      rightPageRule = `@page:right {\n${rightBottomRight}}\n\n`;
    }
  }

  // Insert the new rules after the main @page rule
  const pageRuleMatch = currentCss.match(/@page\s*\{[^}]*\}/);
  if (pageRuleMatch) {
    const insertPosition = pageRuleMatch.index + pageRuleMatch[0].length;
    currentCss =
      currentCss.slice(0, insertPosition) +
      '\n\n' +
      leftPageRule +
      rightPageRule +
      currentCss.slice(insertPosition);
  }

  stylesheetStore.content = currentCss;
};

const syncFromStore = () => {
  isUpdatingFromStore = true;

  try {
    const pageBlock = stylesheetStore.extractBlock('@page');

    const sizeMatch = pageBlock.match(/size:\s*([A-Za-z0-9]+)/);
    if (sizeMatch) {
      pageFormat.value = sizeMatch[1];
    }

    const marginMatch = pageBlock.match(
      /margin:\s*([0-9.]+)([a-z]+)\s+([0-9.]+)([a-z]+)\s+([0-9.]+)([a-z]+)\s+([0-9.]+)([a-z]+)/i
    );
    if (marginMatch) {
      margins.value.top = {
        value: parseFloat(marginMatch[1]),
        unit: marginMatch[2],
      };
      margins.value.right = {
        value: parseFloat(marginMatch[3]),
        unit: marginMatch[4],
      };
      margins.value.bottom = {
        value: parseFloat(marginMatch[5]),
        unit: marginMatch[6],
      };
      margins.value.left = {
        value: parseFloat(marginMatch[7]),
        unit: marginMatch[8],
      };
    }

    const bgMatch = pageBlock.match(/background:\s*([^;]+)/);
    if (bgMatch) {
      background.value.value = bgMatch[1].trim();
    }

    // Check for page numbers and running title in @page:left and @page:right
    const leftPageMatch = stylesheetStore.content.match(/@page:left\s*\{[^}]*\}/);
    const rightPageMatch = stylesheetStore.content.match(/@page:right\s*\{[^}]*\}/);

    // Check if page numbers exist (counter(page) in either left or right)
    const hasPageNumbers =
      (leftPageMatch && leftPageMatch[0].includes('counter(page)')) ||
      (rightPageMatch && rightPageMatch[0].includes('counter(page)'));
    pageNumbers.value = hasPageNumbers;

    // Check if running title exists (string(title) in either left or right)
    const hasRunningTitle =
      (leftPageMatch && leftPageMatch[0].includes('string(title)')) ||
      (rightPageMatch && rightPageMatch[0].includes('string(title)'));
    runningTitle.value = hasRunningTitle;
  } finally {
    isUpdatingFromStore = false;
  }
};

watch(
  () => stylesheetStore.content,
  () => {
    if (!isUpdatingFromStore) {
      syncFromStore();
    }
  }
);

const updateColorisButton = () => {
  const input = backgroundColorInput.value;
  if (input && background.value.value) {
    // Force Coloris to update by triggering a change event
    const event = new Event('input', { bubbles: true });
    input.dispatchEvent(event);
  }
};

// Watch for when the user returns to the "document" tab
watch(activeTab, (newTab, oldTab) => {
  if (newTab === 'document' && oldTab !== 'document' && background.value.value) {
    // Small delay to ensure DOM is ready
    setTimeout(updateColorisButton, 100);
  }
});

onMounted(() => {
  syncFromStore();

  // Initialize Coloris
  Coloris.init();
  Coloris({
    el: '[data-coloris]',
    theme: 'pill',
    themeMode: 'dark',
    formatToggle: true,
    alpha: true,
    closeButton: true,
    closeLabel: 'Fermer',
    clearButton: true,
    clearLabel: 'Effacer',
    swatchesOnly: false,
    inline: false,
    wrap: true,
    swatches: [
      '#264653',
      '#2a9d8f',
      '#e9c46a',
      '#f4a261',
      '#e76f51',
      '#d62828',
      '#023e8a',
      '#0077b6',
      '#ffffff',
      '#000000',
    ],
  });

  // Initialize button color if value exists
  if (background.value.value) {
    setTimeout(updateColorisButton, 100);
  }
});
</script>
