import { t } from '../i18n.js'
import { escapeHTML } from '../utils/helpers.js'

/**
 * Error Boundary Component
 * Catches errors in child components and displays fallback UI
 */
class ErrorBoundary extends HTMLElement {
    constructor() {
        super()
        this.hasError = false
        this.error = null
    }

    connectedCallback() {
        this.setupErrorHandling()
    }

    setupErrorHandling() {
        // Catch errors from child components
        this.addEventListener('error', (e) => {
            e.stopPropagation()
            this.handleError(e.error || e.message || 'Unknown error')
        })
    }

    handleError(error) {
        console.error('ErrorBoundary caught:', error)
        this.hasError = true
        this.error = error
        this.renderError()
    }

    renderError() {
        const errorMessage = this.error?.message || String(this.error) || t('common.error')
        
        this.innerHTML = /* html */`
            <div class="error-boundary">
                <div class="error-icon">⚠️</div>
                <h3 class="error-title">${t('error.title')}</h3>
                <p class="error-message">${escapeHTML(errorMessage)}</p>
                <button class="btn btn-primary error-retry" type="button">
                    ${t('error.retry')}
                </button>
            </div>
        `

        this.querySelector('.error-retry')?.addEventListener('click', () => this.retry())
    }

    retry() {
        this.hasError = false
        this.error = null
        this.innerHTML = ''
        this.dispatchEvent(new CustomEvent('retry', { bubbles: true }))
    }

    reset() {
        this.hasError = false
        this.error = null
    }

}

customElements.define('error-boundary', ErrorBoundary)

/**
 * Global error handler for uncaught errors
 */
export function setupGlobalErrorHandler() {
    window.addEventListener('error', (event) => {
        console.error('Global error:', event.error)
        
        // Don't show UI for script loading errors
        if (event.filename && event.filename.includes('.js')) {
            showErrorToast(event.message || 'Ein Fehler ist aufgetreten')
        }
    })

    window.addEventListener('unhandledrejection', (event) => {
        console.error('Unhandled promise rejection:', event.reason)
        showErrorToast(event.reason?.message || 'Ein Fehler ist aufgetreten')
    })

    // Offline/Online detection
    setupOfflineIndicator()
}

/**
 * Shows/hides offline indicator based on network status
 */
function setupOfflineIndicator() {
    const updateStatus = () => {
        let indicator = document.querySelector('.offline-indicator')
        
        if (!navigator.onLine) {
            if (!indicator) {
                indicator = document.createElement('div')
                indicator.className = 'offline-indicator'
                indicator.innerHTML = `
                    <span class="offline-icon">📡</span>
                    <span class="offline-text">Offline</span>
                `
                document.body.appendChild(indicator)
                requestAnimationFrame(() => indicator.classList.add('visible'))
            }
        } else {
            if (indicator) {
                indicator.classList.remove('visible')
                setTimeout(() => indicator.remove(), 300)
            }
        }
    }

    window.addEventListener('online', updateStatus)
    window.addEventListener('offline', updateStatus)
    
    // Check on init
    updateStatus()
}

/**
 * Shows a temporary error toast notification
 */
function showErrorToast(message) {
    // Remove existing toast
    document.querySelector('.error-toast')?.remove()

    const toast = document.createElement('div')
    toast.className = 'error-toast'
    toast.innerHTML = /* html */`
        <span class="error-toast-icon">⚠️</span>
        <span class="error-toast-message">${escapeHTML(message)}</span>
        <button class="error-toast-close" aria-label="${t('common.close')}">×</button>
    `

    document.body.appendChild(toast)

    // Auto-dismiss after 5 seconds
    const timeout = setTimeout(() => toast.remove(), 5000)

    toast.querySelector('.error-toast-close')?.addEventListener('click', () => {
        clearTimeout(timeout)
        toast.remove()
    })

    // Trigger animation
    requestAnimationFrame(() => toast.classList.add('visible'))
}

// Styles
const style = document.createElement('style')
style.textContent = /* css */`
    error-boundary {
        display: block;
    }

    error-boundary .error-boundary {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        padding: var(--space-2xl);
        text-align: center;
        min-height: 200px;
    }

    error-boundary .error-icon {
        font-size: 3rem;
        margin-bottom: var(--space-md);
        filter: grayscale(1);
    }

    error-boundary .error-title {
        font-size: var(--font-size-lg);
        margin: 0 0 var(--space-sm);
        color: var(--color-text);
    }

    error-boundary .error-message {
        font-size: var(--font-size-sm);
        color: var(--color-text-muted);
        margin: 0 0 var(--space-lg);
        max-width: 400px;
    }

    /* Error Toast */
    .error-toast {
        position: fixed;
        bottom: var(--space-lg);
        left: 50%;
        transform: translateX(-50%) translateY(100px);
        display: flex;
        align-items: center;
        gap: var(--space-sm);
        padding: var(--space-sm) var(--space-md);
        background: var(--color-bg-secondary);
        border: 1px solid var(--color-border);
        border-radius: var(--radius-md);
        box-shadow: var(--shadow-lg);
        z-index: 10000;
        opacity: 0;
        transition: transform 0.3s ease, opacity 0.3s ease;
    }

    .error-toast.visible {
        transform: translateX(-50%) translateY(0);
        opacity: 1;
    }

    .error-toast-icon {
        filter: grayscale(1);
    }

    .error-toast-message {
        font-size: var(--font-size-sm);
        color: var(--color-text);
        max-width: 300px;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    .error-toast-close {
        background: none;
        border: none;
        font-size: var(--font-size-lg);
        color: var(--color-text-muted);
        cursor: pointer;
        padding: 0;
        line-height: 1;
    }

    .error-toast-close:hover {
        color: var(--color-text);
    }

    /* Offline Indicator */
    .offline-indicator {
        position: fixed;
        top: var(--space-md);
        left: 50%;
        transform: translateX(-50%) translateY(-100px);
        display: flex;
        align-items: center;
        gap: var(--space-xs);
        padding: var(--space-xs) var(--space-md);
        background: var(--color-bg-secondary);
        border: 1px solid var(--color-border);
        border-radius: var(--radius-full);
        box-shadow: var(--shadow-md);
        z-index: 10001;
        opacity: 0;
        transition: transform 0.3s ease, opacity 0.3s ease;
    }

    .offline-indicator.visible {
        transform: translateX(-50%) translateY(0);
        opacity: 1;
    }

    .offline-indicator .offline-icon {
        filter: grayscale(1);
    }

    .offline-indicator .offline-text {
        font-size: var(--font-size-sm);
        font-weight: var(--font-weight-medium);
        color: var(--color-text);
    }
`
document.head.appendChild(style)

export { ErrorBoundary }
