// ============================================================
// Callbacks: CRUD management
// ============================================================

import { t, showToast, escapeHtml, closeDialog, showConfirm, getAuthHeaders, hasCredentials } from './core.js';
import { IconSelect } from './icon-select.js';
import { callbackEventIcons } from './icons.js';

export let callbackFormDirty = false;
export function setCallbackFormDirty(value) { callbackFormDirty = value; }

let _callbackEventIconSelect = null;

function _ensureCallbackEventIconSelect() {
    if (_callbackEventIconSelect) return;
    const select = document.getElementById('callbackName');
    if (!select) return;

    const items = Object.entries(callbackEventIcons).map(([value, icon]) => ({
        value,
        icon,
        label: value,
    }));

    _callbackEventIconSelect = new IconSelect({
        target: select,
        items,
        columns: 3,
        placeholder: t('callbacks.placeholder.event'),
        onChange: () => { callbackFormDirty = true; },
    });
}

let _loadCallbacksPromise = null;
export async function loadCallbacksTable() {
    if (_loadCallbacksPromise) return _loadCallbacksPromise;
    _loadCallbacksPromise = _loadCallbacksTableImpl();
    _loadCallbacksPromise.finally(() => { _loadCallbacksPromise = null; });
    return _loadCallbacksPromise;
}

async function _loadCallbacksTableImpl() {
    const tbody = document.getElementById('callbacksTableBody');

    try {
        const response = await fetch('/api/callbacks/list', {
            headers: getAuthHeaders()
        });

        if (!response.ok) {
            throw new Error('Failed to fetch callbacks');
        }

        const callbacksList = await response.json();

        if (callbacksList.length === 0) {
            tbody.innerHTML = '<tr><td colspan="4" class="empty-state"><div class="empty-state-illustration"><svg viewBox="0 0 64 64"><circle cx="32" cy="32" r="24"/><path d="M32 20v12l8 8"/></svg><p>' + t('callbacks.empty') + '</p></div></td></tr>';
            return;
        }

        tbody.innerHTML = callbacksList.map(callback => `
            <tr>
                <td><code>${escapeHtml(callback.name)}</code></td>
                <td style="max-width: 200px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;"
                    title="${escapeHtml(callback.command)}">${escapeHtml(callback.command)}</td>
                <td>${callback.timeout}s</td>
                <td>
                    <div class="action-buttons">
                        <button class="action-btn execute" data-action="execute" data-callback-name="${escapeHtml(callback.name)}" title="Execute callback">
                            <svg viewBox="0 0 24 24"><path d="M8 5v14l11-7z"/></svg>
                        </button>
                        <button class="action-btn" data-action="edit" data-callback-name="${escapeHtml(callback.name)}" title="Edit callback">
                            <svg viewBox="0 0 24 24"><path d="M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.39-.39-1.02-.39-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z"/></svg>
                        </button>
                        <button class="action-btn delete" data-action="delete" data-callback-name="${escapeHtml(callback.name)}" title="Delete callback">
                            <svg viewBox="0 0 24 24"><path d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"/></svg>
                        </button>
                    </div>
                </td>
            </tr>
        `).join('');
    } catch (error) {
        console.error('Error loading callbacks:', error);
        tbody.innerHTML = `<tr><td colspan="4" class="empty-state" style="color: var(--error);">${escapeHtml(t('callbacks.msg.load_failed'))}</td></tr>`;
    }
}

export function showAddCallbackDialog() {
    const dialog = document.getElementById('callbackDialog');
    const form = document.getElementById('callbackForm');
    const title = document.getElementById('callbackDialogTitle');

    form.reset();
    document.getElementById('callbackIsEdit').value = 'false';
    document.getElementById('callbackName').disabled = false;
    title.textContent = t('callbacks.dialog.add');

    _ensureCallbackEventIconSelect();
    if (_callbackEventIconSelect) _callbackEventIconSelect.setValue('', false);

    callbackFormDirty = false;

    document.body.classList.add('dialog-open');
    dialog.showModal();
}

export async function showEditCallbackDialog(callbackName) {
    const dialog = document.getElementById('callbackDialog');
    const title = document.getElementById('callbackDialogTitle');

    try {
        const response = await fetch('/api/callbacks/list', {
            headers: getAuthHeaders()
        });

        if (!response.ok) {
            throw new Error('Failed to fetch callback details');
        }

        const callbacksList = await response.json();
        const callback = callbacksList.find(c => c.name === callbackName);

        if (!callback) {
            showToast(t('callbacks.msg.not_found'), 'error');
            return;
        }

        document.getElementById('callbackIsEdit').value = 'true';
        document.getElementById('callbackName').value = callbackName;
        document.getElementById('callbackName').disabled = true;

        _ensureCallbackEventIconSelect();
        if (_callbackEventIconSelect) _callbackEventIconSelect.setValue(callbackName, false);
        document.getElementById('callbackCommand').value = callback.command;
        document.getElementById('callbackTimeout').value = callback.timeout;
        document.getElementById('callbackWorkingDir').value = callback.working_dir || '';

        title.textContent = t('callbacks.dialog.edit');
        callbackFormDirty = false;

        document.body.classList.add('dialog-open');
        dialog.showModal();
    } catch (error) {
        console.error('Error loading callback for edit:', error);
        showToast(t('callbacks.msg.load_failed'), 'error');
    }
}

export async function closeCallbackDialog() {
    if (callbackFormDirty) {
        if (!await showConfirm(t('callbacks.confirm.unsaved'))) {
            return;
        }
    }

    const dialog = document.getElementById('callbackDialog');
    callbackFormDirty = false;
    closeDialog(dialog);
    document.body.classList.remove('dialog-open');
}

export async function saveCallback(event) {
    event.preventDefault();

    const submitBtn = event.target.querySelector('button[type="submit"]');
    if (submitBtn) submitBtn.disabled = true;

    const isEdit = document.getElementById('callbackIsEdit').value === 'true';
    const callbackName = document.getElementById('callbackName').value;

    const data = {
        command: document.getElementById('callbackCommand').value,
        timeout: parseInt(document.getElementById('callbackTimeout').value) || 30,
        working_dir: document.getElementById('callbackWorkingDir').value || null,
        shell: true
    };

    const encodedName = encodeURIComponent(callbackName);
    const endpoint = isEdit ?
        `/api/callbacks/update/${encodedName}` :
        `/api/callbacks/create/${encodedName}`;

    const method = isEdit ? 'PUT' : 'POST';

    try {
        const response = await fetch(endpoint, {
            method,
            headers: { 'Content-Type': 'application/json', ...getAuthHeaders() },
            body: JSON.stringify(data)
        });

        const result = await response.json();

        if (response.ok && result.success) {
            showToast(t(isEdit ? 'callbacks.msg.updated' : 'callbacks.msg.created'), 'success');
            callbackFormDirty = false;
            closeCallbackDialog();
            loadCallbacksTable();
        } else {
            showToast(result.detail || t(isEdit ? 'callbacks.msg.update_failed' : 'callbacks.msg.create_failed'), 'error');
        }
    } catch (error) {
        console.error('Error saving callback:', error);
        showToast(t(isEdit ? 'callbacks.msg.update_failed' : 'callbacks.msg.create_failed'), 'error');
    } finally {
        if (submitBtn) submitBtn.disabled = false;
    }
}

export async function deleteCallbackConfirm(callbackName) {
    if (!await showConfirm(t('callbacks.confirm.delete').replace('{name}', callbackName))) {
        return;
    }

    try {
        const response = await fetch(`/api/callbacks/delete/${encodeURIComponent(callbackName)}`, {
            method: 'DELETE',
            headers: getAuthHeaders()
        });

        const result = await response.json();

        if (response.ok && result.success) {
            showToast(t('callbacks.msg.deleted'), 'success');
            loadCallbacksTable();
        } else {
            showToast(result.detail || t('callbacks.msg.delete_failed'), 'error');
        }
    } catch (error) {
        console.error('Error deleting callback:', error);
        showToast(t('callbacks.msg.delete_failed'), 'error');
    }
}
