/**
 * AniWorld - Edit Modal Component
 *
 * Modal dialog for viewing/editing anime metadata (key, tmdb_id, tvdb_id)
 * and NFO diagnostics with repair functionality.
 *
 * Dependencies: api-client.js, ui-utils.js
 */

var AniWorld = window.AniWorld || {};

AniWorld.EditModal = (function() {
    'use strict';

    let modalElement = null;
    let originalData = null;
    let currentKey = null;

    /**
     * Open the edit modal for a specific anime series.
     * @param {string} seriesKey - The series key to edit
     */
    async function open(seriesKey) {
        currentKey = seriesKey;
        modalElement = document.getElementById('edit-metadata-modal');
        if (!modalElement) return;

        // Show modal
        modalElement.classList.remove('hidden');

        // Reset form state
        setLoading(true);
        clearErrors();
        hideKeyWarning();

        try {
            // Find series data from the local series list
            const seriesData = findSeriesData(seriesKey);

            originalData = {
                key: seriesKey,
                tmdb_id: seriesData ? seriesData.tmdb_id : null,
                tvdb_id: seriesData ? seriesData.tvdb_id : null,
            };

            // Populate form fields
            setFieldValue('edit-key', originalData.key);
            setFieldValue('edit-tmdb-id', originalData.tmdb_id || '');
            setFieldValue('edit-tvdb-id', originalData.tvdb_id || '');

            // Load NFO diagnostics
            await loadDiagnostics(seriesKey);

        } catch (err) {
            AniWorld.UI.showToast('Failed to load series data', 'error');
            console.error('Edit modal load error:', err);
        } finally {
            setLoading(false);
        }

        // Attach event listeners
        attachListeners();
    }

    /**
     * Close the edit modal and reset state.
     */
    function close() {
        if (modalElement) {
            modalElement.classList.add('hidden');
        }
        originalData = null;
        currentKey = null;
        detachListeners();
    }

    /**
     * Save changed metadata to the backend.
     */
    async function save() {
        clearErrors();

        const newKey = getFieldValue('edit-key').trim().toLowerCase();
        const tmdbIdStr = getFieldValue('edit-tmdb-id').trim();
        const tvdbIdStr = getFieldValue('edit-tvdb-id').trim();

        // Validate key
        if (!newKey) {
            showFieldError('edit-key', 'Key cannot be empty');
            return;
        }
        if (!/^[a-z0-9][a-z0-9-]*[a-z0-9]$|^[a-z0-9]$/.test(newKey)) {
            showFieldError('edit-key', 'Key must contain only lowercase letters, numbers, and hyphens');
            return;
        }

        // Validate IDs
        const tmdbId = tmdbIdStr ? parseInt(tmdbIdStr, 10) : null;
        const tvdbId = tvdbIdStr ? parseInt(tvdbIdStr, 10) : null;

        if (tmdbIdStr && (isNaN(tmdbId) || tmdbId < 1)) {
            showFieldError('edit-tmdb-id', 'TMDB ID must be a positive number');
            return;
        }
        if (tvdbIdStr && (isNaN(tvdbId) || tvdbId < 1)) {
            showFieldError('edit-tvdb-id', 'TVDB ID must be a positive number');
            return;
        }

        // Check if key changed — show confirmation
        if (newKey !== originalData.key) {
            const confirmed = await AniWorld.UI.showConfirmModal(
                'Rename Series Key',
                `Changing the key from "${originalData.key}" to "${newKey}" will update the primary identifier. ` +
                'This may affect provider linkage. Are you sure?'
            );
            if (!confirmed) return;
        }

        // Build update payload (only changed fields)
        const payload = {};
        if (newKey !== originalData.key) payload.key = newKey;
        if (tmdbId !== originalData.tmdb_id) payload.tmdb_id = tmdbId;
        if (tvdbId !== originalData.tvdb_id) payload.tvdb_id = tvdbId;

        if (Object.keys(payload).length === 0) {
            AniWorld.UI.showToast('No changes to save', 'info');
            return;
        }

        // Send update
        setSaveLoading(true);
        try {
            const response = await AniWorld.ApiClient.put(
                '/api/anime/' + encodeURIComponent(currentKey),
                payload
            );

            if (!response) return;

            if (response.ok) {
                const result = await response.json();
                AniWorld.UI.showToast('Metadata updated successfully', 'success');

                // Update local state
                const oldKey = currentKey;
                currentKey = result.key;
                originalData = {
                    key: result.key,
                    tmdb_id: result.tmdb_id,
                    tvdb_id: result.tvdb_id,
                };

                // Update the card in the DOM
                updateCardAfterSave(oldKey, result);

                // Update repair button state
                updateRepairButtonState();

            } else if (response.status === 409) {
                showFieldError('edit-key', 'A series with this key already exists');
            } else if (response.status === 422) {
                const err = await response.json();
                AniWorld.UI.showToast('Validation error: ' + (err.detail || 'Invalid input'), 'error');
            } else {
                AniWorld.UI.showToast('Failed to update metadata', 'error');
            }
        } catch (err) {
            AniWorld.UI.showToast('Connection error. Check your network.', 'error');
            console.error('Save error:', err);
        } finally {
            setSaveLoading(false);
        }
    }

    /**
     * Trigger NFO repair for the current series.
     */
    async function repairNfo() {
        setRepairLoading(true);
        try {
            const response = await AniWorld.ApiClient.post(
                '/api/nfo/' + encodeURIComponent(currentKey) + '/repair',
                {}
            );

            if (!response) return;

            if (response.ok) {
                const result = await response.json();
                AniWorld.UI.showToast(result.message, 'success');

                // Refresh diagnostics
                await loadDiagnostics(currentKey);
            } else if (response.status === 400) {
                const err = await response.json();
                AniWorld.UI.showToast(err.detail || 'Cannot repair NFO', 'error');
            } else {
                AniWorld.UI.showToast('Failed to repair NFO', 'error');
            }
        } catch (err) {
            AniWorld.UI.showToast('Connection error during repair', 'error');
            console.error('Repair error:', err);
        } finally {
            setRepairLoading(false);
        }
    }

    /**
     * Load NFO diagnostics for the current series.
     * @param {string} key - Series key
     */
    async function loadDiagnostics(key) {
        const container = document.getElementById('nfo-diagnostics-container');
        if (!container) return;

        try {
            const response = await AniWorld.ApiClient.get(
                '/api/nfo/' + encodeURIComponent(key) + '/diagnostics'
            );

            if (!response || !response.ok) {
                container.innerHTML = '<p class="nfo-error">Failed to load NFO diagnostics</p>';
                return;
            }

            const data = await response.json();
            renderDiagnostics(data);
            updateRepairButtonState();

        } catch (err) {
            container.innerHTML = '<p class="nfo-error">Error loading diagnostics</p>';
            console.error('Diagnostics error:', err);
        }
    }

    /**
     * Render NFO diagnostics data into the modal.
     * @param {Object} data - NfoDiagnosticsResponse
     */
    function renderDiagnostics(data) {
        const badge = document.getElementById('nfo-status-badge');
        const tagsList = document.getElementById('nfo-missing-tags');

        if (badge) {
            if (!data.has_nfo) {
                badge.className = 'nfo-status-badge nfo-missing';
                badge.textContent = 'No NFO File';
            } else if (data.missing_tags.length === 0) {
                badge.className = 'nfo-status-badge nfo-complete';
                badge.textContent = 'Complete';
            } else {
                badge.className = 'nfo-status-badge nfo-incomplete';
                badge.textContent = data.missing_tags.length + ' Missing';
            }
        }

        if (tagsList) {
            if (data.missing_tags.length === 0) {
                tagsList.innerHTML = '<p class="nfo-all-good">All required tags present</p>';
            } else {
                tagsList.innerHTML = data.missing_tags.map(function(tag) {
                    return '<span class="missing-tag-chip">' + escapeHtml(tag) + '</span>';
                }).join('');
            }
        }
    }

    /**
     * Update repair button disabled state based on tmdb_id field.
     */
    function updateRepairButtonState() {
        const btn = document.getElementById('btn-repair-nfo');
        const hint = document.getElementById('repair-hint');
        const tmdbValue = getFieldValue('edit-tmdb-id').trim();

        if (btn) {
            // Enable repair even without tmdb_id — the service can search by name
            btn.disabled = false;
        }
        if (hint) {
            hint.style.display = tmdbValue ? 'none' : 'block';
        }
    }

    // ---- Helpers ----

    function findSeriesData(key) {
        // Access the series data from the series manager if available
        if (AniWorld.SeriesManager && AniWorld.SeriesManager.getSeriesData) {
            const allSeries = AniWorld.SeriesManager.getSeriesData();
            if (allSeries) {
                return allSeries.find(function(s) { return s.key === key; });
            }
        }
        return null;
    }

    function updateCardAfterSave(oldKey, result) {
        const card = document.querySelector('[data-series-id="' + oldKey + '"]');
        if (card) {
            card.setAttribute('data-key', result.key);
            card.setAttribute('data-series-id', result.key);
            // Update checkbox data-key
            const checkbox = card.querySelector('.series-checkbox');
            if (checkbox) {
                checkbox.setAttribute('data-key', result.key);
            }
        }

        // Update local series data array
        if (AniWorld.SeriesManager && AniWorld.SeriesManager.updateSeriesKey) {
            AniWorld.SeriesManager.updateSeriesKey(oldKey, result.key);
        }
    }

    function setFieldValue(id, value) {
        const el = document.getElementById(id);
        if (el) el.value = value !== null && value !== undefined ? value : '';
    }

    function getFieldValue(id) {
        const el = document.getElementById(id);
        return el ? el.value : '';
    }

    function showFieldError(fieldId, message) {
        const el = document.getElementById(fieldId);
        if (el) {
            const errorEl = el.parentElement.querySelector('.field-error');
            if (errorEl) {
                errorEl.textContent = message;
                errorEl.style.display = 'block';
            }
            el.classList.add('input-error');
        }
    }

    function clearErrors() {
        if (!modalElement) return;
        modalElement.querySelectorAll('.field-error').forEach(function(el) {
            el.style.display = 'none';
            el.textContent = '';
        });
        modalElement.querySelectorAll('.input-error').forEach(function(el) {
            el.classList.remove('input-error');
        });
    }

    function hideKeyWarning() {
        const warning = document.getElementById('key-change-warning');
        if (warning) warning.style.display = 'none';
    }

    function setLoading(loading) {
        const form = document.getElementById('edit-metadata-form');
        if (form) {
            form.style.opacity = loading ? '0.5' : '1';
            form.style.pointerEvents = loading ? 'none' : 'auto';
        }
    }

    function setSaveLoading(loading) {
        const btn = document.getElementById('btn-save-metadata');
        if (btn) {
            btn.disabled = loading;
            btn.innerHTML = loading
                ? '<i class="fa-solid fa-spinner fa-spin"></i> Saving...'
                : '<i class="fa-solid fa-floppy-disk"></i> Save';
        }
    }

    function setRepairLoading(loading) {
        const btn = document.getElementById('btn-repair-nfo');
        if (btn) {
            btn.disabled = loading;
            btn.innerHTML = loading
                ? '<i class="fa-solid fa-spinner fa-spin"></i> Repairing...'
                : '<i class="fa-solid fa-wrench"></i> Repair NFO';
        }
    }

    function escapeHtml(str) {
        var div = document.createElement('div');
        div.textContent = str;
        return div.innerHTML;
    }

    // Event listener management
    let listeners = [];

    function attachListeners() {
        detachListeners();

        const saveBtn = document.getElementById('btn-save-metadata');
        const cancelBtn = document.getElementById('btn-cancel-metadata');
        const repairBtn = document.getElementById('btn-repair-nfo');
        const overlay = modalElement ? modalElement.querySelector('.modal-overlay') : null;
        const keyInput = document.getElementById('edit-key');

        if (saveBtn) {
            var saveFn = function() { save(); };
            saveBtn.addEventListener('click', saveFn);
            listeners.push({ el: saveBtn, event: 'click', fn: saveFn });
        }

        if (cancelBtn) {
            var cancelFn = function() { close(); };
            cancelBtn.addEventListener('click', cancelFn);
            listeners.push({ el: cancelBtn, event: 'click', fn: cancelFn });
        }

        if (repairBtn) {
            var repairFn = function() { repairNfo(); };
            repairBtn.addEventListener('click', repairFn);
            listeners.push({ el: repairBtn, event: 'click', fn: repairFn });
        }

        if (overlay) {
            var overlayFn = function() { close(); };
            overlay.addEventListener('click', overlayFn);
            listeners.push({ el: overlay, event: 'click', fn: overlayFn });
        }

        if (keyInput) {
            var keyFn = function() {
                var warning = document.getElementById('key-change-warning');
                if (warning) {
                    warning.style.display = keyInput.value !== originalData.key ? 'block' : 'none';
                }
            };
            keyInput.addEventListener('input', keyFn);
            listeners.push({ el: keyInput, event: 'input', fn: keyFn });
        }
    }

    function detachListeners() {
        listeners.forEach(function(l) {
            l.el.removeEventListener(l.event, l.fn);
        });
        listeners = [];
    }

    return {
        open: open,
        close: close,
        save: save,
        repairNfo: repairNfo
    };
})();
