<script>
    import { onMount } from 'svelte';

    let { adminPath, media = [], isPicker = false, onSelect = null, permissions = {}, availableLocales: propAvailableLocales = ['en', 'es', 'fr', 'de'] } = $props();

    const normalizedAdminPath = $derived(adminPath.endsWith('/') ? adminPath.slice(0, -1) : adminPath);
    const userPermissions = $derived(typeof permissions === 'string' ? JSON.parse(permissions) : permissions);
    const availableLocales = $derived(Array.isArray(propAvailableLocales) ? propAvailableLocales : ['en']);

    let displayMedia = $state([]);
    let selectedFile = $state(null);
    let uploading = $state(false);
    let showFocalPoint = $state(false);
    let focalX = $state(50);
    let focalY = $state(50);
    let focalPointRef = $state(null);

    // Multi-locale metadata state
    let activeLocale = $state('en');
    let metadata = $state({});

    $effect(() => {
        const locales = availableLocales;
        if (locales.length > 0 && !locales.includes(activeLocale)) {
            activeLocale = locales[0];
        }
    });

    $effect(() => {
        const locales = availableLocales;
        // Only update if metadata is actually missing keys from the current locale list
        const missingKeys = locales.filter(l => !metadata[l]);
        if (missingKeys.length > 0) {
            const initialMetadata = {};
            locales.forEach(l => {
                initialMetadata[l] = { caption: '', alt: '' };
            });
            metadata = { ...initialMetadata, ...metadata };
        }
    });

    $effect(() => {
        displayMedia = media;
    });

    onMount(async () => {
        if (displayMedia.length === 0) {
            try {
                const response = await fetch(`${normalizedAdminPath}/media`, {
                    headers: {
                        'Accept': 'application/json'
                    }
                });
                if (response.ok) {
                    const data = await response.json();
                    displayMedia = data.media || [];
                }
            } catch (err) {
                console.error("Failed to load media:", err);
            }
        }
    });

    function formatBytes(bytes, decimals = 2) {
        if (bytes === 0) return '0 Bytes';
        const k = 1024;
        const dm = decimals < 0 ? 0 : decimals;
        const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
        const i = Math.floor(Math.log(bytes) / Math.log(k));
        return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
    }

    function handleKeydown(event, action) {
        if (event.key === 'Enter' || event.key === ' ') {
            event.preventDefault();
            action();
        }
    }

    async function handleUpload(event) {
        const files = event.target.files;
        if (files.length === 0) return;

        uploading = true;
        const formData = new FormData();
        formData.append('file', files[0]);

        try {
            const response = await fetch(`${normalizedAdminPath}/media/upload`, {
                method: 'POST',
                headers: {
                    'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content
                },
                body: formData
            });

            if (response.ok) {
                const result = await response.json();
                displayMedia = [result.media, ...displayMedia];
            } else {
                const error = await response.json();
                alert(error.message || 'Upload failed');
            }
        } catch (err) {
            console.error(err);
            alert('An error occurred during upload');
        } finally {
            uploading = false;
            event.target.value = '';
        }
    }

    async function deleteFile(file) {
        if (!confirm('Are you sure you want to delete this file?')) return;

        try {
            const response = await fetch(`${normalizedAdminPath}/media`, {
                method: 'DELETE',
                headers: {
                    'Content-Type': 'application/json',
                    'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content
                },
                body: JSON.stringify({ id: file.id })
            });

            if (response.ok) {
                displayMedia = displayMedia.filter(f => f.id !== file.id);
                if (selectedFile?.id === file.id) selectedFile = null;
            } else {
                alert('Failed to delete file');
            }
        } catch (err) {
            console.error(err);
            alert('An error occurred during deletion');
        }
    }

    function selectFile(file) {
        selectedFile = file;
        focalX = file.focal_x || 50;
        focalY = file.focal_y || 50;
        showFocalPoint = false;

        // Load metadata
        if (file.metadata) {
            metadata = { ...metadata, ...file.metadata };
        } else {
            metadata = {
                en: { caption: '', alt: '' },
                es: { caption: '', alt: '' },
                fr: { caption: '', alt: '' },
                de: { caption: '', alt: '' }
            };
        }
    }

    function setFocalPoint(event) {
        const rect = focalPointRef.getBoundingClientRect();
        const x = ((event.clientX - rect.left) / rect.width) * 100;
        const y = ((event.clientY - rect.top) / rect.height) * 100;

        focalX = Math.round(x * 100) / 100;
        focalY = Math.round(y * 100) / 100;
    }

    async function saveFocalPoint() {
        try {
            const response = await fetch(`${normalizedAdminPath}/media`, {
                method: 'PUT',
                headers: {
                    'Content-Type': 'application/json',
                    'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content
                },
                body: JSON.stringify({
                    id: selectedFile.id,
                    focal_x: focalX,
                    focal_y: focalY
                })
            });

            if (response.ok) {
                const result = await response.json();
                selectedFile.focal_x = focalX;
                selectedFile.focal_y = focalY;

                // Update in list
                const index = displayMedia.findIndex(f => f.id === selectedFile.id);
                if (index !== -1) {
                    displayMedia[index] = result.media;
                }

                alert('Focal point saved');
                showFocalPoint = false;
            } else {
                alert('Failed to save focal point');
            }
        } catch (err) {
            console.error(err);
            alert('An error occurred');
        }
    }

    async function saveMetadata() {
        try {
            const response = await fetch(`${normalizedAdminPath}/media`, {
                method: 'PUT',
                headers: {
                    'Content-Type': 'application/json',
                    'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content
                },
                body: JSON.stringify({
                    id: selectedFile.id,
                    metadata: metadata
                })
            });

            if (response.ok) {
                const result = await response.json();
                selectedFile.metadata = metadata;

                // Update in list
                const index = displayMedia.findIndex(f => f.id === selectedFile.id);
                if (index !== -1) {
                    displayMedia[index] = result.media;
                }
                alert('Metadata saved');
            } else {
                alert('Failed to save metadata');
            }
        } catch (err) {
            console.error(err);
            alert('An error occurred');
        }
    }
</script>

<div class="ui grid">
    <div class="row">
        {#if !isPicker}
            <div class="column">
                <h1 class="ui header">
                    <i class="images outline icon"></i>
                    <div class="content">
                        Media Manager
                        <div class="sub header">Manage your site's media files</div>
                    </div>
                </h1>
            </div>
        {/if}
    </div>

    <div class="row">
        <div class="{isPicker ? 'eleven' : 'twelve'} wide column">
            <div class="ui segment">
                <div class="ui top attached menu">
                    {#if userPermissions['upload-media']}
                        <div class="item">
                            <label for="media-upload" class="ui primary button {uploading ? 'loading disabled' : ''}">
                                <i class="upload icon"></i> Upload File
                            </label>
                            <input type="file" id="media-upload" hidden onchange={handleUpload} accept="image/*" />
                        </div>
                    {/if}
                </div>
                <div class="ui attached segment" style="min-height: {isPicker ? '300px' : '400px'}; max-height: {isPicker ? '400px' : '600px'}; overflow-y: auto;">
                    {#if displayMedia.length === 0}
                        <div class="ui placeholder segment">
                            <div class="ui icon header">
                                <i class="images outline icon"></i>
                                No media files found.
                            </div>
                        </div>
                    {:else}
                        <div class="ui {isPicker ? 'four' : 'five'} cards">
                            {#each displayMedia as file}
                                <div class="card {selectedFile?.id === file.id ? 'blue' : ''}"
                                     role="button"
                                     tabindex="0"
                                     onkeydown={(e) => handleKeydown(e, () => selectFile(file))}
                                     onclick={() => selectFile(file)}
                                     style="cursor: pointer;">
                                    <div class="image" style="height: {isPicker ? '100px' : '150px'}; overflow: hidden; background: #eee; display: flex; align-items: center; justify-content: center;">
                                        {#if file.mime_type.startsWith('image/')}
                                            <img src="/media/{file.filename}?w=200&h=200&fit=crop" alt={file.filename} style="object-fit: cover; width: 100%; height: 100%;" />
                                        {:else}
                                            <i class="huge file outline icon"></i>
                                        {/if}
                                    </div>
                                    <div class="extra content" style="padding: 5px;">
                                        <div class="header" style="font-size: 0.8em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">
                                            {file.filename}
                                        </div>
                                    </div>
                                </div>
                            {/each}
                        </div>
                    {/if}
                </div>
            </div>
        </div>

        <div class="{isPicker ? 'five' : 'four'} wide column">
            <div class="ui segment">
                <h3 class="ui header">Details</h3>
                {#if selectedFile}
                    <div class="ui list">
                        <div class="item">
                            <div class="content">
                                <strong>Name:</strong> {selectedFile.filename}
                            </div>
                        </div>
                        <div class="item">
                            <div class="content">
                                <strong>Type:</strong> {selectedFile.mime_type}
                            </div>
                        </div>
                        <div class="item">
                            <div class="content">
                                <strong>Size:</strong> {formatBytes(selectedFile.size)}
                            </div>
                        </div>
                    </div>

                    {#if isPicker}
                        <div class="ui divider"></div>
                        <button class="ui fluid primary button" onclick={() => onSelect(selectedFile)}>
                            <i class="check icon"></i> Select File
                        </button>
                    {/if}

                    <div class="ui divider"></div>

                    {#if selectedFile.mime_type.startsWith('image/')}
                        <div class="ui segment secondary small">
                            <h4 class="ui header">Metadata</h4>
                            <div class="ui menu secondary pointing mini">
                                {#each availableLocales as loc}
                                    <button type="button"
                                            class="item {activeLocale === loc ? 'active' : ''}"
                                            onclick={() => activeLocale = loc}>
                                        {loc.toUpperCase()}
                                    </button>
                                {/each}
                            </div>

                            <div class="field mt-2">
                                <label for="media-caption-{activeLocale}" class="tiny-label">Caption ({activeLocale.toUpperCase()})</label>
                                <input type="text"
                                       id="media-caption-{activeLocale}"
                                       class="ui mini input fluid"
                                       bind:value={metadata[activeLocale].caption}
                                       placeholder="Caption">
                            </div>
                            <div class="field mt-2">
                                <label for="media-alt-{activeLocale}" class="tiny-label">Alt Text ({activeLocale.toUpperCase()})</label>
                                <input type="text"
                                       id="media-alt-{activeLocale}"
                                       class="ui mini input fluid"
                                       bind:value={metadata[activeLocale].alt}
                                       placeholder="Alt Text">
                            </div>

                            {#if userPermissions['update-media']}
                                <button class="ui fluid green mini button mt-2" onclick={saveMetadata}>
                                    Save Metadata
                                </button>
                            {/if}
                        </div>

                        {#if userPermissions['update-media']}
                            <button class="ui fluid button" onclick={() => showFocalPoint = !showFocalPoint}>
                                <i class="crosshairs icon"></i> Set Focal Point
                            </button>
                        {/if}

                        {#if showFocalPoint && userPermissions['update-media']}
                            <div class="ui segment p-0 mt-2" style="position: relative;">
                                <div
                                    bind:this={focalPointRef}
                                    role="button"
                                    tabindex="0"
                                    aria-label="Set focal point"
                                    onkeydown={(e) => handleKeydown(e, (ev) => setFocalPoint(ev || e))}
                                    onclick={setFocalPoint}
                                    style="cursor: crosshair; position: relative;"
                                >
                                    <img src="/media/{selectedFile.filename}?w=400" alt="Focal selector" class="ui fluid image" />
                                    <div
                                        style="position: absolute; left: {focalX}%; top: {focalY}%; width: 20px; height: 20px; border: 2px solid white; border-radius: 50%; box-shadow: 0 0 5px rgba(0,0,0,0.5); transform: translate(-50%, -50%); pointer-events: none;"
                                    >
                                        <div style="position: absolute; left: 50%; top: 50%; width: 4px; height: 4px; background: red; border-radius: 50%; transform: translate(-50%, -50%);"></div>
                                    </div>
                                </div>
                                <div class="ui segment basic tiny">
                                    X: {focalX}% Y: {focalY}%
                                    <div class="ui two buttons mt-2">
                                        <button class="ui green tiny button" onclick={saveFocalPoint}>Save</button>
                                        <button class="ui tiny button" onclick={() => showFocalPoint = false}>Cancel</button>
                                    </div>
                                </div>
                            </div>
                        {/if}
                    {/if}

                    <div class="ui divider"></div>

                    <div class="ui vertical buttons fluid">
                        <a href={selectedFile.url} target="_blank" class="ui button">
                            <i class="external alternate icon"></i> View Original
                        </a>
                        {#if !isPicker && userPermissions['delete-media']}
                            <button class="ui red button" onclick={() => deleteFile(selectedFile)}>
                                <i class="trash icon"></i> Delete
                            </button>
                        {/if}
                    </div>
                {:else}
                    <div class="ui message">Select a file to see details</div>
                {/if}
            </div>
        </div>
    </div>
</div>

<style>
    .mt-2 { margin-top: 0.5rem; }
    .p-0 { padding: 0 !important; }
    .tiny-label { font-size: 0.8em; font-weight: bold; display: block; margin-bottom: 2px; }
</style>
