<script setup>
import { ref, computed, watch } from "vue";
import GoogleIcon from "@Shared/GoogleIcon.vue";
import TiptapEditor from "./TiptapEditor.vue";

const props = defineProps({
  element: { type: Object, required: true },
  isSelected: { type: Boolean, default: false },
});
const emit = defineEmits([
  "select",
  "delete",
  "update",
  "move",
  "editor-active",
  "table-editing",
]);

const isEditing = ref(false);
const elementRef = ref(null);
const isDragging = ref(false);
const isResizing = ref(false);
const dragStart = ref({ mouseX: 0, mouseY: 0, elementX: 0, elementY: 0 });
const resizeStart = ref({ x: 0, y: 0, width: 0, height: 0 });
const fileInput = ref(null);

const elementStyles = computed(() => ({
  left: `${props.element.x}px`,
  top: `${props.element.y}px`,
  width: `${props.element.width || 200}px`,
  height: `${props.element.height || 120}px`,
  position: "absolute",
}));

watch(
  () => props.isSelected,
  (selected) => {
    if (!selected && isEditing.value) {
      isEditing.value = false;
      emit("editor-active", null);
      if (props.element.type === "table") {
        emit("table-editing", false);
      }
    }
  }
);

const handleSelect = (event) => {
  event.stopPropagation();
  emit("select", props.element.id);
};

const startEditing = () => {
  if (!props.isSelected) emit("select", props.element.id);

  if (props.element.type === "text" || props.element.type === "table") {
    isEditing.value = true;
    if (props.element.type === "table") {
      emit("table-editing", true);
    }
  }
  if (props.element.type === "image") {
    fileInput.value.click();
  }
};

const handleContentUpdate = (newContent) => {
  emit("update", { id: props.element.id, content: newContent });
};

const handleCellUpdate = (rowIndex, colIndex, value) => {
  const updatedData = JSON.parse(JSON.stringify(props.element.content.data));
  updatedData[rowIndex][colIndex] = value;
  emit("update", {
    id: props.element.id,
    content: { data: updatedData },
  });
};

const handleEditorFocus = (editor) => {
  emit("editor-active", editor);
};

const handleMouseDown = (event) => {
  if (isEditing.value || event.target.closest(".resize-handle")) return;
  event.preventDefault();
  if (!props.isSelected) emit("select", props.element.id);
  isDragging.value = true;
  dragStart.value = {
    mouseX: event.clientX,
    mouseY: event.clientY,
    elementX: props.element.x,
    elementY: props.element.y,
  };
  document.addEventListener("mousemove", handleMouseMove);
  document.addEventListener("mouseup", handleMouseUp);
};

const handleMouseMove = (event) => {
  if (isDragging.value) {
    const deltaX = event.clientX - dragStart.value.mouseX;
    const deltaY = event.clientY - dragStart.value.mouseY;
    const newX = dragStart.value.elementX + deltaX;
    const newY = dragStart.value.elementY + deltaY;
    emit("move", {
      id: props.element.id,
      x: Math.max(0, newX),
      y: Math.max(0, newY),
    });
  } else if (isResizing.value) {
    handleResizeMove(event);
  }
};

const handleMouseUp = () => {
  isDragging.value = false;
  isResizing.value = false;
  document.removeEventListener("mousemove", handleMouseMove);
  document.removeEventListener("mouseup", handleMouseUp);
};

const startResize = (event) => {
  event.stopPropagation();
  event.preventDefault();
  if (isEditing.value) return;
  isResizing.value = true;
  resizeStart.value = {
    x: event.clientX,
    y: event.clientY,
    width: elementRef.value.offsetWidth,
    height: elementRef.value.offsetHeight,
  };
  document.addEventListener("mousemove", handleMouseMove);
  document.addEventListener("mouseup", handleMouseUp);
};

const handleResizeMove = (event) => {
  if (!isResizing.value) return;
  const deltaX = event.clientX - resizeStart.value.x;
  const deltaY = event.clientY - resizeStart.value.y;
  const newWidth = Math.max(100, resizeStart.value.width + deltaX);
  const newHeight = Math.max(40, resizeStart.value.height + deltaY);
  emit("update", { id: props.element.id, width: newWidth, height: newHeight });
};

const handleDelete = () => emit("delete", props.element.id);

const handleFileSelect = (event) => {
  const file = event.target.files[0];
  if (file && file.type.startsWith("image/")) {
    const reader = new FileReader();
    reader.onload = (e) =>
      emit("update", {
        id: props.element.id,
        content: e.target.result,
        fileName: file.name,
      });
    reader.readAsDataURL(file);
  }
  event.target.value = null;
};
</script>

<template>
  <div
    ref="elementRef"
    :style="elementStyles"
    class="group select-none bg-white border border-gray-300 rounded"
    :class="{
      'ring-2 ring-blue-500 border-blue-500 z-10': isSelected,
      'z-20': isEditing,
      'shadow-md': isSelected,
      'overflow-hidden': element.type === 'image',
    }"
    @click="handleSelect"
    @dblclick="startEditing"
  >
    <div
      v-if="!isEditing"
      @mousedown="handleMouseDown"
      class="absolute inset-0 z-10 cursor-move"
    />

    <TiptapEditor
      v-if="element.type === 'text'"
      :model-value="element.content"
      :editable="isEditing"
      @update:model-value="handleContentUpdate"
      @focus="handleEditorFocus"
    />

    <div
      v-else-if="element.type === 'image'"
      class="w-full h-full flex items-center justify-center bg-gray-50"
    >
      <img
        v-if="element.content"
        :src="element.content"
        class="w-full h-full object-cover rounded"
        :alt="element.fileName || 'Imagen'"
      />
      <div v-else class="text-gray-400 text-center p-4">
        <GoogleIcon name="image" class="text-3xl mb-2" />
        <p class="text-xs">Doble clic para subir</p>
      </div>
    </div>

    <div
      v-else-if="element.type === 'table'"
      class="w-full h-full overflow-auto"
      @mousedown.stop
    >
      <table class="w-full h-full border-collapse">
        <tbody>
          <tr
            v-for="(row, rowIndex) in element.content.data"
            :key="rowIndex"
            class="align-top"
          >
            <td
              v-for="(cell, colIndex) in row"
              :key="colIndex"
              class="border p-0 text-sm relative"
            >
              <TiptapEditor
                :key="`${element.id}-${rowIndex}-${colIndex}`"
                :model-value="cell"
                :editable="isEditing"
                @update:model-value="
                  handleCellUpdate(rowIndex, colIndex, $event)
                "
                @focus="handleEditorFocus"
                class="w-full h-full min-h-[2.5em]"
              />
            </td>
          </tr>
        </tbody>
      </table>
    </div>

    <div
      v-if="isSelected && !isEditing"
      class="absolute -top-8 right-0 flex items-center gap-1 z-20"
    >
      <button
        @click.stop="handleDelete"
        class="w-6 h-6 bg-red-500 hover:bg-red-600 text-white rounded flex items-center justify-center text-xs font-bold transition-colors"
        title="Eliminar"
      >
        x
      </button>
    </div>
    <div
      v-if="isSelected && !isEditing"
      @mousedown.stop="startResize"
      class="resize-handle absolute -bottom-1 -right-1 w-3 h-3 bg-blue-500 border-2 border-white cursor-se-resize rounded-full z-20 hover:bg-blue-600 transition-colors"
    />
    <input
      ref="fileInput"
      type="file"
      accept="image/*"
      @change="handleFileSelect"
      class="hidden"
    />
  </div>
</template>
