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,
    };

    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 performSwipe = (direction) => {
        if (!state.currentImageInfo) return;

        card.classList.add(`swipe-${direction}`);
        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);

        setTimeout(() => {
            card.classList.remove(`swipe-${direction}`);
            loadNewImage();
        }, 500);
    };

    const recordSelection = async (imageInfo, action) => {
        try {
            const response = await fetch('/selection', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({
                    image_path: imageInfo.path,
                    action,
                }),
            });
            if (!response.ok) {
                console.error('Error recording selection. Status:', response.status);
            } else {
                const data = await response.json();
                console.log('Selection recorded:', data);
            }
        } catch (err) {
            console.error('Error recording selection:', err);
        }
    };

    const loadNewImage = () => {
        if (state.isLoading) return;
        state.isLoading = true;
        card.classList.add('loading');

        const params = new URLSearchParams({
            orientation: state.currentOrientation.join(','),
            t: new Date().getTime(),
        });

        // NSFW param
        params.append('allow_nsfw', state.allowNsfw ? '1' : '0');

        if (state.searchKeywords.length > 0) {
            params.append('search', state.searchKeywords.join(','));
        }

        if (state.currentActions.length > 0) {
            params.append('actions', state.currentActions.join(','));
        }

        fetch(`/random-image?${params.toString()}`)
            .then(response => response.json())
            .then(data => {
                state.isLoading = false;
                // card.classList.remove('loading'); // moved to image load handler
                if (data && data.path) {
                    state.currentImageInfo = data;
                    const cardImage = card.querySelector('img');
                    // Use load event to ensure indicator hides after image fully loads
                    cardImage.onload = () => {
                        card.classList.remove('loading');
                    };
                    cardImage.src = data.path;
                    updateImageInfo(data);
                    adjustContainerToImage(data.orientation);
                } else {
                    const placeholder = 'static/no-image.png';
                    const imgEl = card.querySelector('img');
                    if (imgEl) {
                        imgEl.onload = () => card.classList.remove('loading');
                        imgEl.src = placeholder;
                    }
                    updateImageInfo({ filename:'No image', creation_date:'', resolution:'', prompt_data:''});
                    state.currentImageInfo = null; // disables swipe actions
                }
            })
            .catch(error => {
                console.error('Error fetching image:', error);
                state.isLoading = false;
                card.classList.remove('loading');
                card.innerHTML = '<div class="no-images-message">Error loading image.</div>';
            });
    };

    const adjustContainerToImage = (orientation) => {
        const container = document.querySelector('.swipe-container');
        if (window.innerWidth < 992) { // Only on desktop
            container.style.transition = 'all 0.5s ease-in-out';
            if (orientation === 'landscape') {
                container.style.flex = '4';
            } else {
                container.style.flex = '2';
            }
        }
    };

    const handlePointerDown = (x, y) => {
        state.isDragging = true;
        state.startX = x;
        state.startY = y;
        state.hasMoved = false;
        state.touchStartTime = Date.now();
        card.classList.add('swiping');
    };

    const handlePointerMove = (x, y) => {
        if (!state.isDragging) return;

        state.moveX = x - state.startX;
        state.moveY = y - state.startY;

        if (Math.abs(state.moveX) > 10 || Math.abs(state.moveY) > 10) {
            state.hasMoved = true;
        }

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

    const handlePointerUp = () => {
        if (!state.isDragging) return;
        state.isDragging = false;
        card.classList.remove('swiping');

        const absX = Math.abs(state.moveX);
        const absY = Math.abs(state.moveY);

        if (state.hasMoved && (absX > SWIPE_THRESHOLD || absY > SWIPE_THRESHOLD)) {
            if (absX > absY) {
                performSwipe(state.moveX > 0 ? 'right' : 'left');
            } else {
                performSwipe(state.moveY > 0 ? 'down' : 'up');
            }
        } else {
            card.style.transform = '';
        }

        state.moveX = 0;
        state.moveY = 0;
    };

    card.addEventListener('mousedown', e => handlePointerDown(e.clientX, e.clientY));
    document.addEventListener('mousemove', e => handlePointerMove(e.clientX, e.clientY));
    document.addEventListener('mouseup', () => handlePointerUp());

    card.addEventListener('touchstart', e => handlePointerDown(e.touches[0].clientX, e.touches[0].clientY), { passive: true });
    card.addEventListener('touchmove', e => handlePointerMove(e.touches[0].clientX, e.touches[0].clientY), { passive: true });
    card.addEventListener('touchend', () => handlePointerUp());

    document.getElementById('btn-left').addEventListener('click', () => performSwipe('left'));
    document.getElementById('btn-right').addEventListener('click', () => performSwipe('right'));
    document.getElementById('btn-up').addEventListener('click', () => performSwipe('up'));
    document.getElementById('btn-down').addEventListener('click', () => performSwipe('down'));

    document.addEventListener('keydown', (e) => {
        if (state.isLoading || document.activeElement === searchInput) return;

        const keyMap = {
            ArrowLeft: 'left',
            ArrowRight: 'right',
            ArrowUp: 'up',
            ArrowDown: 'down',
        };

        if (keyMap[e.key]) {
            e.preventDefault(); // Prevent scrolling
            performSwipe(keyMap[e.key]);
        }
    });

    orientationFilters.addEventListener('click', (e) => {
        const button = e.target.closest('button');
        if (!button) return;

        const clickedOrientation = button.dataset.orientation;
        
        if (clickedOrientation === 'all') {
            state.currentOrientation = ['all'];
        } else {
            // If 'all' was the only active filter, start a new selection
            if (state.currentOrientation.length === 1 && state.currentOrientation[0] === 'all') {
                state.currentOrientation = [];
            }

            const index = state.currentOrientation.indexOf(clickedOrientation);
            if (index > -1) {
                // Already selected, so deselect
                state.currentOrientation.splice(index, 1);
            } else {
                // Not selected, so select
                state.currentOrientation.push(clickedOrientation);
            }
        }

        // If no filters are selected after interaction, default to 'all'
        if (state.currentOrientation.length === 0) {
            state.currentOrientation = ['all'];
        }
        
        // Update UI based on the state
        orientationFilters.querySelectorAll('button').forEach(btn => {
            if (state.currentOrientation.includes(btn.dataset.orientation)) {
                btn.classList.add('active');
            } else {
                btn.classList.remove('active');
            }
        });

        loadNewImage();
    });

    actionFilters.addEventListener('click', (e) => {
        const button = e.target.closest('button');
        if (!button) return;

        const clickedAction = button.dataset.action;
        
        if (state.currentActions.length === 1 && state.currentActions[0] === 'Unactioned' && clickedAction !== 'Unactioned') {
            state.currentActions = [];
        }

        const index = state.currentActions.indexOf(clickedAction);
        if (index > -1) {
            state.currentActions.splice(index, 1);
        } else {
            state.currentActions.push(clickedAction);
        }

        if (state.currentActions.length === 0) {
            state.currentActions = ['Unactioned'];
        }

        actionFilters.querySelectorAll('button').forEach(btn => {
            if (state.currentActions.includes(btn.dataset.action)) {
                btn.classList.add('active');
            } else {
                btn.classList.remove('active');
            }
        });

        loadNewImage();
    });

    const renderKeywordPills = () => {
        keywordPillsContainer.innerHTML = '';
        state.searchKeywords.forEach(keyword => {
            const pill = document.createElement('div');
            pill.className = 'keyword-pill';
            pill.textContent = keyword;

            const removeBtn = document.createElement('button');
            removeBtn.className = 'remove-keyword';
            removeBtn.innerHTML = '&times;';
            removeBtn.dataset.keyword = keyword;
            pill.appendChild(removeBtn);

            keywordPillsContainer.appendChild(pill);
        });
    };

    const addSearchKeyword = () => {
        const newKeyword = searchInput.value.trim();
        if (newKeyword && !state.searchKeywords.includes(newKeyword)) {
            state.searchKeywords.push(newKeyword);
            renderKeywordPills();
            loadNewImage();
        }
        searchInput.value = '';
        searchInput.focus();
    };

    searchButton.addEventListener('click', addSearchKeyword);

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

    keywordPillsContainer.addEventListener('click', (e) => {
        if (e.target.classList.contains('remove-keyword')) {
            const keywordToRemove = e.target.dataset.keyword;
            state.searchKeywords = state.searchKeywords.filter(k => k !== keywordToRemove);
            renderKeywordPills();
            loadNewImage();
        }
    });

    card.addEventListener('click', () => {
        if (!state.hasMoved && state.currentImageInfo) {
            fullscreenImage.src = state.currentImageInfo.path;
            document.getElementById('modal-resolution').textContent = `Resolution: ${state.currentImageInfo.resolution}`;
            document.getElementById('modal-filename').textContent = `Filename: ${state.currentImageInfo.filename || 'N/A'}`;
            document.getElementById('modal-creation-date').textContent = `Creation Date: ${state.currentImageInfo.creation_date || 'N/A'}`;
            document.getElementById('modal-prompt-data').textContent = `Prompt: ${state.currentImageInfo.prompt_data || 'N/A'}`;
            modal.style.display = 'flex';
        }
    });

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

    document.addEventListener('keydown', (e) => {
        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
});
