(function () {
    const logs = [];
    const MAX_LOGS = 200;
    let bugModal = null;
    let screenshotDataUrl = null;
    let pendingScreenshotPromise = null;
    let isCapturingDisplayMedia = false;
    let html2canvasLoaderPromise = null;

    const pushLog = (type, args) => {
        try {
            logs.push({
                type,
                message: (args || []).map((x) => {
                    if (typeof x === 'string') return x;
                    try {
                        return JSON.stringify(x);
                    } catch (_) {
                        return String(x);
                    }
                }).join(' '),
                timestamp: new Date().toISOString()
            });
            if (logs.length > MAX_LOGS) {
                logs.splice(0, logs.length - MAX_LOGS);
            }
        } catch (_) {
            // no-op
        }
    };

    ['log', 'warn', 'error'].forEach((type) => {
        const original = console[type];
        console[type] = function (...args) {
            pushLog(type, args);
            original.apply(console, args);
        };
    });

    window.addEventListener('error', (event) => {
        logs.push({
            type: 'error',
            message: event.message,
            url: event.filename,
            line: event.lineno,
            col: event.colno,
            timestamp: new Date().toISOString()
        });
        if (logs.length > MAX_LOGS) {
            logs.splice(0, logs.length - MAX_LOGS);
        }
    });

    function getCurrentUser() {
        const metaUser = document.querySelector('meta[name="user-id"]');
        const userFromMeta = metaUser ? metaUser.getAttribute('content') : null;
        let userFromToken = null;
        const token = localStorage.getItem('access_token');
        if (token) {
            try {
                const payload = JSON.parse(atob(token.split('.')[1]));
                userFromToken = payload.sub || payload.user_id || null;
            } catch (_) {
                userFromToken = null;
            }
        }
        return userFromToken || userFromMeta || null;
    }

    function getMetadata() {
        return {
            url: window.location.href,
            userAgent: navigator.userAgent,
            timestamp: new Date().toISOString(),
            screenSize: `${window.innerWidth}x${window.innerHeight}`,
            user: getCurrentUser(),
        };
    }

    async function toDataUrl(file) {
        return new Promise((resolve, reject) => {
            const reader = new FileReader();
            reader.onload = () => resolve(String(reader.result || ''));
            reader.onerror = reject;
            reader.readAsDataURL(file);
        });
    }

    async function withTimeout(promise, ms, timeoutMessage) {
        let timer = null;
        try {
            return await Promise.race([
                promise,
                new Promise((_, reject) => {
                    timer = setTimeout(() => reject(new Error(timeoutMessage || 'Operation timed out')), ms);
                }),
            ]);
        } finally {
            if (timer) clearTimeout(timer);
        }
    }

    function isCrossOriginUrl(url) {
        try {
            if (!url) return false;
            const parsed = new URL(url, window.location.href);
            return parsed.origin !== window.location.origin;
        } catch (_) {
            return false;
        }
    }

    function shouldIgnoreInScreenshot(el) {
        if (!el || !el.tagName) return false;
        const tag = String(el.tagName).toUpperCase();

        if (tag === 'IFRAME' || tag === 'VIDEO' || tag === 'OBJECT' || tag === 'EMBED') {
            return true;
        }

        if (tag === 'IMG') {
            const src = el.getAttribute('src') || '';
            return isCrossOriginUrl(src);
        }

        return false;
    }

    async function renderScreenshot(target, opts) {
        const canvas = await window.html2canvas(target, opts);
        return canvas.toDataURL('image/png');
    }

    async function ensureHtml2Canvas() {
        if (window.html2canvas) {
            return;
        }

        if (!html2canvasLoaderPromise) {
            html2canvasLoaderPromise = new Promise((resolve, reject) => {
                const script = document.createElement('script');
                script.src = 'https://cdn.jsdelivr.net/npm/html2canvas@1.4.1/dist/html2canvas.min.js';
                script.async = true;
                script.onload = () => resolve();
                script.onerror = () => reject(new Error('Could not load screenshot library'));
                document.head.appendChild(script);
            });
        }

        await html2canvasLoaderPromise;
    }

    async function takeScreenshotViaDisplayMedia() {
        if (!navigator.mediaDevices || !navigator.mediaDevices.getDisplayMedia) {
            throw new Error('Display media API not supported');
        }

        const stream = await navigator.mediaDevices.getDisplayMedia({
            video: true,
            audio: false,
        });

        try {
            const video = document.createElement('video');
            video.srcObject = stream;
            video.muted = true;
            video.playsInline = true;

            await new Promise((resolve, reject) => {
                video.onloadedmetadata = () => resolve();
                video.onerror = () => reject(new Error('Kunne ikke læse videostream'));
            });

            await video.play();

            const width = Math.max(1, video.videoWidth || window.innerWidth);
            const height = Math.max(1, video.videoHeight || window.innerHeight);
            const canvas = document.createElement('canvas');
            canvas.width = width;
            canvas.height = height;

            const ctx = canvas.getContext('2d');
            if (!ctx) {
                throw new Error('Canvas context unavailable');
            }

            ctx.drawImage(video, 0, 0, width, height);
            return canvas.toDataURL('image/png');
        } finally {
            stream.getTracks().forEach((t) => t.stop());
        }
    }

    async function takeScreenshot() {
        await ensureHtml2Canvas();

        const doc = document.documentElement;
        const body = document.body;
        const fullWidth = Math.max(
            doc ? doc.scrollWidth : 0,
            doc ? doc.offsetWidth : 0,
            doc ? doc.clientWidth : 0,
            body ? body.scrollWidth : 0,
            body ? body.offsetWidth : 0,
            window.innerWidth || 0
        );
        const fullHeight = Math.max(
            doc ? doc.scrollHeight : 0,
            doc ? doc.offsetHeight : 0,
            doc ? doc.clientHeight : 0,
            body ? body.scrollHeight : 0,
            body ? body.offsetHeight : 0,
            window.innerHeight || 0
        );

        const common = {
            useCORS: true,
            allowTaint: true,
            logging: false,
            scale: 1,
            backgroundColor: '#ffffff',
            imageTimeout: 7000,
            ignoreElements: shouldIgnoreInScreenshot,
            removeContainer: true,
        };

        // Strategy 0: Viewport capture via foreignObject (works on many CSS-heavy pages)
        try {
            return await renderScreenshot(document.body || document.documentElement, {
                ...common,
                foreignObjectRendering: true,
                width: window.innerWidth,
                height: window.innerHeight,
                windowWidth: window.innerWidth,
                windowHeight: window.innerHeight,
                scrollX: window.scrollX,
                scrollY: window.scrollY,
            });
        } catch (e0) {
            console.warn('Bug report screenshot strategy 0 failed', e0);
        }

        // Strategy 1: Full page (most useful when it works)
        try {
            return await renderScreenshot(document.documentElement, {
                ...common,
                width: fullWidth,
                height: fullHeight,
                windowWidth: fullWidth,
                windowHeight: fullHeight,
                x: 0,
                y: 0,
                scrollX: 0,
                scrollY: 0,
            });
        } catch (e1) {
            console.warn('Bug report screenshot strategy 1 failed', e1);
        }

        // Strategy 2: Main content only (explicit selectors avoid navbar-only captures)
        const contentRoot =
            document.querySelector('.container-fluid.px-4.py-4') ||
            document.querySelector('[data-bugreport-root]') ||
            document.querySelector('#main-content') ||
            document.querySelector('#content') ||
            document.querySelector('main') ||
            document.querySelector('.content-wrapper') ||
            document.documentElement;
        try {
            return await renderScreenshot(contentRoot, {
                ...common,
                width: Math.max(contentRoot.scrollWidth || 0, contentRoot.clientWidth || 0, window.innerWidth || 0),
                height: Math.max(contentRoot.scrollHeight || 0, contentRoot.clientHeight || 0, window.innerHeight || 0),
                scrollX: 0,
                scrollY: 0,
            });
        } catch (e2) {
            console.warn('Bug report screenshot strategy 2 failed', e2);
        }

        throw new Error('Automatic screenshot failed');
    }

    function setStatus(text, isError) {
        const el = document.getElementById('bugReportStatus');
        if (!el) return;
        el.textContent = text || '';
        el.className = isError ? 'small text-danger mt-2' : 'small text-muted mt-2';
    }

    function setPreview(dataUrl) {
        const img = document.getElementById('bugScreenshotPreview');
        const placeholder = document.getElementById('bugScreenshotPreviewPlaceholder');
        if (!img || !placeholder) return;
        if (dataUrl) {
            img.src = dataUrl;
            img.style.display = '';
            placeholder.style.display = 'none';
        } else {
            img.removeAttribute('src');
            img.style.display = 'none';
            placeholder.style.display = '';
        }
    }

    async function handlePasteScreenshot(event) {
        const modalVisible = document.getElementById('bugReportModal')?.classList.contains('show');
        if (!modalVisible) return;

        const items = Array.from(event.clipboardData?.items || []);
        const imageItem = items.find((item) => item.kind === 'file' && item.type.startsWith('image/'));
        if (!imageItem) return;

        const blob = imageItem.getAsFile();
        if (!blob) return;

        event.preventDefault();
        try {
            const dataUrl = await toDataUrl(blob);
            screenshotDataUrl = dataUrl;
            setPreview(dataUrl);
            setStatus('Screenshot indsat fra clipboard.');
        } catch (e) {
            console.warn('Clipboard screenshot parse failed', e);
            setStatus('Kunne ikke indsætte screenshot fra clipboard.', true);
        }
    }

    async function captureScreenshotBeforeModal() {
        try {
            screenshotDataUrl = await withTimeout(
                takeScreenshotViaDisplayMedia(),
                12000,
                'Skærmvalg timed out'
            );
            return { ok: true, viaDisplayMedia: true };
        } catch (displayErr) {
            console.warn('Bug report display-media first attempt failed', displayErr);
        }

        const attemptAutoCapture = async () => {
            const promise = pendingScreenshotPromise || takeScreenshot();
            pendingScreenshotPromise = promise;
            return await promise;
        };

        try {
            screenshotDataUrl = await attemptAutoCapture();
            return { ok: true };
        } catch (firstError) {
            console.warn('Bug report screenshot first attempt failed', firstError);

            try {
                pendingScreenshotPromise = withTimeout(
                    takeScreenshot(),
                    8000,
                    'Automatic screenshot timed out'
                );
                screenshotDataUrl = await pendingScreenshotPromise;
                return { ok: true, recovered: true };
            } catch (secondError) {
                console.warn('Bug report screenshot retry failed', secondError);
                screenshotDataUrl = null;
                return { ok: false, error: secondError || firstError };
            }
        } finally {
            pendingScreenshotPromise = null;
        }
    }

    async function openBugReportModal(statusText, statusIsError) {
        if (!bugModal) {
            const modalEl = document.getElementById('bugReportModal');
            if (!modalEl || !window.bootstrap) return;
            bugModal = new bootstrap.Modal(modalEl);
        }

        setPreview(screenshotDataUrl);
        setStatus(
            statusText || (screenshotDataUrl
                ? 'Screenshot klar. Udfyld felterne og send.'
                : 'Kunne ikke tage screenshot automatisk. Klik "Tag screenshot via skærmdeling" eller indsæt med Cmd+V.'),
            Boolean(statusIsError)
        );

        bugModal.show();
    }

    function prepareScreenshotFromTrigger(forceNew) {
        if (!forceNew && pendingScreenshotPromise) {
            return pendingScreenshotPromise;
        }

        pendingScreenshotPromise = takeScreenshot();
        return pendingScreenshotPromise;
    }

    async function captureScreenshotViaDisplayMediaFromUserGesture() {
        if (isCapturingDisplayMedia) return;

        const btn = document.getElementById('bugCaptureDisplayMediaBtn');
        const originalHtml = btn ? btn.innerHTML : '';
        isCapturingDisplayMedia = true;

        if (btn) {
            btn.disabled = true;
            btn.innerHTML = '<span class="spinner-border spinner-border-sm me-1"></span>Venter på skærmvalg...';
        }

        try {
            const dataUrl = await takeScreenshotViaDisplayMedia();
            screenshotDataUrl = dataUrl;
            setPreview(dataUrl);
            setStatus('Screenshot taget via skærmdeling.');
        } catch (e) {
            console.warn('Bug report display media capture failed', e);
            setStatus('Skærmdelings-screenshot mislykkedes. Prøv igen eller indsæt med Cmd+V.', true);
        } finally {
            isCapturingDisplayMedia = false;
            if (btn) {
                btn.disabled = false;
                btn.innerHTML = originalHtml || '<i class="bi bi-display me-1"></i>Tag screenshot via skærmdeling';
            }
        }
    }

    async function submitBugReport() {
        const actual = (document.getElementById('bugActualInput')?.value || '').trim();
        const expected = (document.getElementById('bugExpectedInput')?.value || '').trim();
        const fileInput = document.getElementById('bugExtraFileInput');
        const submitBtn = document.getElementById('bugReportSubmitBtn');

        if (!actual || !expected) {
            setStatus('Udfyld både "Hvad gik galt" og "Hvad burde være sket".', true);
            return;
        }

        let extraFileName = null;
        let extraFileBase64 = null;
        if (fileInput && fileInput.files && fileInput.files[0]) {
            const f = fileInput.files[0];
            extraFileName = f.name;
            try {
                extraFileBase64 = await toDataUrl(f);
            } catch (_) {
                setStatus('Kunne ikke læse ekstra fil.', true);
                return;
            }
        }

        const payload = {
            actual,
            expected,
            screenshot_base64: screenshotDataUrl,
            metadata: getMetadata(),
            logs,
            extra_file_name: extraFileName,
            extra_file_base64: extraFileBase64,
        };

        const prevText = submitBtn ? submitBtn.innerHTML : '';
        if (submitBtn) {
            submitBtn.disabled = true;
            submitBtn.innerHTML = '<span class="spinner-border spinner-border-sm me-1"></span>Sender...';
        }

        try {
            const endpoints = ['/api/v1/bug-reports', '/bug-reports'];
            let res = null;
            let data = {};

            for (const endpoint of endpoints) {
                res = await fetch(endpoint, {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    credentials: 'include',
                    body: JSON.stringify(payload),
                });

                data = await res.json().catch(() => ({}));

                // Try fallback endpoint only when path is missing.
                if (res.status === 404) {
                    continue;
                }
                break;
            }

            if (!res || !res.ok) {
                const detail = (data && (data.detail || data.message)) || 'Kunne ikke sende fejlrapport';
                throw new Error(detail);
            }

            setStatus('Fejl rapporteret.');
            const target = data.case_url || '/sag';
            setTimeout(() => {
                window.location.href = target;
            }, 500);
        } catch (e) {
            setStatus(e.message || 'Kunne ikke sende fejlrapport', true);
        } finally {
            if (submitBtn) {
                submitBtn.disabled = false;
                submitBtn.innerHTML = prevText;
            }
        }
    }

    document.addEventListener('DOMContentLoaded', () => {
        const btn = document.getElementById('bugReportBtn');
        const submitBtn = document.getElementById('bugReportSubmitBtn');
        const displayMediaBtn = document.getElementById('bugCaptureDisplayMediaBtn');
        const modalEl = document.getElementById('bugReportModal');

        if (btn) {
            btn.addEventListener('click', async (e) => {
                e.preventDefault();
                const capture = await captureScreenshotBeforeModal();
                if (capture.ok) {
                    const msg = capture.viaDisplayMedia
                        ? 'Screenshot taget ved klik via skærmdeling. Udfyld felterne og send.'
                        : 'Screenshot taget ved klik. Udfyld felterne og send.';
                    openBugReportModal(msg, false);
                } else {
                    const reason = String(capture?.error?.message || '').trim();
                    const errorMsg = reason
                        ? `Kunne ikke tage screenshot automatisk (${reason}). Klik \"Tag screenshot via skærmdeling\" eller indsæt med Cmd+V.`
                        : 'Kunne ikke tage screenshot automatisk. Klik "Tag screenshot via skærmdeling" eller indsæt med Cmd+V.';
                    openBugReportModal(errorMsg, true);
                }
            });
        }

        if (submitBtn) {
            submitBtn.addEventListener('click', () => {
                submitBugReport();
            });
        }

        if (displayMediaBtn) {
            displayMediaBtn.addEventListener('click', (e) => {
                e.preventDefault();
                captureScreenshotViaDisplayMediaFromUserGesture();
            });
        }

        if (modalEl) {
            modalEl.addEventListener('hidden.bs.modal', () => {
                const actual = document.getElementById('bugActualInput');
                const expected = document.getElementById('bugExpectedInput');
                const fileInput = document.getElementById('bugExtraFileInput');
                if (actual) actual.value = '';
                if (expected) expected.value = '';
                if (fileInput) fileInput.value = '';
                screenshotDataUrl = null;
                setPreview(null);
                setStatus('');
            });
        }

        document.addEventListener('paste', (e) => {
            handlePasteScreenshot(e);
        });

        document.addEventListener('keydown', (e) => {
            const isTyping = ['INPUT', 'TEXTAREA'].includes((e.target?.tagName || '').toUpperCase());
            if (isTyping) return;
            if (e.ctrlKey && e.shiftKey && (e.key === 'B' || e.key === 'b')) {
                e.preventDefault();
                captureScreenshotBeforeModal().then((capture) => {
                    if (capture.ok) {
                        const msg = capture.viaDisplayMedia
                            ? 'Screenshot taget ved klik via skærmdeling. Udfyld felterne og send.'
                            : 'Screenshot taget ved klik. Udfyld felterne og send.';
                        openBugReportModal(msg, false);
                    } else {
                        const reason = String(capture?.error?.message || '').trim();
                        const errorMsg = reason
                            ? `Kunne ikke tage screenshot automatisk (${reason}). Klik \"Tag screenshot via skærmdeling\" eller indsæt med Cmd+V.`
                            : 'Kunne ikke tage screenshot automatisk. Klik "Tag screenshot via skærmdeling" eller indsæt med Cmd+V.';
                        openBugReportModal(errorMsg, true);
                    }
                });
            }
        });
    });
})();
