<?php


$_atEntity = $aiTranslateEntityType ?? 'tags';
$_atLabel  = $_atEntity === 'categories' ? 'Categories' : 'Tags';
$_atSingle = $_atEntity === 'categories' ? 'category' : 'tag';

 
$_atCreditRate = (static function () {
    $r = Setting::get('catalogue_credit_rate', '');
    return $r !== '' ? (float) $r : 0.01;
})();
?>


<div id="atOverlay" class="hidden fixed inset-0 bg-black/50 backdrop-blur-sm z-[70] transition-opacity" onclick="AT.close()"></div>
<div id="atModal" class="hidden fixed inset-0 z-[70] flex items-center justify-center p-4">
    <div class="bg-white rounded-2xl shadow-2xl w-full max-w-lg overflow-hidden" onclick="event.stopPropagation()">

        
        <div class="px-6 pt-5 pb-4 border-b border-gray-100">
            <div class="flex items-start justify-between">
                <div>
                    <h3 class="text-base font-bold text-gray-900 flex items-center gap-2">
                        <i class="fa-solid fa-language text-sky-500"></i>
                        <span id="atTitle">AI Translate <?= $_atLabel ?></span>
                    </h3>
                    <p class="text-xs text-gray-500 mt-0.5" id="atSubtitle"></p>
                </div>
                <button type="button" onclick="AT.close()" class="p-1.5 text-gray-400 hover:text-gray-600 rounded-lg hover:bg-gray-100 transition-colors">
                    <svg class="w-5 h-5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"/></svg>
                </button>
            </div>
        </div>

        
        <div id="atStep1" class="px-6 py-5 space-y-4">

            
            <div id="atLoading" class="text-center py-8">
                <svg class="w-6 h-6 mx-auto mb-2 animate-spin text-gray-300" fill="none" viewBox="0 0 24 24"><circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"/><path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"/></svg>
                <p class="text-sm text-gray-400">Preparing translation...</p>
            </div>

            
            <div id="atSummary" class="hidden space-y-4">
                
                <div class="rounded-xl border border-gray-200 overflow-hidden">
                    <div class="px-4 py-3 bg-gray-50/80 border-b border-gray-100">
                        <span class="text-xs font-bold text-gray-900 uppercase tracking-wider">Translation Summary</span>
                    </div>
                    <div class="divide-y divide-gray-100">
                        <div class="px-4 py-2.5 flex items-center justify-between text-sm">
                            <span class="flex items-center gap-2 text-gray-700">
                                <i class="fa-solid fa-<?= $_atEntity === 'categories' ? 'folder' : 'tag' ?> text-gray-400 text-xs"></i>
                                <?= $_atLabel ?> to translate
                            </span>
                            <span class="font-semibold text-gray-900" id="atItemCount">0</span>
                        </div>
                        <div class="px-4 py-2.5 flex items-center justify-between text-sm">
                            <span class="flex items-center gap-2 text-gray-700">
                                <i class="fa-solid fa-globe text-sky-400 text-xs"></i>
                                Target languages
                            </span>
                            <span class="font-semibold text-gray-900" id="atLangCount">0</span>
                        </div>
                        <div class="px-4 py-2.5" id="atLangFlags"></div>
                    </div>
                    
                    <div class="px-4 py-3 bg-sky-50/60 border-t border-sky-100">
                        <div class="flex items-center justify-between text-xs text-gray-500 mb-1">
                            <span>Cost per <?= $_atSingle ?></span>
                            <span>
                                <span id="atCostPer">0.50 Cr</span>
                                <span class="text-gray-400" id="atCostPerUsd"></span>
                            </span>
                        </div>
                        <div class="flex items-center justify-between pt-1.5 border-t border-sky-200">
                            <span class="text-sm font-bold text-gray-900">Total cost</span>
                            <span class="flex items-baseline gap-1.5">
                                <span class="text-base font-bold text-sky-700" id="atTotalCost">0.00 Cr</span>
                                <span class="text-xs font-medium text-gray-400" id="atTotalCostUsd"></span>
                            </span>
                        </div>
                    </div>
                </div>

                
                <div class="flex items-center justify-between px-4 py-2.5 rounded-xl border border-gray-200">
                    <span class="text-sm text-gray-600">Your balance</span>
                    <span class="text-sm font-bold" id="atBalance">0.00 Cr</span>
                </div>

                
                <div id="atWarnings" class="hidden space-y-2"></div>

                
                <div id="atNotConnectedWarn" class="hidden rounded-xl bg-blue-50 border border-blue-200 p-4">
                    <div class="flex items-start gap-3">
                        <div class="w-9 h-9 rounded-lg bg-blue-100 flex items-center justify-center shrink-0">
                            <svg class="w-5 h-5 text-blue-600" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m9.86-2.54a4.5 4.5 0 00-1.242-7.244l-4.5-4.5a4.5 4.5 0 00-6.364 6.364L4.343 8.28"/></svg>
                        </div>
                        <div class="flex-1 min-w-0">
                            <div class="text-sm font-bold text-blue-800">Connect your TubePress account</div>
                            <p class="text-xs text-blue-700 mt-1 leading-relaxed">Connect your account to use AI translation. It only takes a few seconds.</p>
                        </div>
                    </div>
                    <div class="flex items-center gap-2 mt-3 ml-12">
                        <button type="button" onclick="AT.connect()" id="atConnectBtn" class="inline-flex items-center gap-1.5 px-4 py-2 text-sm font-semibold text-white bg-blue-600 hover:bg-blue-700 rounded-lg transition-colors">
                            <svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m9.86-2.54a4.5 4.5 0 00-1.242-7.244l-4.5-4.5a4.5 4.5 0 00-6.364 6.364L4.343 8.28"/></svg>
                            Connect
                        </button>
                    </div>
                </div>

                
                <div id="atInsufficientWarn" class="hidden rounded-xl bg-amber-50 border border-amber-300 p-4">
                    <div class="flex items-start gap-3">
                        <div class="w-9 h-9 rounded-lg bg-amber-100 flex items-center justify-center shrink-0">
                            <svg class="w-5 h-5 text-amber-600" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126zM12 15.75h.007v.008H12v-.008z"/></svg>
                        </div>
                        <div class="flex-1 min-w-0">
                            <div class="text-sm font-bold text-amber-800">Insufficient Credits</div>
                            <p class="text-xs text-amber-700 mt-1 leading-relaxed" id="atInsufficientMsg"></p>
                        </div>
                    </div>
                    <div class="flex items-center gap-2 mt-3 ml-12">
                        <button type="button" onclick="AT.openTopUp()" class="inline-flex items-center gap-1.5 px-4 py-2 text-sm font-semibold text-white bg-amber-500 hover:bg-amber-600 rounded-lg transition-colors">
                            <svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="2.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M12 4.5v15m7.5-7.5h-15"/></svg>
                            Buy Credits
                        </button>
                    </div>
                </div>

                
                <label class="flex items-center gap-2 cursor-pointer">
                    <input type="checkbox" id="atSkipTranslated" checked class="w-4 h-4 rounded border-gray-300 text-sky-600 focus:ring-sky-500">
                    <span class="text-xs text-gray-600">Skip already translated <?= strtolower($_atLabel) ?></span>
                </label>

                
                <label class="flex items-center gap-2 cursor-pointer">
                    <input type="checkbox" id="atAutoNew" onchange="AT.setAuto(this)" <?= Setting::get('entity_autotranslate_' . $_atSingle, '0') === '1' ? 'checked' : '' ?> class="w-4 h-4 rounded border-gray-300 text-emerald-600 focus:ring-emerald-500">
                    <span class="text-xs text-gray-600"><i class="fa-solid fa-bolt text-emerald-500 mr-0.5"></i> Auto-translate new <?= strtolower($_atLabel) ?> as they're added</span>
                </label>
            </div>
        </div>

        
        <div id="atStep2" class="hidden px-6 py-5 space-y-4">
            <div class="space-y-2">
                <div class="flex items-center justify-between text-xs text-gray-500">
                    <span id="atProgressLabel">Translating...</span>
                    <span id="atProgressPct">0%</span>
                </div>
                <div class="w-full h-2 bg-gray-100 rounded-full overflow-hidden">
                    <div id="atProgressBar" class="h-full bg-sky-500 rounded-full transition-all duration-300" style="width:0%"></div>
                </div>
            </div>
            <div class="text-xs text-gray-500 flex items-center gap-3" id="atProgressStats">
                <span><i class="fa-solid fa-check text-green-500"></i> <span id="atDoneCount">0</span> done</span>
                <span><i class="fa-solid fa-xmark text-red-400"></i> <span id="atFailCount">0</span> failed</span>
            </div>
            
            <div id="atCurrentItem" class="px-3 py-2 bg-gray-50 rounded-lg text-xs text-gray-600 truncate">
                <i class="fa-solid fa-spinner fa-spin text-sky-500 mr-1"></i>
                <span id="atCurrentName">...</span>
            </div>
            
            <div class="space-y-2">
                <div class="flex items-center gap-2 px-3 py-2 bg-blue-50 border border-blue-100 rounded-lg text-[11px] text-blue-600">
                    <i class="fa-solid fa-info-circle shrink-0"></i>
                    <span>You can safely close this window. Translation will continue in the background.</span>
                </div>
                <div class="flex items-center gap-2 px-3 py-2 bg-gray-50 border border-gray-200 rounded-lg text-[11px] text-gray-500">
                    <i class="fa-solid fa-coins shrink-0"></i>
                    <span>If you stop, untranslated items will be automatically refunded to your balance.</span>
                </div>
            </div>
            
            <div id="atErrorLog" class="hidden max-h-32 overflow-y-auto space-y-1"></div>
        </div>

        
        <div id="atStep3" class="hidden px-6 py-5 text-center">
            <div class="w-14 h-14 mx-auto mb-4 bg-green-100 rounded-full flex items-center justify-center">
                <svg class="w-7 h-7 text-green-600" fill="none" stroke="currentColor" stroke-width="2.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"/></svg>
            </div>
            <h4 class="text-lg font-bold text-gray-900 mb-1">Translation Complete</h4>
            <p class="text-sm text-gray-600 mb-4" id="atCompleteSummary"></p>
            <div class="inline-flex items-center gap-1.5 px-3 py-1.5 bg-green-50 border border-green-200 rounded-full text-xs font-semibold text-green-700">
                <svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M12 6v12m-3-2.818l.879.659c1.171.879 3.07.879 4.242 0 1.172-.879 1.172-2.303 0-3.182C13.536 12.219 12.768 12 12 12c-.725 0-1.45-.22-2.003-.659-1.106-.879-1.106-2.303 0-3.182s2.9-.879 4.006 0l.415.33M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>
                Balance: <span id="atFinalBalance">0.00</span> Cr
            </div>
        </div>

        
        <div class="px-6 py-3.5 bg-gray-50/80 border-t border-gray-100 flex items-center justify-between">
            <button type="button" id="atCancelBtn" onclick="AT.close()" class="text-sm text-gray-400 hover:text-gray-600 transition-colors">Cancel</button>
            <div class="flex items-center gap-2.5">
                <button type="button" id="atStopBtn" onclick="AT.stop()" class="hidden inline-flex items-center gap-1.5 px-4 py-2 text-sm font-semibold text-red-600 bg-red-50 hover:bg-red-100 border border-red-200 rounded-lg transition-colors">
                    <i class="fa-solid fa-stop"></i>
                    Stop
                </button>
                <button type="button" id="atStartBtn" onclick="AT.start()" class="inline-flex items-center gap-1.5 px-5 py-2 text-sm font-semibold text-white bg-sky-600 hover:bg-sky-700 rounded-lg transition-colors disabled:opacity-40 disabled:cursor-not-allowed" disabled>
                    <i class="fa-solid fa-language"></i>
                    Start Translation
                </button>
                <button type="button" id="atCloseBtn" onclick="AT.closeAndReload()" class="hidden inline-flex items-center gap-1.5 px-5 py-2 text-sm font-semibold text-white bg-green-600 hover:bg-green-700 rounded-lg transition-colors">
                    <i class="fa-solid fa-check"></i>
                    Done
                </button>
            </div>
        </div>
    </div>
</div>

<script>
(function(){
    const ENTITY = '<?= $_atEntity ?>';
    const CSRF   = '<?= Router::csrfToken() ?>';
    let CREDIT_RATE = <?= (float) $_atCreditRate ?>;  
    const POLL_MS = 2000;

    let state = { ids: [], jobId: null, pollTimer: null, _allMode: false, _originalIds: [] };

    function $(id){ return document.getElementById(id); }
    function show(el){ el && el.classList.remove('hidden'); }
    function hide(el){ el && el.classList.add('hidden'); }
    function fmtUsd(credits){
        var v = (parseFloat(credits) || 0) * CREDIT_RATE;
        if (v <= 0) return '~$0.00';
        
        
        var s = v.toFixed(2);
        if (parseFloat(s) === 0) s = v.toFixed(4);
        return '~$' + s;
    }

    const AT = window.AT = {

        open: function(mode, ids) {
            show($('atOverlay')); show($('atModal'));
            show($('atStep1')); hide($('atStep2')); hide($('atStep3'));
            show($('atLoading')); hide($('atSummary'));
            show($('atStartBtn')); hide($('atStopBtn')); hide($('atCloseBtn'));
            show($('atCancelBtn'));
            $('atStartBtn').disabled = true;
            $('atSkipTranslated').checked = true;
            state = { ids: [], jobId: null, pollTimer: null, _allMode: mode === 'all', _originalIds: ids };

            
            fetch('/admin/' + ENTITY + '/ai-translate-status', { credentials: 'same-origin' })
            .then(r => r.json())
            .then(data => {
                if (data.active) {
                    
                    state.jobId = data.job_id;
                    AT.showProgress(data);
                    return;
                }
                AT.loadInit(mode, ids, true);
            })
            .catch(() => AT.loadInit(mode, ids, true));
        },

        loadInit: function(mode, ids, skipTranslated) {
            var body = mode === 'all'
                ? { all: true, skip_translated: skipTranslated }
                : { ids: ids, skip_translated: skipTranslated };

            fetch('/admin/' + ENTITY + '/ai-translate-init', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': CSRF },
                body: JSON.stringify(body),
                credentials: 'same-origin'
            })
            .then(r => r.json())
            .then(data => {
                if (data.error) {
                    hide($('atLoading')); show($('atSummary'));
                    $('atSummary').innerHTML = '<div class="rounded-xl bg-red-50 border border-red-200 p-4 text-sm text-red-700"><i class="fa-solid fa-circle-exclamation mr-1"></i> ' + AT.esc(data.error) + '</div>';
                    return;
                }
                AT.renderSummary(data);
            })
            .catch(() => {
                hide($('atLoading')); show($('atSummary'));
                $('atSummary').innerHTML = '<div class="rounded-xl bg-red-50 border border-red-200 p-4 text-sm text-red-700"><i class="fa-solid fa-circle-exclamation mr-1"></i> Connection error.</div>';
            });
        },

        renderSummary: function(data) {
            hide($('atLoading')); show($('atSummary'));
            state.ids = data.ids || [];

            $('atItemCount').textContent = data.count;
            $('atLangCount').textContent = data.languages.length;
            var subtitle = data.count + ' ' + ENTITY + ' to translate into ' + data.languages.length + ' language(s)';
            if (data.warnings && data.warnings.length > 0 && data.count === 0) {
                subtitle = 'All selected ' + ENTITY + ' are already translated';
            }
            $('atSubtitle').textContent = subtitle;
            
            if (data.credit_rate) CREDIT_RATE = parseFloat(data.credit_rate);
            $('atCostPer').textContent = data.cost_per_item.toFixed(2) + ' Cr';
            $('atCostPerUsd').textContent = fmtUsd(data.cost_per_item);
            $('atTotalCost').textContent = data.total_cost.toFixed(2) + ' Cr';
            $('atTotalCostUsd').textContent = fmtUsd(data.total_cost);

            var balEl = $('atBalance');
            balEl.textContent = data.balance.toFixed(2) + ' Cr';
            balEl.className = 'text-sm font-bold ' + (data.sufficient ? 'text-green-600' : 'text-red-600');

            var flagsHtml = '<div class="flex flex-wrap gap-1.5">';
            (data.languages || []).forEach(function(l) {
                flagsHtml += '<span class="inline-flex items-center gap-1 px-2 py-0.5 bg-gray-100 rounded text-[11px] text-gray-700">';
                flagsHtml += '<img src="https://flagcdn.com/16x12/' + AT.esc(l.flag) + '.png" class="w-4 h-3" alt="">';
                flagsHtml += AT.esc(l.name) + '</span>';
            });
            flagsHtml += '</div>';
            $('atLangFlags').innerHTML = flagsHtml;

            
            hide($('atNotConnectedWarn'));
            hide($('atInsufficientWarn'));

            
            var warnEl = $('atWarnings');
            if (data.warnings && data.warnings.length > 0) {
                warnEl.innerHTML = data.warnings.map(function(w) {
                    return '<div class="flex items-start gap-2 px-3 py-2 bg-amber-50 border border-amber-200 rounded-lg text-xs text-amber-800"><i class="fa-solid fa-triangle-exclamation text-amber-500 mt-0.5 shrink-0"></i><span>' + AT.esc(w) + '</span></div>';
                }).join('');
                show(warnEl);
            } else {
                hide(warnEl);
            }

            if (data.count === 0) {
                
                $('atStartBtn').disabled = true;
                $('atStartBtn').innerHTML = '<i class="fa-solid fa-check text-green-400"></i> Nothing to translate';
            } else if (data.not_connected) {
                show($('atNotConnectedWarn'));
                $('atStartBtn').disabled = true;
            } else if (!data.sufficient) {
                show($('atInsufficientWarn'));
                $('atInsufficientMsg').innerHTML = 'You need <strong>' + data.total_cost.toFixed(2) + '</strong> credits but only have <strong>' + data.balance.toFixed(2) + '</strong>. Missing <strong>' + data.missing.toFixed(2) + '</strong> credits.';
                $('atStartBtn').disabled = true;
            } else {
                $('atStartBtn').disabled = false;
                $('atStartBtn').innerHTML = '<i class="fa-solid fa-language"></i> Start Translation';
            }

            $('atSkipTranslated').onchange = function() {
                show($('atLoading')); hide($('atSummary'));
                $('atStartBtn').disabled = true;
                AT.loadInit(state._allMode ? 'all' : 'selected', state._allMode ? [] : (state._originalIds || state.ids), this.checked);
            };
        },

         
        start: function() {
            if (state.ids.length === 0) return;
            $('atStartBtn').disabled = true;
            $('atStartBtn').innerHTML = '<i class="fa-solid fa-spinner fa-spin"></i> Starting...';

            fetch('/admin/' + ENTITY + '/ai-translate-start', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': CSRF },
                body: JSON.stringify({ ids: state.ids }),
                credentials: 'same-origin'
            })
            .then(r => r.json())
            .then(data => {
                if (data.error) {
                    $('atStartBtn').disabled = false;
                    $('atStartBtn').innerHTML = '<i class="fa-solid fa-language"></i> Start Translation';
                    alert(data.error);
                    return;
                }
                state.jobId = data.job_id;
                AT.showProgress({ total: state.ids.length, processed: 0, translated: 0, failed: 0 });
            })
            .catch(() => {
                $('atStartBtn').disabled = false;
                $('atStartBtn').innerHTML = '<i class="fa-solid fa-language"></i> Start Translation';
                alert('Connection error. Please try again.');
            });
        },

        showProgress: function(data) {
            hide($('atStep1')); show($('atStep2')); hide($('atStep3'));
            hide($('atStartBtn')); show($('atStopBtn')); hide($('atCloseBtn'));
            hide($('atCancelBtn'));
            $('atStopBtn').disabled = false;

            AT.updateProgress(data);
            AT.startPolling();
        },

        startPolling: function() {
            if (state.pollTimer) clearInterval(state.pollTimer);
            state.pollTimer = setInterval(AT.poll, POLL_MS);
        },

        poll: function() {
            var url = '/admin/' + ENTITY + '/ai-translate-status';
            if (state.jobId) url += '?job_id=' + state.jobId;

            fetch(url, { credentials: 'same-origin' })
            .then(r => r.json())
            .then(data => {
                if (!data.active) {
                    
                    clearInterval(state.pollTimer);
                    state.pollTimer = null;
                    AT.updateProgress(data);
                    AT.finish(data);
                    return;
                }
                AT.updateProgress(data);
            })
            .catch(() => {}); 
        },

        updateProgress: function(data) {
            var total = data.total || 1;
            var processed = data.processed || 0;
            var pct = Math.min(100, Math.round((processed / total) * 100));

            $('atDoneCount').textContent = data.translated || 0;
            $('atFailCount').textContent = data.failed || 0;
            $('atProgressBar').style.width = pct + '%';
            $('atProgressPct').textContent = pct + '%';
            $('atProgressLabel').textContent = 'Translating ' + processed + ' / ' + total + '...';
            $('atCurrentName').textContent = processed < total ? 'Processing in background...' : 'Finishing...';

            if (data.error) {
                show($('atErrorLog'));
                $('atErrorLog').innerHTML = '<div class="px-2 py-1 bg-red-50 rounded text-[11px] text-red-700"><i class="fa-solid fa-xmark mr-1"></i>' + AT.esc(data.error) + '</div>';
            }
        },

        finish: function(data) {
            hide($('atStep2')); show($('atStep3'));
            hide($('atStopBtn')); show($('atCloseBtn'));
            show($('atCancelBtn'));

            var parts = [];
            if ((data.translated || 0) > 0) parts.push((data.translated || 0) + ' translated');
            if ((data.failed || 0) > 0) parts.push((data.failed || 0) + ' failed');
            if (data.status === 'cancelled') {
                parts.push('cancelled');
                if (state._refunded > 0) parts.push(state._refunded.toFixed(2) + ' Cr refunded');
            }
            $('atCompleteSummary').textContent = parts.join(', ') || 'Job finished.';

            fetch('/admin/catalogue/balance', { credentials: 'same-origin' })
            .then(r => r.json())
            .then(function(d) {
                if (d && typeof d.credits !== 'undefined') $('atFinalBalance').textContent = parseFloat(d.credits).toFixed(2);
            }).catch(function() {});
        },

        stop: function() {
            $('atStopBtn').disabled = true;
            $('atStopBtn').innerHTML = '<i class="fa-solid fa-spinner fa-spin"></i> Stopping...';
            $('atProgressLabel').textContent = 'Cancelling...';

            fetch('/admin/' + ENTITY + '/ai-translate-cancel', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': CSRF },
                body: JSON.stringify({ job_id: state.jobId }),
                credentials: 'same-origin'
            }).then(function(r) {
                
                if (r.redirected || r.status === 403 || r.status === 401) {
                    $('atStopBtn').disabled = false;
                    $('atStopBtn').innerHTML = '<i class="fa-solid fa-stop"></i> Stop';
                    if (confirm('Your session has expired. Log in again to stop the translation.\n\nThe translation will continue in the background.')) {
                        window.location.href = '/admin/';
                    }
                    return;
                }
                return r.json();
            }).then(function(data) {
                if (!data) return;
                if (data.error) {
                    $('atStopBtn').disabled = false;
                    $('atStopBtn').innerHTML = '<i class="fa-solid fa-stop"></i> Stop';
                    alert(data.error);
                    return;
                }
                if (data.refunded > 0) {
                    state._refunded = data.refunded;
                }
            }).catch(function() {
                $('atStopBtn').disabled = false;
                $('atStopBtn').innerHTML = '<i class="fa-solid fa-stop"></i> Stop';
            });
        },

        close: function() {
            if (state.pollTimer) clearInterval(state.pollTimer);
            hide($('atOverlay')); hide($('atModal'));
        },

        closeAndReload: function() {
            if (state.pollTimer) clearInterval(state.pollTimer);
            hide($('atOverlay')); hide($('atModal'));
            location.reload();
        },

        connect: function() {
            if (typeof MP !== 'undefined' && MP.autoConnect) {
                
                window.AT_CONNECTING = true;
                MP.autoConnect();
                
                window.addEventListener('message', async function _atConnH(e) {
                    if (!e.data || e.data.type !== 'tubepress-connect') return;
                    window.removeEventListener('message', _atConnH);
                    
                    try {
                        await fetch('/admin/catalogue/save-config', {
                            method: 'POST',
                            headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': CSRF },
                            body: JSON.stringify({
                                catalogue_api_key: e.data.api_key,
                                catalogue_api_secret: e.data.api_secret,
                                catalogue_api_url: 'https://tubepress.io/v1',
                            })
                        });
                    } catch(err) {}
                    window.AT_CONNECTING = false;
                    
                    show($('atLoading')); hide($('atSummary'));
                    AT.loadInit(state._allMode ? 'all' : 'selected', state._allMode ? [] : (state._originalIds || state.ids), $('atSkipTranslated').checked);
                });
            } else {
                window.open('/admin/import', '_blank');
            }
        },

        openTopUp: function() {
            if (typeof MP !== 'undefined' && MP.openTopUpModal) {
                
                hide($('atOverlay'));
                hide($('atModal'));
                MP.openTopUpModal();
                
                var _checkInterval = setInterval(function() {
                    var modal = document.getElementById('mpTopUpModal');
                    if (modal && modal.classList.contains('hidden')) {
                        clearInterval(_checkInterval);
                        show($('atOverlay'));
                        show($('atModal'));
                        
                        show($('atLoading')); hide($('atSummary'));
                        AT.loadInit(state._allMode ? 'all' : 'selected', state._allMode ? [] : (state._originalIds || state.ids), $('atSkipTranslated').checked);
                    }
                }, 500);
            } else {
                window.open('/admin/import', '_blank');
            }
        },

        esc: function(s) { var d = document.createElement('div'); d.textContent = s || ''; return d.innerHTML; },

        translateAll: function() { AT.open('all', []); },

        setAuto: function(checkbox) {
            var on = !!checkbox.checked;
            fetch('/admin/' + ENTITY + '/ai-translate-auto', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': CSRF },
                body: JSON.stringify({ enabled: on }),
                credentials: 'same-origin'
            }).then(function(r){ return r.json(); }).then(function(d){
                if (!d || !d.success) { checkbox.checked = !on; }
            }).catch(function(){ checkbox.checked = !on; });
        },

        disableAuto: function() {
            fetch('/admin/' + ENTITY + '/ai-translate-auto', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': CSRF },
                body: JSON.stringify({ enabled: false }),
                credentials: 'same-origin'
            }).then(function(){ location.reload(); }).catch(function(){ location.reload(); });
        },

        translateSelected: function() {
            var ids = [];
            document.querySelectorAll('[data-bulk-id]:checked').forEach(function(cb) { ids.push(parseInt(cb.dataset.bulkId)); });
            if (ids.length === 0) { alert('Please select at least one item.'); return; }
            AT.open('selected', ids);
        }
    };
})();
</script>
