import { showToast, updateImageInfo } from './utils.js';

document.addEventListener('DOMContentLoaded', () => {
    const state = {
        currentImageInfo: null,
        currentOrientation: ['all'],
        currentActions: ['Unactioned'],
        previousOrientation: ['all'],
        allowNsfw: false,
        searchKeywords: [],
        isLoading: false,
        isDragging: false,
        startX: 0,
        startY: 0,
        moveX: 0,
        moveY: 0,
        touchStartTime: 0,
        hasMoved: false,
        isAnimating: false, // Flag to prevent actions during animation
    };

    const card = document.getElementById('current-card');
    const lastActionText = document.getElementById('last-action');
    const orientationFilters = document.querySelector('.orientation-filters');
    const actionFilters = document.querySelector('.action-filters');
    const modal = document.getElementById('fullscreen-modal');
    const fullscreenImage = document.getElementById('fullscreen-image');
    const closeModal = document.querySelector('.close-modal');
    const searchInput = document.getElementById('search-input');
    const nsfwToggleBtn = document.getElementById('toggle-nsfw');
    const searchButton = document.getElementById('search-button');
    const keywordPillsContainer = document.getElementById('keyword-pills-container');

    const SWIPE_THRESHOLD = 100;
    const ACTION_ANGLE_THRESHOLD = 15; // Degrees of rotation to commit to swipe

    function resetCardPosition(animated = true) {
        if (state.isAnimating && animated) return;
        
        card.style.transition = animated ? 'transform 0.4s cubic-bezier(0.25, 0.8, 0.25, 1)' : 'none';
        card.style.transform = 'translate(0, 0) rotate(0deg)';
        
        if (animated) {
            state.isAnimating = true;
            card.addEventListener('transitionend', () => {
                state.isAnimating = false;
                card.style.transition = 'none';
            }, { once: true });
        } else {
            card.style.transition = 'none';
        }
    }

    const performSwipe = (direction) => {
        if (!state.currentImageInfo || state.isAnimating) return;

        state.isAnimating = true;
        
        const actionNameMap = { left: 'Discarded', right: 'Kept', up: 'Favourited', down: 'Reviewing' };
        const actionName = actionNameMap[direction] || direction;
        lastActionText.textContent = `Last action: ${actionName}`;
        const toastMap = { left: 'Discarded', right: 'Kept', up: 'Favourited', down: 'Reviewing' };
        showToast(toastMap[direction] || 'Action');

        recordSelection(state.currentImageInfo, actionName);

        // Animate swipe out
        let rotation, translateX, translateY;
        const windowWidth = window.innerWidth;
        const windowHeight = window.innerHeight;

        switch (direction) {
            case 'left':
                rotation = -30;
                translateX = -windowWidth;
                translateY = state.moveY;
                break;
            case 'right':
                rotation = 30;
                translateX = windowWidth;
                translateY = state.moveY;
                break;
            case 'up':
                rotation = 0;
                translateX = state.moveX;
                translateY = -windowHeight;
                break;
            case 'down':
                rotation = 0;
                translateX = state.moveX;
                translateY = windowHeight;
                break;
        }

        card.style.transition = 'transform 0.5s cubic-bezier(0.6, -0.28, 0.735, 0.045)';
        card.style.transform = `translate(${translateX}px, ${translateY}px) rotate(${rotation}deg)`;

        card.addEventListener('transitionend', () => {
            loadNewImage();
            state.isAnimating = false;
        }, { once: true });
    };

    async function getNextImage() {
        const queryParams = new URLSearchParams({
            orientation: state.currentOrientation.join(','),
            actions: state.currentActions.join(','),
            nsfw: state.allowNsfw,
            keywords: state.searchKeywords.join(','),
        }).toString();

        const response = await fetch(`/next-image?${queryParams}`);
        if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
        }
        return await response.json();
    }

    function recordSelection(imageInfo, action) {
        fetch('/record-selection', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ filename: imageInfo.filename, action: action }),
        }).catch(error => console.error('Failed to record selection:', error));
    }

    function handleNoImageAvailable() {
        const imageElement = card.querySelector('img');
        imageElement.src = `data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%22400%22%20height%3D%22400%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Crect%20width%3D%22400%22%20height%3D%22400%22%20fill%3D%22%23e0e0e0%22%2F%3E%3Ctext%20x%3D%22200%22%20y%3D%22200%22%20font-size%3D%2220%22%20text-anchor%3D%22middle%22%20alignment-baseline%3D%22middle%22%20fill%3D%22%23999%22%3ENo%20images%20found%3C%2Ftext%3E%3C%2Fsvg%3E`;
        state.currentImageInfo = null;
        updateImageInfo(null);
        showToast('No more images matching your criteria.', 'info');
    }

    async function loadNewImage() {
        if (state.isLoading) return;
        resetCardPosition(false); // Reset position without animation for new image
        state.isLoading = true;
        const loadingIndicator = card.querySelector('.loading-indicator');
        loadingIndicator.style.display = 'block';

        try {
            const data = await getNextImage();
            if (data && data.image_data) {
                const imageUrl = `data:image/jpeg;base64,${data.image_data}`;
                const imageElement = card.querySelector('img');
                imageElement.src = imageUrl;
                state.currentImageInfo = data;
                updateImageInfo(data);
            } else {
                handleNoImageAvailable();
            }
        } catch (error) {
            console.error('Error loading image:', error);
            showToast('Failed to load image.', 'error');
            handleNoImageAvailable();
        } finally {
            state.isLoading = false;
            loadingIndicator.style.display = 'none';
        }
    }

    // --- Event Listeners ---

    // Swipe and Drag
    card.addEventListener('mousedown', onDragStart);
    card.addEventListener('touchstart', onDragStart, { passive: true });

    function onDragStart(e) {
        if (state.isLoading || state.isAnimating) return;
        state.isDragging = true;
        state.hasMoved = false;
        card.style.transition = 'none';
        state.startX = e.clientX || e.touches[0].clientX;
        state.startY = e.clientY || e.touches[0].clientY;
        state.touchStartTime = Date.now();
        document.addEventListener('mousemove', onDragMove);
        document.addEventListener('touchmove', onDragMove, { passive: false });
        document.addEventListener('mouseup', onDragEnd);
        document.addEventListener('touchend', onDragEnd);
    }

    function onDragMove(e) {
        if (!state.isDragging) return;
        e.preventDefault();
        state.hasMoved = true;
        
        const currentX = e.clientX || e.touches[0].clientX;
        const currentY = e.clientY || e.touches[0].clientY;
        
        state.moveX = currentX - state.startX;
        state.moveY = currentY - state.startY;

        const rotation = state.moveX * 0.1;
        card.style.transform = `translate(${state.moveX}px, ${state.moveY}px) rotate(${rotation}deg)`;
    }

    function onDragEnd() {
        if (!state.isDragging) return;
        state.isDragging = false;

        document.removeEventListener('mousemove', onDragMove);
        document.removeEventListener('touchmove', onDragMove);
        document.removeEventListener('mouseup', onDragEnd);
        document.removeEventListener('touchend', onDragEnd);

        if (!state.hasMoved) return;

        const rotation = state.moveX * 0.1;

        if (Math.abs(rotation) > ACTION_ANGLE_THRESHOLD || Math.abs(state.moveX) > SWIPE_THRESHOLD || Math.abs(state.moveY) > SWIPE_THRESHOLD) {
            const angle = Math.atan2(state.moveY, state.moveX) * 180 / Math.PI;
            let direction;
            if (angle > -45 && angle <= 45) {
                direction = 'right';
            } else if (angle > 45 && angle <= 135) {
                direction = 'down';
            } else if (angle > 135 || angle <= -135) {
                direction = 'left';
            } else if (angle > -135 && angle <= -45) {
                direction = 'up';
            }
            performSwipe(direction);
        } else {
            resetCardPosition();
        }
        
        state.moveX = 0;
        state.moveY = 0;
    }

    // Filter buttons
    orientationFilters.addEventListener('click', (e) => {
        const button = e.target.closest('button');
        if (!button) return;
        state.currentOrientation = [button.dataset.value];
        loadNewImage();
    });

    actionFilters.addEventListener('click', (e) => {
        const button = e.target.closest('button');
        if (!button) return;
        state.currentActions = [button.dataset.value];
        loadNewImage();
    });

    // Modal
    card.addEventListener('click', (e) => {
        if (!state.hasMoved && state.currentImageInfo) {
            fullscreenImage.src = card.querySelector('img').src;
            modal.style.display = 'flex';
        }
    });

    closeModal.addEventListener('click', () => {
        modal.style.display = 'none';
    });

    window.addEventListener('click', (e) => {
        if (e.target === modal) {
            modal.style.display = 'none';
        }
    });

    // Search
    const addKeyword = () => {
        const keyword = searchInput.value.trim();
        if (keyword && !state.searchKeywords.includes(keyword)) {
            state.searchKeywords.push(keyword);
            renderKeywordPills();
            searchInput.value = '';
        }
    };

    const removeKeyword = (keywordToRemove) => {
        state.searchKeywords = state.searchKeywords.filter(k => k !== keywordToRemove);
        renderKeywordPills();
    };

    const renderKeywordPills = () => {
        keywordPillsContainer.innerHTML = '';
        state.searchKeywords.forEach(keyword => {
            const pill = document.createElement('div');
            pill.className = 'keyword-pill';
            pill.textContent = keyword;
            const removeBtn = document.createElement('span');
            removeBtn.textContent = 'x';
            removeBtn.onclick = () => removeKeyword(keyword);
            pill.appendChild(removeBtn);
            keywordPillsContainer.appendChild(pill);
        });
    };

    searchInput.addEventListener('keydown', (e) => {
        if (e.key === 'Enter') {
            addKeyword();
        }
    });

    searchButton.addEventListener('click', () => {
        loadNewImage();
    });

    // Keyboard shortcuts
    document.addEventListener('keydown', (e) => {
        if (searchInput === document.activeElement) return;

        if (modal.style.display === 'flex' && e.key === 'Escape') {
            modal.style.display = 'none';
            return;
        }
        if (modal.style.display !== 'flex') {
            switch (e.key) {
                case 'ArrowLeft': performSwipe('left'); break;
                case 'ArrowRight': performSwipe('right'); break;
                case 'ArrowUp': performSwipe('up'); break;
                case 'ArrowDown': performSwipe('down'); break;
            }
        }
    });

    // --- Ultra-wide mode ---
    const fullscreenToggle = document.getElementById('fullscreen-toggle');
    fullscreenToggle.setAttribute('title', 'Toggle fullscreen Mode');

    const setfullscreenMode = (isActive) => {
        if (isActive) {
            // Entering ultra-wide mode: just disable filter controls
            orientationFilters.style.pointerEvents = 'none';
            orientationFilters.style.opacity = '0.5';
        } else {
            // Exiting ultra-wide mode: re-enable filter controls
            orientationFilters.style.pointerEvents = 'auto';
            orientationFilters.style.opacity = '1';
        }
    };

    fullscreenToggle.addEventListener('click', () => {
        const isActive = document.body.classList.toggle('fullscreen-mode');
        localStorage.setItem('fullscreenMode', isActive);
        showToast(isActive ? 'fullscreen mode enabled' : 'fullscreen mode disabled');
        setfullscreenMode(isActive);
    });

    // Check for saved preference on load
    const isfullscreenModeOnLoad = localStorage.getItem('fullscreenMode') === 'true';
    if (isfullscreenModeOnLoad) {
        document.body.classList.add('fullscreen-mode');
        setfullscreenMode(true);
    }

    // --- NSFW toggle ---
    nsfwToggleBtn.addEventListener('click', () => {
        state.allowNsfw = !state.allowNsfw;
        nsfwToggleBtn.dataset.allow = state.allowNsfw ? '1' : '0';
        nsfwToggleBtn.classList.toggle('active', state.allowNsfw);
        loadNewImage();
    });

    loadNewImage(); // Always load an image on startup
});
