/**
 * Image Cropper Component
 * Uses Cropper.js for image cropping with square aspect ratio
 */

import { t } from '../i18n.js'

// Load Cropper.js dynamically (self-hosted for privacy)
let cropperLoaded = false
async function loadCropperJS() {
    if (cropperLoaded) return
    
    // Load CSS
    const link = document.createElement('link')
    link.rel = 'stylesheet'
    link.href = '/css/vendor/cropper.min.css'
    document.head.appendChild(link)
    
    // Load JS
    await new Promise((resolve, reject) => {
        const script = document.createElement('script')
        script.src = '/js/vendor/cropper.min.js'
        script.onload = resolve
        script.onerror = reject
        document.head.appendChild(script)
    })
    
    cropperLoaded = true
}

class ImageCropper extends HTMLElement {
    constructor() {
        super()
        this.cropper = null
        this.currentFile = null
        this.onCropComplete = null
        this.onCancel = null
        this.currentAspectRatio = 1
    }

    connectedCallback() {
        this.render()
        this.setupEventListeners()
    }

    disconnectedCallback() {
        this.destroyCropper()
    }

    render() {
        this.innerHTML = /* html */`
            <div class="cropper-overlay" id="cropper-overlay">
                <div class="cropper-modal">
                    <div class="cropper-header">
                        <h3>${t('cropper.title')}</h3>
                        <button type="button" class="cropper-close" id="cropper-close" aria-label="${t('common.close')}">
                            <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                                <line x1="18" y1="6" x2="6" y2="18"></line>
                                <line x1="6" y1="6" x2="18" y2="18"></line>
                            </svg>
                        </button>
                    </div>
                    <div class="cropper-container">
                        <img id="cropper-image" src="" alt="Crop preview">
                    </div>
                    <div class="cropper-toolbar">
                        <span class="cropper-toolbar-label">${t('cropper.aspectRatio')}</span>
                        <div class="cropper-ratio-buttons">
                            <button type="button" class="cropper-ratio-btn active" data-ratio="1">1:1</button>
                            <button type="button" class="cropper-ratio-btn" data-ratio="1.333">4:3</button>
                            <button type="button" class="cropper-ratio-btn" data-ratio="1.778">16:9</button>
                            <button type="button" class="cropper-ratio-btn" data-ratio="0">${t('cropper.free')}</button>
                        </div>
                    </div>
                    <div class="cropper-preview-section">
                        <span class="cropper-preview-label">${t('cropper.preview')}</span>
                        <div class="cropper-preview" id="cropper-preview"></div>
                    </div>
                    <div class="cropper-actions">
                        <button type="button" class="btn btn-outline" id="cropper-cancel">${t('cropper.cancel')}</button>
                        <button type="button" class="btn btn-primary" id="cropper-confirm">${t('cropper.confirm')}</button>
                    </div>
                </div>
            </div>
        `
    }

    setupEventListeners() {
        this.querySelector('#cropper-close')?.addEventListener('click', () => this.cancel())
        this.querySelector('#cropper-cancel')?.addEventListener('click', () => this.cancel())
        this.querySelector('#cropper-confirm')?.addEventListener('click', () => this.confirm())
        
        // Close on overlay click
        this.querySelector('#cropper-overlay')?.addEventListener('click', (e) => {
            if (e.target.id === 'cropper-overlay') this.cancel()
        })
        
        // Aspect ratio buttons
        this.querySelectorAll('.cropper-ratio-btn').forEach(btn => {
            btn.addEventListener('click', () => {
                this.querySelectorAll('.cropper-ratio-btn').forEach(b => b.classList.remove('active'))
                btn.classList.add('active')
                const ratio = parseFloat(btn.dataset.ratio)
                this.currentAspectRatio = ratio
                if (this.cropper) {
                    this.cropper.setAspectRatio(ratio === 0 ? NaN : ratio)
                }
            })
        })
    }

    async open(file, onComplete, onCancel) {
        await loadCropperJS()
        
        this.currentFile = file
        this.onCropComplete = onComplete
        this.onCancel = onCancel
        
        const overlay = this.querySelector('#cropper-overlay')
        const image = this.querySelector('#cropper-image')
        
        // Create object URL for the file
        const url = URL.createObjectURL(file)
        image.src = url
        
        // Wait for image to load
        await new Promise(resolve => {
            image.onload = resolve
        })
        
        // Show overlay
        overlay.classList.add('visible')
        document.body.style.overflow = 'hidden'
        
        // Reset aspect ratio buttons
        this.currentAspectRatio = 1
        this.querySelectorAll('.cropper-ratio-btn').forEach(btn => {
            btn.classList.toggle('active', btn.dataset.ratio === '1')
        })
        
        // Initialize Cropper
        this.destroyCropper()
        this.cropper = new window.Cropper(image, {
            aspectRatio: 1,
            viewMode: 1,
            dragMode: 'move',
            autoCropArea: 0.9,
            cropBoxMovable: true,
            cropBoxResizable: true,
            toggleDragModeOnDblclick: false,
            preview: '#cropper-preview',
            background: false
        })
    }

    async confirm() {
        if (!this.cropper) return
        
        // Calculate output dimensions based on aspect ratio
        const maxSize = 1200
        let width, height
        if (this.currentAspectRatio === 0 || isNaN(this.currentAspectRatio)) {
            // Free crop - use actual crop box dimensions, max 1200px on longest side
            const cropData = this.cropper.getCropBoxData()
            const scale = Math.min(1, maxSize / Math.max(cropData.width, cropData.height))
            width = Math.round(cropData.width * scale)
            height = Math.round(cropData.height * scale)
        } else if (this.currentAspectRatio >= 1) {
            width = maxSize
            height = Math.round(maxSize / this.currentAspectRatio)
        } else {
            height = maxSize
            width = Math.round(maxSize * this.currentAspectRatio)
        }
        
        // Get cropped canvas
        const canvas = this.cropper.getCroppedCanvas({
            width,
            height,
            imageSmoothingEnabled: true,
            imageSmoothingQuality: 'high'
        })
        
        // Convert to blob
        const blob = await new Promise(resolve => {
            canvas.toBlob(resolve, 'image/jpeg', 0.9)
        })
        
        // Create file from blob
        const croppedFile = new File([blob], this.currentFile.name, {
            type: 'image/jpeg',
            lastModified: Date.now()
        })
        
        // Create preview URL
        const previewUrl = canvas.toDataURL('image/jpeg', 0.9)
        
        this.close()
        
        if (this.onCropComplete) {
            this.onCropComplete(croppedFile, previewUrl)
        }
    }

    cancel() {
        this.close()
        if (this.onCancel) {
            this.onCancel()
        }
    }

    close() {
        const overlay = this.querySelector('#cropper-overlay')
        overlay.classList.remove('visible')
        document.body.style.overflow = ''
        
        this.destroyCropper()
        
        // Revoke object URL
        const image = this.querySelector('#cropper-image')
        if (image.src.startsWith('blob:')) {
            URL.revokeObjectURL(image.src)
        }
        image.src = ''
    }

    destroyCropper() {
        if (this.cropper) {
            this.cropper.destroy()
            this.cropper = null
        }
    }
}

customElements.define('image-cropper', ImageCropper)

const style = document.createElement('style')
style.textContent = /* css */`
    image-cropper .cropper-overlay {
        position: fixed;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        background: rgba(0, 0, 0, 0.85);
        display: none;
        align-items: center;
        justify-content: center;
        z-index: 1000;
        padding: var(--space-md);
    }

    image-cropper .cropper-overlay.visible {
        display: flex;
    }

    image-cropper .cropper-modal {
        background: var(--color-bg);
        border-radius: var(--radius-lg);
        max-width: 600px;
        width: 100%;
        max-height: 90vh;
        margin: auto;
        overflow: hidden;
        display: flex;
        flex-direction: column;
        box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5);
        opacity: 1;
    }

    image-cropper .cropper-header {
        display: flex;
        justify-content: space-between;
        align-items: center;
        padding: var(--space-md) var(--space-lg);
        border-bottom: 1px solid var(--color-border);
    }

    image-cropper .cropper-header h3 {
        margin: 0;
        font-size: var(--font-size-lg);
    }

    image-cropper .cropper-close {
        background: none;
        border: none;
        padding: var(--space-xs);
        cursor: pointer;
        color: var(--color-text-muted);
        border-radius: var(--radius-sm);
    }

    image-cropper .cropper-close:hover {
        background: var(--color-bg-tertiary);
        color: var(--color-text);
    }

    image-cropper .cropper-container {
        position: relative;
        width: 100%;
        height: 350px;
        background: var(--color-bg-tertiary);
    }

    image-cropper .cropper-container img {
        display: block;
        max-width: 100%;
        max-height: 100%;
    }

    image-cropper .cropper-toolbar {
        display: flex;
        align-items: center;
        gap: var(--space-md);
        padding: var(--space-sm) var(--space-lg);
        border-top: 1px solid var(--color-border);
        background: var(--color-bg-secondary);
    }

    image-cropper .cropper-toolbar-label {
        font-size: var(--font-size-sm);
        color: var(--color-text-muted);
    }

    image-cropper .cropper-ratio-buttons {
        display: flex;
        gap: var(--space-xs);
    }

    image-cropper .cropper-ratio-btn {
        padding: var(--space-xs) var(--space-sm);
        font-size: var(--font-size-sm);
        border: 1px solid var(--color-border);
        background: var(--color-bg);
        color: var(--color-text-secondary);
        border-radius: var(--radius-sm);
        cursor: pointer;
        transition: all var(--transition-fast);
    }

    image-cropper .cropper-ratio-btn:hover {
        background: var(--color-bg-tertiary);
        color: var(--color-text);
    }

    image-cropper .cropper-ratio-btn.active {
        background: var(--color-primary);
        border-color: var(--color-primary);
        color: var(--color-bg);
    }

    image-cropper .cropper-preview-section {
        display: flex;
        align-items: center;
        gap: var(--space-md);
        padding: var(--space-md) var(--space-lg);
        border-top: 1px solid var(--color-border);
    }

    image-cropper .cropper-preview-label {
        font-size: var(--font-size-sm);
        color: var(--color-text-muted);
    }

    image-cropper .cropper-preview {
        width: 80px;
        height: 80px;
        border-radius: var(--radius-md);
        overflow: hidden;
        border: 1px solid var(--color-border);
    }

    image-cropper .cropper-actions {
        display: flex;
        justify-content: flex-end;
        gap: var(--space-sm);
        padding: var(--space-md) var(--space-lg);
        border-top: 1px solid var(--color-border);
    }

    @media (max-width: 768px) {
        image-cropper .cropper-container {
            height: 280px;
        }
    }
`
document.head.appendChild(style)

export { ImageCropper }
