import { showLoader, hideLoader, showAlert } from '../ui.js';
import { getPDFDocument } from '../utils/helpers.js';
import { icons, createIcons } from 'lucide';
import * as pdfjsLib from 'pdfjs-dist';

pdfjsLib.GlobalWorkerOptions.workerSrc = new URL('pdfjs-dist/build/pdf.worker.min.mjs', import.meta.url).toString();

interface CompareState {
    pdfDoc1: pdfjsLib.PDFDocumentProxy | null;
    pdfDoc2: pdfjsLib.PDFDocumentProxy | null;
    currentPage: number;
    viewMode: 'overlay' | 'side-by-side';
    isSyncScroll: boolean;
}

const pageState: CompareState = {
    pdfDoc1: null,
    pdfDoc2: null,
    currentPage: 1,
    viewMode: 'overlay',
    isSyncScroll: true,
};

async function renderPage(
    pdfDoc: pdfjsLib.PDFDocumentProxy,
    pageNum: number,
    canvas: HTMLCanvasElement,
    container: HTMLElement
) {
    const page = await pdfDoc.getPage(pageNum);

    const containerWidth = container.clientWidth - 2;
    const viewport = page.getViewport({ scale: 1.0 });
    const scale = containerWidth / viewport.width;
    const scaledViewport = page.getViewport({ scale: scale });

    canvas.width = scaledViewport.width;
    canvas.height = scaledViewport.height;

    await page.render({
        canvasContext: canvas.getContext('2d')!,
        viewport: scaledViewport,
        canvas
    }).promise;
}

async function renderBothPages() {
    if (!pageState.pdfDoc1 || !pageState.pdfDoc2) return;

    showLoader(`Loading page ${pageState.currentPage}...`);

    const canvas1 = document.getElementById('canvas-compare-1') as HTMLCanvasElement;
    const canvas2 = document.getElementById('canvas-compare-2') as HTMLCanvasElement;
    const panel1 = document.getElementById('panel-1') as HTMLElement;
    const panel2 = document.getElementById('panel-2') as HTMLElement;
    const wrapper = document.getElementById('compare-viewer-wrapper') as HTMLElement;

    const container1 = pageState.viewMode === 'overlay' ? wrapper : panel1;
    const container2 = pageState.viewMode === 'overlay' ? wrapper : panel2;

    await Promise.all([
        renderPage(
            pageState.pdfDoc1,
            Math.min(pageState.currentPage, pageState.pdfDoc1.numPages),
            canvas1,
            container1
        ),
        renderPage(
            pageState.pdfDoc2,
            Math.min(pageState.currentPage, pageState.pdfDoc2.numPages),
            canvas2,
            container2
        ),
    ]);

    updateNavControls();
    hideLoader();
}

function updateNavControls() {
    const maxPages = Math.max(
        pageState.pdfDoc1?.numPages || 0,
        pageState.pdfDoc2?.numPages || 0
    );
    const currentDisplay = document.getElementById('current-page-display-compare');
    const totalDisplay = document.getElementById('total-pages-display-compare');
    const prevBtn = document.getElementById('prev-page-compare') as HTMLButtonElement;
    const nextBtn = document.getElementById('next-page-compare') as HTMLButtonElement;

    if (currentDisplay) currentDisplay.textContent = pageState.currentPage.toString();
    if (totalDisplay) totalDisplay.textContent = maxPages.toString();
    if (prevBtn) prevBtn.disabled = pageState.currentPage <= 1;
    if (nextBtn) nextBtn.disabled = pageState.currentPage >= maxPages;
}

function setViewMode(mode: 'overlay' | 'side-by-side') {
    pageState.viewMode = mode;
    const wrapper = document.getElementById('compare-viewer-wrapper');
    const overlayControls = document.getElementById('overlay-controls');
    const sideControls = document.getElementById('side-by-side-controls');
    const btnOverlay = document.getElementById('view-mode-overlay');
    const btnSide = document.getElementById('view-mode-side');
    const canvas2 = document.getElementById('canvas-compare-2') as HTMLCanvasElement;
    const opacitySlider = document.getElementById('opacity-slider') as HTMLInputElement;

    if (mode === 'overlay') {
        if (wrapper) wrapper.className = 'compare-viewer-wrapper overlay-mode bg-gray-900 rounded-lg border border-gray-700 min-h-[400px] relative';
        if (overlayControls) overlayControls.classList.remove('hidden');
        if (sideControls) sideControls.classList.add('hidden');
        if (btnOverlay) {
            btnOverlay.classList.add('bg-indigo-600');
            btnOverlay.classList.remove('bg-gray-700');
        }
        if (btnSide) {
            btnSide.classList.remove('bg-indigo-600');
            btnSide.classList.add('bg-gray-700');
        }
        if (canvas2 && opacitySlider) canvas2.style.opacity = opacitySlider.value;
    } else {
        if (wrapper) wrapper.className = 'compare-viewer-wrapper side-by-side-mode bg-gray-900 rounded-lg border border-gray-700 min-h-[400px]';
        if (overlayControls) overlayControls.classList.add('hidden');
        if (sideControls) sideControls.classList.remove('hidden');
        if (btnOverlay) {
            btnOverlay.classList.remove('bg-indigo-600');
            btnOverlay.classList.add('bg-gray-700');
        }
        if (btnSide) {
            btnSide.classList.add('bg-indigo-600');
            btnSide.classList.remove('bg-gray-700');
        }
        if (canvas2) canvas2.style.opacity = '1';
    }
    renderBothPages();
}

async function handleFileInput(inputId: string, docKey: 'pdfDoc1' | 'pdfDoc2', displayId: string) {
    const fileInput = document.getElementById(inputId) as HTMLInputElement;
    const dropZone = document.getElementById(`drop-zone-${inputId.slice(-1)}`);

    async function handleFile(file: File) {
        if (!file || file.type !== 'application/pdf') {
            showAlert('Invalid File', 'Please select a valid PDF file.');
            return;
        }

        const displayDiv = document.getElementById(displayId);
        if (displayDiv) {
            displayDiv.innerHTML = '';

            const icon = document.createElement('i');
            icon.setAttribute('data-lucide', 'check-circle');
            icon.className = 'w-10 h-10 mb-3 text-green-500';

            const p = document.createElement('p');
            p.className = 'text-sm text-gray-300 truncate';
            p.textContent = file.name;

            displayDiv.append(icon, p);
            createIcons({ icons });
        }

        try {
            showLoader(`Loading ${file.name}...`);
            const arrayBuffer = await file.arrayBuffer();
            pageState[docKey] = await getPDFDocument({ data: arrayBuffer }).promise;

            if (pageState.pdfDoc1 && pageState.pdfDoc2) {
                const compareViewer = document.getElementById('compare-viewer');
                if (compareViewer) compareViewer.classList.remove('hidden');
                pageState.currentPage = 1;
                await renderBothPages();
            }
        } catch (e) {
            showAlert('Error', 'Could not load PDF. It may be corrupt or password-protected.');
            console.error(e);
        } finally {
            hideLoader();
        }
    }

    if (fileInput) {
        fileInput.addEventListener('change', function (e) {
            const files = (e.target as HTMLInputElement).files;
            if (files && files[0]) handleFile(files[0]);
        });
    }

    if (dropZone) {
        dropZone.addEventListener('dragover', function (e) {
            e.preventDefault();
        });
        dropZone.addEventListener('drop', function (e) {
            e.preventDefault();
            const files = e.dataTransfer?.files;
            if (files && files[0]) handleFile(files[0]);
        });
    }
}

document.addEventListener('DOMContentLoaded', function () {
    const backBtn = document.getElementById('back-to-tools');

    if (backBtn) {
        backBtn.addEventListener('click', function () {
            window.location.href = import.meta.env.BASE_URL;
        });
    }

    handleFileInput('file-input-1', 'pdfDoc1', 'file-display-1');
    handleFileInput('file-input-2', 'pdfDoc2', 'file-display-2');

    const prevBtn = document.getElementById('prev-page-compare');
    const nextBtn = document.getElementById('next-page-compare');

    if (prevBtn) {
        prevBtn.addEventListener('click', function () {
            if (pageState.currentPage > 1) {
                pageState.currentPage--;
                renderBothPages();
            }
        });
    }

    if (nextBtn) {
        nextBtn.addEventListener('click', function () {
            const maxPages = Math.max(
                pageState.pdfDoc1?.numPages || 0,
                pageState.pdfDoc2?.numPages || 0
            );
            if (pageState.currentPage < maxPages) {
                pageState.currentPage++;
                renderBothPages();
            }
        });
    }

    const btnOverlay = document.getElementById('view-mode-overlay');
    const btnSide = document.getElementById('view-mode-side');

    if (btnOverlay) {
        btnOverlay.addEventListener('click', function () {
            setViewMode('overlay');
        });
    }

    if (btnSide) {
        btnSide.addEventListener('click', function () {
            setViewMode('side-by-side');
        });
    }

    const flickerBtn = document.getElementById('flicker-btn');
    const canvas2 = document.getElementById('canvas-compare-2') as HTMLCanvasElement;
    const opacitySlider = document.getElementById('opacity-slider') as HTMLInputElement;

    // Track flicker state
    let flickerVisible = true;

    if (flickerBtn && canvas2) {
        flickerBtn.addEventListener('click', function () {
            flickerVisible = !flickerVisible;
            canvas2.style.transition = 'opacity 150ms ease-in-out';
            canvas2.style.opacity = flickerVisible ? (opacitySlider?.value || '0.5') : '0';
        });
    }

    if (opacitySlider && canvas2) {
        opacitySlider.addEventListener('input', function () {
            flickerVisible = true; // Reset flicker state when slider changes
            canvas2.style.transition = '';
            canvas2.style.opacity = opacitySlider.value;
        });
    }

    const panel1 = document.getElementById('panel-1');
    const panel2 = document.getElementById('panel-2');
    const syncToggle = document.getElementById('sync-scroll-toggle') as HTMLInputElement;

    if (syncToggle) {
        syncToggle.addEventListener('change', function () {
            pageState.isSyncScroll = syncToggle.checked;
        });
    }

    let scrollingPanel: HTMLElement | null = null;

    if (panel1 && panel2) {
        panel1.addEventListener('scroll', function () {
            if (pageState.isSyncScroll && scrollingPanel !== panel2) {
                scrollingPanel = panel1;
                panel2.scrollTop = panel1.scrollTop;
                setTimeout(function () { scrollingPanel = null; }, 100);
            }
        });

        panel2.addEventListener('scroll', function () {
            if (pageState.isSyncScroll && scrollingPanel !== panel1) {
                scrollingPanel = panel2;
                panel1.scrollTop = panel2.scrollTop;
                setTimeout(function () { scrollingPanel = null; }, 100);
            }
        });
    }

    createIcons({ icons });
});
