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

/** Propiedades */
const props = defineProps({
    element: {
        type: Object,
        required: true
    },
    isSelected: {
        type: Boolean,
        default: false
    }
});

/** Eventos */
const emit = defineEmits(['select', 'delete', 'update', 'move']);

/** Referencias */
const isEditing = ref(false);
const editValue = ref('');
const editInput = ref(null);
const editTextarea = ref(null);
const elementRef = ref(null);
const isDragging = ref(false);
const isResizing = ref(false);
const resizeDirection = ref(null); // 'corner', 'right', 'bottom'
const dragStart = ref({ x: 0, y: 0 });
const resizeStart = ref({ x: 0, y: 0, width: 0, height: 0 });
const fileInput = ref(null);

/** Propiedades computadas */
const elementStyles = computed(() => ({
    left: `${props.element.x}px`,
    top: `${props.element.y}px`,
    width: `${props.element.width || 200}px`,
    height: `${props.element.height || 40}px`
}));

/** Watchers */
watch(() => props.isSelected, (selected) => {
    if (selected && isEditing.value) {
        nextTick(() => {
            if (props.element.type === 'text' && editInput.value) {
                editInput.value.focus();
                editInput.value.select();
            } else if (props.element.type === 'code' && editTextarea.value) {
                editTextarea.value.focus();
                editTextarea.value.select();
            }
        });
    }
});

/** Métodos */
const handleSelect = (event) => {
    event.stopPropagation();
    emit('select', props.element.id);
};

const handleDelete = () => {
    emit('delete', props.element.id);
};

const startEditing = () => {
    if (props.element.type === 'table' && props.element.content) {
        // Deep copy para evitar mutaciones directas
        editValue.value = JSON.parse(JSON.stringify(props.element.content));
    } else if (props.element.type === 'code') {
        editValue.value = props.element.content || 'console.log("Hola mundo");';
    } else {
        editValue.value = props.element.content || getDefaultEditValue();
    }
    isEditing.value = true;
    
    nextTick(() => {
        if (editTextarea.value) editTextarea.value.focus();
        if (editInput.value) editInput.value.focus();
    });
};

const finishEditing = () => {
    if (isEditing.value) {
        isEditing.value = false;
        
        // Para tablas, emitir el objeto completo
        if (props.element.type === 'table') {
            emit('update', {
                id: props.element.id,
                content: editValue.value
            });
        } else {
            emit('update', {
                id: props.element.id,
                content: editValue.value
            });
        }
    }
};

const handleKeydown = (event) => {
    if (props.element.type === 'text') {
        if (event.key === 'Enter' && !event.shiftKey) {
            event.preventDefault();
            finishEditing();
        } else if (event.key === 'Escape') {
            isEditing.value = false;
            editValue.value = props.element.content || 'Nuevo texto';
        }
    } else if (props.element.type === 'code') {
        if (event.key === 'Escape') {
            isEditing.value = false;
            editValue.value = props.element.content || 'console.log("Hola mundo");';
        }
        // Para código, permitimos Enter normal y usamos Ctrl+Enter para terminar
        if (event.key === 'Enter' && event.ctrlKey) {
            event.preventDefault();
            finishEditing();
        }
    } else if (props.element.type === 'table') {
        if (event.key === 'Escape') {
            isEditing.value = false;
            // Restaurar el contenido original de la tabla
            editValue.value = props.element.content ? 
                JSON.parse(JSON.stringify(props.element.content)) : 
                getDefaultEditValue();
        }
        // Para tablas, Enter normal para nueva línea en celda, Ctrl+Enter para terminar
        if (event.key === 'Enter' && event.ctrlKey) {
            event.preventDefault();
            finishEditing();
        }
    }
};

// Manejo de archivo de imagen
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);
    }
    // Limpiar el input
    event.target.value = '';
};

// Funcionalidad de arrastre
const handleMouseDown = (event) => {
    if (isEditing.value || isResizing.value) return;
    
    isDragging.value = true;
    dragStart.value = {
        x: event.clientX - props.element.x,
        y: event.clientY - props.element.y
    };

    document.addEventListener('mousemove', handleMouseMove);
    document.addEventListener('mouseup', handleMouseUp);
    
    event.preventDefault();
};

const handleMouseMove = (event) => {
    if (isDragging.value && !isResizing.value) {
        const newX = event.clientX - dragStart.value.x;
        const newY = event.clientY - dragStart.value.y;

        emit('move', {
            id: props.element.id,
            x: Math.max(0, newX),
            y: Math.max(0, newY)
        });
    } else if (isResizing.value && !isDragging.value) {
        handleResizeMove(event);
    }
};

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

// Funcionalidad de redimensionamiento por esquina
const startResize = (event) => {
    event.stopPropagation();
    event.preventDefault();
    
    isResizing.value = true;
    resizeDirection.value = 'corner';
    resizeStart.value = {
        x: event.clientX,
        y: event.clientY,
        width: props.element.width || 200,
        height: props.element.height || 40
    };

    document.addEventListener('mousemove', handleMouseMove);
    document.addEventListener('mouseup', handleMouseUp);
};

// Funcionalidad de redimensionamiento por bordes
const startResizeEdge = (event, direction) => {
    event.stopPropagation();
    event.preventDefault();
    
    isResizing.value = true;
    resizeDirection.value = direction;
    resizeStart.value = {
        x: event.clientX,
        y: event.clientY,
        width: props.element.width || 200,
        height: props.element.height || 40
    };

    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;

    let newWidth = resizeStart.value.width;
    let newHeight = resizeStart.value.height;

    // Calcular nuevas dimensiones según la dirección
    if (resizeDirection.value === 'corner') {
        newWidth = Math.max(getMinWidth(), Math.min(getMaxWidth(), resizeStart.value.width + deltaX));
        newHeight = Math.max(getMinHeight(), Math.min(getMaxHeight(), resizeStart.value.height + deltaY));
    } else if (resizeDirection.value === 'right') {
        newWidth = Math.max(getMinWidth(), Math.min(getMaxWidth(), resizeStart.value.width + deltaX));
    } else if (resizeDirection.value === 'bottom') {
        newHeight = Math.max(getMinHeight(), Math.min(getMaxHeight(), resizeStart.value.height + deltaY));
    }

    emit('update', {
        id: props.element.id,
        width: newWidth,
        height: newHeight
    });
};

// Obtener tamaños mínimos según el tipo de elemento
const getMinWidth = () => {
    switch (props.element.type) {
        case 'text':
            return 100;
        case 'image':
            return 100;
        case 'table':
            return 200;
        default:
            return 100;
    }
};

const getMinHeight = () => {
    switch (props.element.type) {
        case 'text':
            return 30;
        case 'image':
            return 80;
        case 'table':
            return 80;
        default:
            return 30;
    }
};

// Obtener tamaños máximos según el tipo de elemento
const getMaxWidth = () => {
    return 800; // Máximo general
};

const getMaxHeight = () => {
    return 600; // Máximo general
};
</script>

<template>
    <div
        ref="elementRef"
        :style="elementStyles"
        @click="handleSelect"
        @dblclick="startEditing"
        @mousedown="handleMouseDown"
        class="absolute group select-none"
        :class="{
            'ring-2 ring-blue-500 ring-opacity-50': isSelected,
            'cursor-move': !isEditing && !isResizing,
            'cursor-text': isEditing && (element.type === 'text' || element.type === 'code'),
            'cursor-se-resize': isResizing && resizeDirection === 'corner',
            'cursor-e-resize': isResizing && resizeDirection === 'right',
            'cursor-s-resize': isResizing && resizeDirection === 'bottom'
        }"
    >
        <!-- Input oculto para selección de archivos -->
        <input
            ref="fileInput"
            type="file"
            accept="image/*"
            @change="handleFileSelect"
            class="hidden"
        />

        <!-- Elemento de Texto -->
        <div
            v-if="element.type === 'text'"
            class="w-full h-full flex items-center px-3 py-2 bg-blue-100 rounded border border-blue-300 text-blue-800 text-sm font-medium dark:bg-blue-900/30 dark:border-blue-600 dark:text-blue-300"
        >
            <input
                v-if="isEditing"
                ref="editInput"
                v-model="editValue"
                @blur="finishEditing"
                @keydown="handleKeydown"
                class="w-full bg-transparent outline-none cursor-text"
                @mousedown.stop
            />
            <span v-else class="truncate pointer-events-none">
                {{ element.content || 'Nuevo texto' }}
            </span>
        </div>

        <!-- Elemento de Imagen -->
        <div
            v-else-if="element.type === 'image'"
            class="w-full h-full flex items-center justify-center bg-gray-100 rounded border border-gray-300 dark:bg-primary/10 dark:border-primary/20 overflow-hidden"
        >
            <!-- Si hay imagen cargada -->
            <img
                v-if="element.content && element.content.startsWith('data:image')"
                :src="element.content"
                :alt="element.fileName || 'Imagen'"
                class="w-full h-full object-cover pointer-events-none"
            />
            <!-- Placeholder para imagen -->
            <div v-else class="flex flex-col items-center justify-center text-gray-400 dark:text-primary-dt/50 p-4">
                <GoogleIcon name="image" class="text-2xl mb-1" />
                <span class="text-xs text-center">Haz doble clic para cargar imagen</span>
            </div>
        </div>

        <!-- Elemento de Código -->
        <div
            v-else-if="element.type === 'code'"
            class="w-full h-full bg-gray-900 rounded border overflow-hidden"
        >
            <div class="w-full h-6 bg-gray-800 flex items-center px-2 text-xs text-gray-400 border-b border-gray-700">
                <div class="flex gap-1">
                    <div class="w-2 h-2 bg-red-500 rounded-full"></div>
                    <div class="w-2 h-2 bg-yellow-500 rounded-full"></div>
                    <div class="w-2 h-2 bg-green-500 rounded-full"></div>
                </div>
                <span class="ml-2">{{ element.fileName || 'script.js' }}</span>
            </div>
            <div class="p-2 h-[calc(100%-24px)]">
                <textarea
                    v-if="isEditing"
                    ref="editTextarea"
                    v-model="editValue"
                    @blur="finishEditing"
                    @keydown="handleKeydown"
                    class="w-full h-full bg-transparent text-green-400 text-xs font-mono outline-none resize-none cursor-text"
                    @mousedown.stop
                />
                <pre v-else class="text-green-400 text-xs font-mono overflow-auto h-full pointer-events-none whitespace-pre-wrap">{{ element.content || 'console.log("Hola mundo");' }}</pre>
            </div>
        </div>

        <!-- Elemento de Tabla -->
        <div
            v-else-if="element.type === 'table'"
            class="w-full h-full bg-white rounded border overflow-hidden"
        >
            <div v-if="element.content && element.content.data" class="w-full h-full">
                <table class="w-full h-full text-xs border-collapse">
                    <thead v-if="element.content.data.length > 0">
                        <tr class="bg-blue-50 dark:bg-blue-900/20">
                            <th 
                                v-for="(header, colIndex) in element.content.data[0]" 
                                :key="colIndex"
                                class="border border-gray-300 dark:border-primary/20 px-1 py-1 text-left font-semibold text-blue-800 dark:text-blue-300"
                            >
                                <input
                                    v-if="isEditing"
                                    v-model="editValue.data[0][colIndex]"
                                    class="w-full bg-transparent outline-none text-xs"
                                    @mousedown.stop
                                    @click.stop
                                    @focus.stop
                                />
                                <span v-else class="truncate">{{ header }}</span>
                            </th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr 
                            v-for="(row, rowIndex) in element.content.data.slice(1)" 
                            :key="rowIndex"
                            class="hover:bg-gray-50 dark:hover:bg-primary/5"
                        >
                            <td 
                                v-for="(cell, colIndex) in row" 
                                :key="colIndex"
                                class="border border-gray-300 dark:border-primary/20 px-1 py-1"
                            >
                                <input
                                    v-if="isEditing"
                                    v-model="editValue.data[rowIndex + 1][colIndex]"
                                    class="w-full bg-transparent outline-none text-xs"
                                    @mousedown.stop
                                    @click.stop
                                    @focus.stop
                                />
                                <span v-else class="truncate text-gray-700 dark:text-primary-dt">{{ cell }}</span>
                            </td>
                        </tr>
                    </tbody>
                </table>
            </div>
            <!-- Placeholder para tabla vacía -->
            <div v-else class="flex flex-col items-center justify-center text-gray-400 dark:text-primary-dt/50 p-4">
                <GoogleIcon name="table_chart" class="text-2xl mb-1" />
                <span class="text-xs text-center">Doble clic para editar tabla</span>
            </div>
        </div>

        <!-- Controles del elemento -->
        <div
            v-if="isSelected && !isEditing"
            class="absolute -top-8 right-0 flex gap-1 opacity-100 transition-opacity z-10"
        >
            <!-- Indicador de tamaño -->
            <div class="px-2 py-1 bg-gray-800 text-white text-xs rounded shadow-sm pointer-events-none">
                {{ Math.round(element.width || 200) }} × {{ Math.round(element.height || 40) }}
            </div>

            <!-- Botón para cargar imagen (solo para elementos de imagen) -->
            <button
                v-if="element.type === 'image'"
                @click.stop="() => fileInput.click()"
                class="w-6 h-6 bg-blue-500 hover:bg-blue-600 text-white rounded text-xs flex items-center justify-center transition-colors shadow-sm"
                title="Cargar imagen"
            >
                <GoogleIcon name="upload" class="text-xs" />
            </button>

            <!-- Botón eliminar -->
            <button
                @click.stop="handleDelete"
                class="w-6 h-6 bg-red-500 hover:bg-red-600 text-white rounded text-xs flex items-center justify-center transition-colors shadow-sm"
                title="Eliminar"
            >
                <GoogleIcon name="close" class="text-xs" />
            </button>
        </div>

        <!-- Controles de redimensionamiento mejorados -->
        <div v-if="isSelected && !isEditing" class="absolute inset-0 pointer-events-none">
            <!-- Esquina inferior derecha -->
            <div
                @mousedown.stop="startResize"
                class="absolute -bottom-1 -right-1 w-2 h-2 bg-blue-500 border border-white cursor-se-resize pointer-events-auto rounded-sm resize-handle-corner"
                title="Redimensionar"
            ></div>

            <!-- Lado derecho -->
            <div
                @mousedown.stop="(event) => startResizeEdge(event, 'right')"
                class="absolute top-1 bottom-1 -right-0.5 w-1 bg-blue-500 opacity-0 cursor-e-resize pointer-events-auto resize-handle-edge"
                title="Redimensionar ancho"
            ></div>

            <!-- Lado inferior -->
            <div
                @mousedown.stop="(event) => startResizeEdge(event, 'bottom')"
                class="absolute -bottom-0.5 left-1 right-1 h-1 bg-blue-500 opacity-0 cursor-s-resize pointer-events-auto resize-handle-edge"
                title="Redimensionar alto"
            ></div>

            <!-- Puntos de agarre visuales en los bordes (solo visuales) -->
            <div class="absolute top-1/2 -right-0.5 w-1 h-6 -translate-y-1/2 bg-blue-500 opacity-30 rounded-full pointer-events-none resize-handle-visual"></div>
            <div class="absolute -bottom-0.5 left-1/2 w-6 h-1 -translate-x-1/2 bg-blue-500 opacity-30 rounded-full pointer-events-none resize-handle-visual"></div>
        </div>

        <!-- Indicador de arrastre -->
        <div
            v-if="isDragging"
            class="absolute inset-0 bg-blue-500 opacity-20 rounded pointer-events-none"
        ></div>

        <!-- Indicador de redimensionamiento -->
        <div
            v-if="isResizing"
            class="absolute inset-0 bg-green-500 opacity-20 rounded pointer-events-none"
        ></div>

        <!-- Tooltip con instrucciones -->
        <div
            v-if="isSelected && !element.content && element.type !== 'image' && !isResizing"
            class="absolute -bottom-8 left-0 bg-gray-900 text-white text-xs px-2 py-1 rounded whitespace-nowrap z-10"
        >
            {{ element.type === 'text' ? 'Doble clic para editar texto' : 'Doble clic para editar código' }}
            {{ element.type === 'code' ? ' (Ctrl+Enter para guardar)' : '' }}
        </div>

        <!-- Tooltip con instrucciones de redimensionamiento -->
        <div
            v-if="isSelected && !isEditing && element.type === 'image' && !element.content && !isResizing"  
            class="absolute -bottom-8 left-0 bg-gray-900 text-white text-xs px-2 py-1 rounded whitespace-nowrap z-10"
        >
            Arrastra las esquinas para redimensionar
        </div>

        <!-- Botón para terminar edición de tabla -->
        <div
            v-if="isEditing && element.type === 'table'"
            class="absolute -bottom-10 left-0 flex gap-2 z-20"
        >
            <button
                @click="finishEditing"
                class="px-3 py-1 bg-green-600 hover:bg-green-700 text-white text-xs rounded shadow-sm transition-colors"
            >
                Guardar (Ctrl+Enter)
            </button>
            <button
                @click="() => { isEditing = false; editValue = JSON.parse(JSON.stringify(element.content)); }"
                class="px-3 py-1 bg-gray-600 hover:bg-gray-700 text-white text-xs rounded shadow-sm transition-colors"
            >
                Cancelar (Esc)
            </button>
        </div>
    </div>
</template>

<style scoped>
/* Estilos para los controles de redimensionamiento mejorados */
.resize-handle-corner {
    transition: all 0.2s ease;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
}

.resize-handle-corner:hover {
    background-color: #2563eb;
    transform: scale(1.1);
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
}

.resize-handle-edge {
    transition: all 0.2s ease;
}

.resize-handle-edge:hover {
    opacity: 0.7 !important;
    background-color: #2563eb;
}

.resize-handle-visual {
    transition: all 0.2s ease;
}

/* Efecto hover para los indicadores visuales */
.group:hover .resize-handle-visual {
    opacity: 0.6 !important;
}

.group:hover .resize-handle-edge {
    opacity: 0.4 !important;
}

/* Prevenir selección de texto durante el redimensionamiento */
.select-none {
    user-select: none;
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
}

/* Animación suave para los controles */
@keyframes pulse-resize {
    0%, 100% {
        opacity: 0.3;
    }
    50% {
        opacity: 0.7;
    }
}

.group:hover .resize-handle-visual {
    animation: pulse-resize 2s infinite;
}
</style>