const video = document.getElementById('video');
const canvas = document.getElementById('canvas');
const loading = document.getElementById('loading');
const errorOverlay = document.getElementById('error-message');
const carousel = document.getElementById('glasses-carousel');
const captureBtn = document.getElementById('capture-btn');
const downloadBtn = document.getElementById('download-btn');
const prevGlassBtn = document.getElementById('prev-glass');
const nextGlassBtn = document.getElementById('next-glass');
const scaleSlider = document.getElementById('scale-slider');
const offsetSlider = document.getElementById('offset-slider');

let selectedGlassImg = null;
let activeGlassElement = null;
let capturedDataUrl = null;
let currentGlassIndex = 0;
let glassesElements = [];

// Dynamic Scale and Offset
let currentScaleFactor = parseFloat(scaleSlider.value);
let currentYOffset = parseFloat(offsetSlider.value);

scaleSlider.addEventListener('input', (e) => currentScaleFactor = parseFloat(e.target.value));
offsetSlider.addEventListener('input', (e) => currentYOffset = parseFloat(e.target.value));
async function init() {
    try {
        // 1. Load Face API models
        await Promise.all([
            faceapi.nets.tinyFaceDetector.loadFromUri('./models'),
            faceapi.nets.faceLandmark68Net.loadFromUri('./models')
        ]);
        
        // 2. Fetch glasses from backend
        await loadGlasses();
        
        // 3. Start Camera
        startCamera();
        
    } catch (err) {
        console.error("Initialization error:", err);
        loading.style.display = 'none';
        errorOverlay.style.display = 'flex';
        errorOverlay.innerHTML = `<p>Error initializing app: ${err.message}</p>`;
    }
}

async function loadGlasses() {
    try {
        const response = await fetch('api_glasses.php?_t=' + Date.now());
        const data = await response.json();
        
        carousel.innerHTML = ''; // Clear skeletons
        
        if (data.success && data.glasses && data.glasses.length > 0) {
            glassesElements = [];
            data.glasses.forEach((src, index) => {
                const item = document.createElement('div');
                item.className = 'glass-item';
                
                const img = new Image();
                img.src = src;
                item.appendChild(img);
                
                item.addEventListener('click', (e) => {
                    if (isDragging) {
                        e.preventDefault();
                        e.stopPropagation();
                        return;
                    }
                    currentGlassIndex = index;
                    selectGlass(item, img);
                });
                carousel.appendChild(item);
                glassesElements.push({ item, img });
                
                // Select first by default
                if (index === 0) {
                    currentGlassIndex = 0;
                    selectGlass(item, img);
                }
            });
        } else {
            carousel.innerHTML = '<p style="padding: 1rem; color: #94a3b8; font-size: 0.875rem;">No glasses uploaded yet. <a href="admin.php" style="color: #3b82f6;">Upload some!</a></p>';
        }
    } catch (err) {
        console.error("Error loading glasses:", err);
        carousel.innerHTML = '<p style="padding: 1rem; color: #ef4444; font-size: 0.875rem;">Failed to load glasses.</p>';
    }
}

function selectGlass(element, imgElement) {
    if (activeGlassElement) {
        activeGlassElement.classList.remove('active');
    }
    element.classList.add('active');
    activeGlassElement = element;
    selectedGlassImg = imgElement;
    
    // Scroll carousel to show selected item without causing page jump
    const scrollLeft = element.offsetLeft - (carousel.clientWidth / 2) + (element.clientWidth / 2);
    carousel.scrollTo({
        left: scrollLeft,
        behavior: 'smooth'
    });
}

// Drag to scroll functionality
let isDown = false;
let startX;
let scrollLeft;
let isDragging = false;

carousel.addEventListener('mousedown', (e) => {
    isDown = true;
    isDragging = false;
    startX = e.pageX - carousel.offsetLeft;
    scrollLeft = carousel.scrollLeft;
});

carousel.addEventListener('mouseleave', () => {
    isDown = false;
    setTimeout(() => { isDragging = false; }, 0);
});

carousel.addEventListener('mouseup', () => {
    isDown = false;
    setTimeout(() => { isDragging = false; }, 0);
});

carousel.addEventListener('mousemove', (e) => {
    if (!isDown) return;
    e.preventDefault();
    isDragging = true;
    const x = e.pageX - carousel.offsetLeft;
    const walk = (x - startX) * 2; // scroll speed multiplier
    carousel.scrollLeft = scrollLeft - walk;
});

function navigateGlass(direction) {
    if (glassesElements.length === 0) return;
    
    currentGlassIndex += direction;
    if (currentGlassIndex < 0) {
        currentGlassIndex = glassesElements.length - 1;
    } else if (currentGlassIndex >= glassesElements.length) {
        currentGlassIndex = 0;
    }
    
    const target = glassesElements[currentGlassIndex];
    selectGlass(target.item, target.img);
}

prevGlassBtn.addEventListener('click', () => navigateGlass(-1));
nextGlassBtn.addEventListener('click', () => navigateGlass(1));

// Keyboard navigation
document.addEventListener('keydown', (e) => {
    if (e.key === 'ArrowLeft') {
        navigateGlass(-1);
    } else if (e.key === 'ArrowRight') {
        navigateGlass(1);
    }
});

function startCamera() {
    navigator.mediaDevices.getUserMedia({ 
        video: { 
            width: { ideal: 720 },
            height: { ideal: 560 },
            facingMode: 'user'
        } 
    }).then(stream => {
        video.srcObject = stream;
    }).catch(err => {
        console.error("Camera error:", err);
        loading.style.display = 'none';
        errorOverlay.style.display = 'flex';
    });
}

video.addEventListener('play', () => {
    loading.style.display = 'none';
    
    // Set canvas dimensions to match video
    const displaySize = { width: video.width, height: video.height };
    faceapi.matchDimensions(canvas, displaySize);
    
    const ctx = canvas.getContext('2d');

    // Run rendering loop
    setInterval(async () => {
        const detections = await faceapi.detectSingleFace(video, new faceapi.TinyFaceDetectorOptions()).withFaceLandmarks();
        
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        
        if (detections && selectedGlassImg) {
            const resizedDetections = faceapi.resizeResults(detections, displaySize);
            const landmarks = resizedDetections.landmarks;
            
            // Get eye positions
            const leftEye = landmarks.getLeftEye();
            const rightEye = landmarks.getRightEye();
            
            // Calculate center of left and right eyes
            const leftEyeCenter = leftEye.reduce((acc, curr) => ({ x: acc.x + curr.x / leftEye.length, y: acc.y + curr.y / leftEye.length }), {x:0, y:0});
            const rightEyeCenter = rightEye.reduce((acc, curr) => ({ x: acc.x + curr.x / rightEye.length, y: acc.y + curr.y / rightEye.length }), {x:0, y:0});
            
            // Calculate distance and angle between eyes
            const eyeDist = Math.sqrt(Math.pow(rightEyeCenter.x - leftEyeCenter.x, 2) + Math.pow(rightEyeCenter.y - leftEyeCenter.y, 2));
            const angle = Math.atan2(rightEyeCenter.y - leftEyeCenter.y, rightEyeCenter.x - leftEyeCenter.x);
            
            // Calculate center point between the two eyes
            const faceCenterX = (leftEyeCenter.x + rightEyeCenter.x) / 2;
            const faceCenterY = (leftEyeCenter.y + rightEyeCenter.y) / 2;
            
            // Determine dimensions for glasses
            const nw = selectedGlassImg.naturalWidth;
            const nh = selectedGlassImg.naturalHeight;
            
            if (nw && nh) {
                const glassWidth = eyeDist * currentScaleFactor;
                const aspectRatio = nw / nh;
                const glassHeight = glassWidth / aspectRatio;
                
                // Apply offset (relative to eye distance)
                const offsetY = eyeDist * currentYOffset;
                
                // Draw glasses
                ctx.save();
                ctx.translate(faceCenterX, faceCenterY + offsetY);
                ctx.rotate(angle);
                ctx.drawImage(
                    selectedGlassImg, 
                    -glassWidth / 2, 
                    -glassHeight / 2, 
                    glassWidth, 
                    glassHeight
                );
                ctx.restore();
            }
        }
    }, 100);
});

// Capture snapshot
captureBtn.addEventListener('click', () => {
    // We need to composite video and canvas. 
    // And handle the mirroring since video is visually mirrored but its stream isn't.
    const compositeCanvas = document.createElement('canvas');
    compositeCanvas.width = video.videoWidth;
    compositeCanvas.height = video.videoHeight;
    const ctx = compositeCanvas.getContext('2d');
    
    // Mirror drawing
    ctx.translate(compositeCanvas.width, 0);
    ctx.scale(-1, 1);
    
    // Draw video frame
    ctx.drawImage(video, 0, 0, compositeCanvas.width, compositeCanvas.height);
    
    // Draw AR canvas
    ctx.drawImage(canvas, 0, 0, compositeCanvas.width, compositeCanvas.height);
    
    // Store and enable download
    capturedDataUrl = compositeCanvas.toDataURL('image/png');
    downloadBtn.disabled = false;
    
    // Visual feedback
    captureBtn.style.background = '#10b981';
    captureBtn.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"></polyline></svg>';
    setTimeout(() => {
        captureBtn.style.background = '';
        captureBtn.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="13" r="4"></circle><path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"></path></svg>';
    }, 1500);
});

// Download snapshot
downloadBtn.addEventListener('click', () => {
    if (capturedDataUrl) {
        const a = document.createElement('a');
        a.href = capturedDataUrl;
        a.download = `snapglass-${Date.now()}.png`;
        a.click();
    }
});

// Start app
init();
