/**
 * Display picker lightbox — display selection for streams and tests.
 * Supports engine-specific displays (e.g. scrcpy → Android devices).
 */

import {
    _cachedDisplays, _displayPickerCallback, _displayPickerSelectedIndex,
    set_displayPickerCallback, set_displayPickerSelectedIndex, displaysCache,
    availableEngines,
} from '../core/state.ts';
import { t } from '../core/i18n.ts';
import { fetchWithAuth } from '../core/api.ts';
import { showToast } from '../core/ui.ts';
import type { Display } from '../types.ts';

/** Currently active engine type for the picker (null = desktop monitors). */
let _pickerEngineType: string | null = null;

/** Check if an engine type has its own device list (for inline onclick use). */
window._engineHasOwnDisplays = (engineType: string) =>
    !!(engineType && availableEngines.find(e => e.type === engineType)?.has_own_displays);

export function openDisplayPicker(callback: (index: number, display?: Display | null) => void, selectedIndex: number | string | null | undefined, engineType: string | null = null): void {
    set_displayPickerCallback(callback);
    set_displayPickerSelectedIndex((selectedIndex !== undefined && selectedIndex !== null && selectedIndex !== '') ? Number(selectedIndex) : null);
    _pickerEngineType = engineType || null;
    const lightbox = document.getElementById('display-picker-lightbox')!;

    // Use "Select a Device" title for engines with own display lists (camera, scrcpy, etc.)
    const titleEl = lightbox.querySelector('.display-picker-title');
    if (titleEl) {
        titleEl.textContent = t(_pickerEngineType ? 'displays.picker.title.device' : 'displays.picker.title');
    }

    lightbox.classList.add('active');

    requestAnimationFrame(() => {
        // Always fetch fresh when engine type is specified (different list each time)
        if (_pickerEngineType) {
            _fetchAndRenderEngineDisplays(_pickerEngineType);
        } else if (_cachedDisplays && _cachedDisplays.length > 0) {
            renderDisplayPickerLayout(_cachedDisplays);
        } else {
            const canvas = document.getElementById('display-picker-canvas')!;
            canvas.innerHTML = '<div class="loading-spinner"></div>';
            displaysCache.fetch().then(displays => {
                if (displays && displays.length > 0) {
                    renderDisplayPickerLayout(displays);
                } else {
                    canvas.innerHTML = `<div class="loading">${t('displays.none')}</div>`;
                }
            });
        }
    });
}

async function _fetchAndRenderEngineDisplays(engineType: string): Promise<void> {
    const canvas = document.getElementById('display-picker-canvas')!;
    canvas.innerHTML = '<div class="loading-spinner"></div>';

    try {
        const resp = await fetchWithAuth(`/config/displays?engine_type=${engineType}`);
        if (!resp.ok) throw new Error(`${resp.status}`);
        const data = await resp.json();
        const displays = data.displays || [];

        // Store in cache so selectDisplay() can look them up
        displaysCache.update(displays);

        if (displays.length > 0) {
            renderDisplayPickerLayout(displays, engineType);
        } else if (engineType === 'scrcpy') {
            _renderEmptyAndroidPicker(canvas);
        } else {
            canvas.innerHTML = `<div class="loading">${t('displays.none')}</div>`;
        }
    } catch (error) {
        console.error('Error fetching engine displays:', error);
        canvas.innerHTML = `<div class="loading">${t('displays.failed')}</div>`;
    }
}

function _renderEmptyAndroidPicker(canvas: HTMLElement): void {
    canvas.innerHTML = `
        <div class="loading">${t('displays.picker.no_android')}</div>
        ${_buildAdbConnectHtml()}
    `;
}

function _buildAdbConnectHtml(): string {
    return `
        <div class="adb-connect-form" style="margin-top: 1rem; display: flex; gap: 0.5rem; align-items: center; justify-content: center;">
            <input type="text" id="adb-connect-ip"
                   placeholder="${t('displays.picker.adb_connect.placeholder')}"
                   style="width: 200px; padding: 0.35rem 0.5rem; border-radius: 4px; border: 1px solid var(--border-color);">
            <button class="btn btn-primary btn-sm" onclick="window._adbConnectFromPicker()">
                ${t('displays.picker.adb_connect.button')}
            </button>
        </div>
    `;
}

/** Called from the inline Connect button inside the display picker. */
window._adbConnectFromPicker = async function () {
    const input = document.getElementById('adb-connect-ip') as HTMLInputElement | null;
    if (!input) return;
    const address = input.value.trim();
    if (!address) return;

    input.disabled = true;
    try {
        const resp = await fetchWithAuth('/adb/connect', {
            method: 'POST',
            body: JSON.stringify({ address }),
        });
        if (!resp.ok) {
            const err = await resp.json().catch(() => ({}));
            throw new Error(err.detail || 'Connection failed');
        }
        showToast(t('displays.picker.adb_connect.success'), 'success');

        // Refresh the picker with updated device list
        if (_pickerEngineType) {
            await _fetchAndRenderEngineDisplays(_pickerEngineType);
        }
    } catch (error) {
        showToast(`${t('displays.picker.adb_connect.error')}: ${error.message}`, 'error');
    } finally {
        if (input) input.disabled = false;
    }
};

export function closeDisplayPicker(event?: Event): void {
    if (event && event.target && (event.target as HTMLElement).closest('.display-picker-content')) return;
    const lightbox = document.getElementById('display-picker-lightbox');
    lightbox?.classList.remove('active');
    set_displayPickerCallback(null);
    _pickerEngineType = null;
}

export function selectDisplay(displayIndex: number): void {
    // Re-read live bindings
    import('../core/state.js').then(({ _displayPickerCallback: cb, _cachedDisplays: displays }) => {
        if (cb) {
            const display = displays ? displays.find(d => d.index === displayIndex) : null;
            cb(displayIndex, display);
        }
        closeDisplayPicker();
    });
}

export function renderDisplayPickerLayout(displays: any[], engineType: string | null = null): void {
    const canvas = document.getElementById('display-picker-canvas')!;

    if (!displays || displays.length === 0) {
        canvas.innerHTML = `<div class="loading">${t('displays.none')}</div>`;
        return;
    }

    // Engines with own displays (camera, scrcpy) → device list layout
    if (engineType) {
        const items = displays.map(display => {
            const isSelected = _displayPickerSelectedIndex !== null && display.index === _displayPickerSelectedIndex;
            return `
                <div class="device-picker-item layout-display-pickable${isSelected ? ' selected' : ''}"
                     onclick="selectDisplay(${display.index})"
                     title="${t('displays.picker.click_to_select')}">
                    <div class="layout-index-label">#${display.index}</div>
                    <div class="layout-display-label">
                        <strong>${display.name}</strong>
                        <small>${display.width}×${display.height} · ${display.refresh_rate} FPS</small>
                    </div>
                </div>
            `;
        }).join('');

        let html = `<div class="device-picker-list">${items}</div>`;

        if (engineType === 'scrcpy') {
            html += _buildAdbConnectHtml();
        }

        canvas.innerHTML = html;
        return;
    }

    // Desktop monitors → positioned rectangle layout
    let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
    displays.forEach(display => {
        minX = Math.min(minX, display.x);
        minY = Math.min(minY, display.y);
        maxX = Math.max(maxX, display.x + display.width);
        maxY = Math.max(maxY, display.y + display.height);
    });

    const totalWidth = maxX - minX;
    const totalHeight = maxY - minY;
    const aspect = totalHeight / totalWidth;

    const displayElements = displays.map(display => {
        const leftPct = ((display.x - minX) / totalWidth) * 100;
        const topPct = ((display.y - minY) / totalHeight) * 100;
        const widthPct = (display.width / totalWidth) * 100;
        const heightPct = (display.height / totalHeight) * 100;

        const isSelected = _displayPickerSelectedIndex !== null && display.index === _displayPickerSelectedIndex;
        return `
            <div class="layout-display layout-display-pickable${isSelected ? ' selected' : ''}"
                 style="left: ${leftPct}%; top: ${topPct}%; width: ${widthPct}%; height: ${heightPct}%;"
                 onclick="selectDisplay(${display.index})"
                 title="${t('displays.picker.click_to_select')}">
                <div class="layout-position-label">(${display.x}, ${display.y})</div>
                <div class="layout-index-label">#${display.index}</div>
                <div class="layout-display-label">
                    <strong>${display.name}</strong>
                    <small>${display.width}×${display.height}</small>
                    <small>${display.refresh_rate}Hz</small>
                </div>
            </div>
        `;
    }).join('');

    canvas.innerHTML = `
        <div class="layout-container" style="width: 100%; padding-bottom: ${aspect * 100}%; position: relative;">
            ${displayElements}
        </div>
    `;
}

export function formatDisplayLabel(displayIndex: number, display: any | null, engineType: string | null = null): string {
    if (display) {
        if (engineType && window._engineHasOwnDisplays(engineType)) {
            return `${display.name} (${display.width}×${display.height})`;
        }
        return `#${display.index}: ${display.width}×${display.height}${display.is_primary ? ' (' + t('displays.badge.primary') + ')' : ''}`;
    }
    return `Display ${displayIndex}`;
}
