<script setup>
import { ref, onMounted, onBeforeUnmount, computed } from "vue";
import GoogleIcon from "@Shared/GoogleIcon.vue";
import Draggable from "@Holos/PDF/Draggable.vue";
import CanvasElement from "@Holos/PDF/Canvas.vue";
import PDFViewport from "@Holos/PDF/PDFViewport.vue";
import TextFormatter from "@Holos/PDF/TextFormatter.vue";
import htmlToPdfMake from "html-to-pdfmake";

/** Estado Reactivo */
const pages = ref([{ id: 1, elements: [] }]);
const selectedElementId = ref(null);
const elementCounter = ref(0);
const documentTitle = ref("Documento sin título");
const currentPage = ref(1);
const pageIdCounter = ref(1);
const isExporting = ref(false);
const currentPageSize = ref("A4");

const elementRefs = ref({});
const activeEditor = ref(null);
const isTableEditing = ref(false);

const allElements = computed(() =>
  pages.value.flatMap((page) => page.elements)
);
const totalElements = computed(() => allElements.value.length);
const selectedElement = computed(() =>
  allElements.value.find((el) => el.id === selectedElementId.value)
);

const addPage = () => {
  pages.value.push({ id: ++pageIdCounter.value, elements: [] });
};

const deletePage = (pageIndex) => {
  if (pages.value.length > 1) {
    if (currentPage.value > pageIndex + 1) {
      currentPage.value--;
    } else if (currentPage.value === pageIndex + 1 && currentPage.value > 1) {
      currentPage.value--;
    }
    pages.value.splice(pageIndex, 1);
  }
};

const handleDrop = (dropData) => {
  const data = JSON.parse(
    dropData.originalEvent.dataTransfer.getData("text/plain")
  );
  const newElement = createNewElement({ ...data, ...dropData });
  pages.value[dropData.pageIndex].elements.push(newElement);
  selectElement(newElement.id);
};

const createNewElement = (data) => ({
  id: `element-${++elementCounter.value}`,
  type: data.type,
  pageIndex: data.pageIndex,
  x: data.x,
  y: data.y,
  width: data.type === "table" ? 400 : 250,
  height: data.type === "image" ? 150 : 120,
  content: getDefaultContent(data.type),
});

const getDefaultContent = (type) => {
  if (type === "text") return "<p>Escribe algo...</p>";
  if (type === "table")
    return {
      data: [
        ["Encabezado 1", "Encabezado 2"],
        ["Celda 1", "Celda 2"],
      ],
    };
  return null;
};

const selectElement = (elementId) => {
  selectedElementId.value = elementId;
};
const deselectAll = (event) => {
  if (event.target === event.currentTarget) {
    selectedElementId.value = null;
    activeEditor.value = null;
    isTableEditing.value = false;
  }
};
const moveElement = (moveData) => {
  const el = allElements.value.find((e) => e.id === moveData.id);
  if (el) Object.assign(el, moveData);
};
const updateElement = (update) => {
  const el = allElements.value.find((e) => e.id === update.id);
  if (el) Object.assign(el, update);
};
const deleteElement = (elementId) => {
  pages.value.forEach((p) => {
    p.elements = p.elements.filter((el) => el.id !== elementId);
  });
  if (selectedElementId.value === elementId) selectedElementId.value = null;
};
const clearCanvas = () => {
  if (confirm("¿Seguro?")) {
    pages.value = [{ id: 1, elements: [] }];
    selectedElementId.value = null;
    elementCounter.value = 0;
    pageIdCounter.value = 1;
    currentPage.value = 1;
  }
};

const handleTableEditing = (editing) => {
  isTableEditing.value = editing;
};

const handlePageSizeChange = (sizeData) => {
  currentPageSize.value = sizeData.size;
};

const handleKeydown = (event) => {
  if (event.key === "Delete" && selectedElementId.value)
    deleteElement(selectedElementId.value);
  if (event.key === "Escape") selectedElementId.value = null;
};
onMounted(() => document.addEventListener("keydown", handleKeydown));
onBeforeUnmount(() => document.removeEventListener("keydown", handleKeydown));

const exportPDF = () => {
  isExporting.value = true;
  try {
    const content = [];
    pages.value.forEach((page, pageIndex) => {
      const pageContent = page.elements
        .map((element) => {
          const position = { x: element.x * 0.75, y: element.y * 0.75 };

          if (element.type === "text" && element.content) {
            return {
              columns: [
                {
                  stack: htmlToPdfMake(element.content),
                  width: (element.width || 250) * 0.75,
                },
              ],
              absolutePosition: position,
            };
          }
          if (element.type === "image" && element.content) {
            return {
              image: element.content,
              width: (element.width || 150) * 0.75,
              absolutePosition: position,
            };
          }
          if (element.type === "table" && element.content) {
            const body = element.content.data.map((row) =>
              row.map((cellContent) => {
                return {
                  stack: htmlToPdfMake(cellContent || "<p></p>"),
                  border: [true, true, true, true],
                };
              })
            );
            const numCols = element.content.data[0]?.length || 1;
            const colWidth = (element.width * 0.75) / numCols;
            const widths = Array(numCols).fill(colWidth);

            return {
              columns: [
                {
                  table: {
                    body: body,
                    widths: widths,
                  },
                  width: element.width * 0.75,
                },
              ],
              absolutePosition: position,
              layout: {
                hLineWidth: () => 0.5,
                vLineWidth: () => 0.5,
                hLineColor: () => "#000000",
                vLineColor: () => "#000000",
                paddingLeft: () => 4,
                paddingRight: () => 4,
                paddingTop: () => 2,
                paddingBottom: () => 2,
              },
            };
          }
          return null;
        })
        .filter(Boolean);
      content.push(...pageContent);
      if (pageIndex < pages.value.length - 1)
        content.push({ text: "", pageBreak: "after" });
    });

    const docDefinition = {
      content,
      pageSize: currentPageSize.value.toUpperCase(),
      pageMargins: [0, 0, 0, 0],
    };

    window.pdfMake
      .createPdf(docDefinition)
      .download(`${documentTitle.value || "documento"}.pdf`);
  } catch (e) {
    console.error("Error al exportar PDF:", e);
    alert("Hubo un error al generar el PDF.");
  } finally {
    isExporting.value = false;
  }
};

const handleTableAction = (action) => {
  if (!selectedElement.value || selectedElement.value.type !== "table") return;
  const tableData = selectedElement.value.content.data;
  const numCols = tableData[0]?.length || 1;
  if (action === "addRow") tableData.push(Array(numCols).fill(""));
  if (action === "addCol") tableData.forEach((row) => row.push(""));
  if (action === "delRow" && tableData.length > 1) tableData.pop();
  if (action === "delCol" && numCols > 1) tableData.forEach((row) => row.pop());

  // Actualizar tamaño de la tabla (opcional)
  const newWidth = Math.max(200, tableData[0].length * 100);
  const newHeight = Math.max(60, tableData.length * 30);
  updateElement({
    id: selectedElement.value.id,
    content: { data: tableData },
    width: newWidth,
    height: newHeight,
  });
};

const availableElements = [
  { type: "text", icon: "text_fields", title: "Texto" },
  { type: "image", icon: "image", title: "Imagen" },
  { type: "table", icon: "table_chart", title: "Tabla" },
];
</script>

<template>
  <div class="flex flex-col lg:flex-row h-screen bg-gray-50">
    <div class="w-full lg:w-64 bg-white border-r border-gray-200 flex flex-col">
      <div class="p-3 lg:p-4 border-b">
        <div class="flex items-center gap-2 mb-3">
          <GoogleIcon name="text_snippet" class="text-blue-600 text-lg" />
          <h2 class="font-semibold text-gray-900 text-sm">Diseñador</h2>
        </div>
        <input
          v-model="documentTitle"
          class="w-full px-2 py-1 text-xs border rounded mb-3"
          placeholder="Título del documento"
        />
        <button
          @click="exportPDF"
          :disabled="isExporting"
          class="w-full flex items-center justify-center gap-2 px-3 py-2 text-sm rounded transition-colors bg-red-600 hover:bg-red-700 text-white"
        >
          <GoogleIcon name="picture_as_pdf" class="text-sm" />{{
            isExporting ? "Generando..." : "Exportar PDF"
          }}
        </button>
      </div>
      <div class="p-3 lg:p-4 flex-1 overflow-y-auto">
        <h3
          class="text-xs font-semibold text-gray-500 uppercase tracking-wider mb-3"
        >
          Elementos
        </h3>
        <div class="grid grid-cols-1 gap-2">
          <Draggable
            v-for="el in availableElements"
            :key="el.type"
            v-bind="el"
          />
        </div>
        <div class="pt-4 mt-4 border-t">
          <button
            v-if="totalElements > 0"
            @click="clearCanvas"
            class="w-full flex items-center justify-center gap-1 px-2 py-1 text-xs text-red-600 hover:bg-red-50 rounded"
          >
            <GoogleIcon name="delete" class="text-sm" />Limpiar Todo
          </button>
        </div>
      </div>
    </div>
    <div class="flex-1 flex flex-col min-h-0">
      <TextFormatter
        :editor="activeEditor"
        :selected-element="selectedElement"
        :is-table-editing="isTableEditing"
        @table-action="handleTableAction"
      />
      <PDFViewport
        :pages="pages"
        :current-page="currentPage"
        @page-change="(p) => (currentPage = p)"
        @add-page="addPage"
        @delete-page="deletePage"
        @drop="handleDrop"
        @click="deselectAll"
        @page-size-change="handlePageSizeChange"
      >
        <template #elements="{ page }">
          <CanvasElement
            v-for="element in page.elements"
            :key="element.id"
            :ref="
              (el) => {
                if (el) elementRefs[element.id] = el;
              }
            "
            :element="element"
            :is-selected="selectedElementId === element.id"
            @select="selectElement"
            @delete="deleteElement"
            @update="updateElement"
            @move="moveElement"
            @editor-active="(editor) => (activeEditor = editor)"
            @table-editing="handleTableEditing"
          />
        </template>
      </PDFViewport>
    </div>
  </div>
</template>
