window._ap = window._ap || {};

const AP_PROBLEM_TAGS = new Set(['dead', 'blocked', 'frozen', 'spamblock', 'resting', 'error']);
const AP_DEAD_TAGS = new Set(['dead', 'blocked', 'frozen']);

function apHasTag(acc, tag) {
    return (acc.filter_tags || []).includes(tag);
}
function apHasAnyTag(acc, tagSet) {
    const ft = acc.filter_tags || [];
    return ft.some(t => tagSet.has(t));
}
function apStatusBadgeStyle(cat) {
    const m = {
        active: 'background:rgba(245,158,11,.2);color:#f59e0b;',
        spamblock: 'background:rgba(255,152,0,.2);color:#ff9800;',
        blocked: 'background:rgba(255,107,107,.2);color:#ff6b6b;',
        frozen: 'background:rgba(99,179,237,.2);color:#63b3ed;',
        dead: 'background:rgba(255,107,107,.15);color:#ff6b6b;',
        resting: 'background:rgba(156,39,176,.2);color:#ab47bc;',
        error: 'background:rgba(255,152,0,.2);color:#ff9800;',
        offline: 'background:rgba(158,158,158,.2);color:#9e9e9e;',
    };
    return m[cat] || 'background:var(--bg-hover);color:var(--text-secondary);';
}

// Fallback for local standalone use: some extracted UI parts call this helper.
if (typeof window.loadAuthAvatars !== 'function') {
    window.loadAuthAvatars = function(root = document) {
        root.querySelectorAll('img[data-auth-src]').forEach((img) => {
            const src = img.getAttribute('data-auth-src');
            if (!src) return;
            if (img.dataset.authLoaded === '1') return;
            img.dataset.authLoaded = '1';
            img.src = src;
        });
    };
}
class AccountPicker {
            constructor(config) {
                this.container = document.getElementById(config.containerId);
                this.mode = config.mode || 'multi';
                this.maxSelect = config.maxSelect || null;
                this.accentColor = config.accentColor || 'var(--primary)';
                this.showProjectColumn = config.showProjectColumn || false;
                this.perPage = config.perPage || 10;
                this.perPageOptions = config.perPageOptions || [10, 20, 50];
                this.existingIds = config.existingIds || new Set();
                this.existingLabel = config.existingLabel || 'В группе';
                this.customIsDisabled = config.customIsDisabled || null;
                this.customStatusHtml = config.customStatusHtml || null;
                this.onSelectionChange = config.onSelectionChange || (() => {});
                this.excludeIds = config.excludeIds || new Set();
                this.accounts = [];
                this.filtered = [];
                this.projects = [];
                this.selected = this.mode === 'multi' ? new Set() : null;
                this.selectedId = this.mode === 'single' ? null : undefined;
                this.page = 1;
                this.uid = 'ap_' + Math.random().toString(36).substr(2, 6);
                window._ap[this.uid] = this;
                this._buildHtml();
            }

            _buildHtml() {
                const u = this.uid;
                const ac = this.accentColor;
                const multiControls = this.mode === 'multi' ? `
                    <div style="margin-left:auto;display:flex;gap:6px;">
                        <button onclick="window._ap['${u}'].selectAllFiltered()" style="padding:6px 12px;border-radius:6px;border:1px solid ${ac};background:transparent;color:${ac};cursor:pointer;font-size:0.75rem;font-weight:500;">Выбрать все</button>
                        <button onclick="window._ap['${u}'].clearSelection()" style="padding:6px 12px;border-radius:6px;border:1px solid var(--border);background:transparent;color:var(--text-secondary);cursor:pointer;font-size:0.75rem;">Сбросить</button>
                    </div>` : '';
                const selectAllCb = this.mode === 'multi'
                    ? `<input type="checkbox" id="${u}_selall" onchange="window._ap['${u}'].togglePageAll(this)" style="cursor:pointer;width:14px;height:14px;accent-color:${ac};" title="Выбрать на странице">`
                    : '';
                const projCol = this.showProjectColumn
                    ? '<div style="padding:6px 4px;width:80px;font-size:.72rem;color:var(--text-secondary);font-weight:600;">Проект</div>' : '';
                const bottomMulti = this.mode === 'multi' ? `
                    <button onclick="window._ap['${u}'].selectPage()" id="${u}_selbtn" style="padding:4px 10px;border-radius:5px;border:1px solid var(--border);background:var(--bg-card);color:var(--text);cursor:pointer;font-size:0.75rem;">Выбрать ${this.perPage}</button>
                    <button onclick="window._ap['${u}'].selectAllFiltered()" id="${u}_selallbtn" style="padding:4px 10px;border-radius:5px;border:1px solid var(--border);background:var(--bg-card);color:var(--text);cursor:pointer;font-size:0.75rem;">Выбрать все (0)</button>
                    <button onclick="window._ap['${u}'].clearSelection()" style="padding:4px 10px;border-radius:5px;border:1px solid var(--border);background:var(--bg-card);color:var(--text-secondary);cursor:pointer;font-size:0.75rem;">Сбросить</button>
                ` : '';
                const ppOpts = this.perPageOptions.map(n => `<option value="${n}" ${n === this.perPage ? 'selected' : ''}>${n}</option>`).join('');

                this.container.innerHTML = `
                    <div style="display:flex;align-items:center;gap:8px;margin-bottom:8px;flex-wrap:wrap;padding:8px 10px;background:var(--bg-card);border-radius:8px;">
                        <div style="position:relative;min-width:160px;flex:1;max-width:220px;">
                            <input type="text" id="${u}_search" placeholder="🔍 Поиск" oninput="window._ap['${u}'].filter()" style="width:100%;padding:6px 10px;border-radius:6px;border:1px solid var(--border);background:var(--input-bg);color:var(--text);font-size:0.8rem;box-sizing:border-box;">
                            <span id="${u}_count" style="position:absolute;right:8px;top:50%;transform:translateY(-50%);font-size:0.7rem;color:var(--text-secondary);"></span>
                        </div>
                        <select id="${u}_project" onchange="window._ap['${u}'].filter()" style="padding:6px 8px;border-radius:6px;border:1px solid var(--border);background:var(--input-bg);color:var(--text);font-size:0.75rem;min-width:120px;">
                            <option value="">Все проекты</option>
                            <option value="none">Без проекта</option>
                        </select>
                        <select id="${u}_status" onchange="window._ap['${u}'].filter()" style="padding:6px 8px;border-radius:6px;border:1px solid var(--border);background:var(--input-bg);color:var(--text);font-size:0.75rem;min-width:110px;">
                            <option value="">Все статусы</option>
                            <option value="active">✓ Активный</option>
                            <option value="online">● Онлайн</option>
                            <option value="offline">○ Оффлайн</option>
                            <option value="spamblock">🤖 Спамблок</option>
                            <option value="problems">⚠️ Проблемные</option>
                        </select>
                        <select id="${u}_task" onchange="window._ap['${u}'].filter()" style="padding:6px 8px;border-radius:6px;border:1px solid var(--border);background:var(--input-bg);color:var(--text);font-size:0.75rem;min-width:100px;">
                            <option value="">Задачи</option>
                            <option value="free">✓ Свободные</option>
                            <option value="sending">📨 Рассылка</option>
                            <option value="parsing">🔍 Парсинг</option>
                        </select>
                        <button onclick="window._ap['${u}'].resetFilters()" style="padding:6px 10px;border-radius:6px;border:1px solid var(--border);background:var(--bg-hover);color:var(--text-secondary);cursor:pointer;font-size:0.75rem;" title="Сбросить фильтры">✕</button>
                        ${multiControls}
                    </div>
                    <div style="flex:1;overflow:hidden;display:flex;flex-direction:column;min-height:0;">
                        <div style="background:var(--bg-card);border:1px solid var(--border);border-radius:8px;overflow:hidden;display:flex;flex-direction:column;height:100%;">
                            <div style="display:flex;align-items:center;border-bottom:1px solid var(--border);background:var(--bg-hover);flex-shrink:0;">
                                <div style="padding:6px 8px 6px 12px;width:36px;">${selectAllCb}</div>
                                <div style="padding:6px 4px;flex:1;font-size:.72rem;color:var(--text-secondary);font-weight:600;">Аккаунт</div>
                                <div style="padding:6px 4px;min-width:130px;max-width:200px;font-size:.72rem;color:var(--text-secondary);font-weight:600;">Статус</div>
                                ${projCol}
                            </div>
                            <div id="${u}_body" style="flex:1;overflow-y:auto;"></div>
                        </div>
                    </div>
                    <div style="display:flex;justify-content:space-between;align-items:center;padding-top:10px;flex-wrap:wrap;gap:8px;">
                        <div style="display:flex;align-items:center;gap:8px;flex-wrap:wrap;">
                            <span id="${u}_info" style="font-size:0.85rem;font-weight:500;color:var(--text-secondary);">${this.mode === 'multi' ? 'Выбрано: 0' : 'Выберите аккаунт'}</span>
                            ${bottomMulti}
                        </div>
                        <div style="display:flex;align-items:center;gap:6px;">
                            <select id="${u}_perpage" onchange="window._ap['${u}'].changePerPage()" style="padding:4px 8px;border-radius:6px;border:1px solid var(--border);background:var(--input-bg);color:var(--text);font-size:0.75rem;">${ppOpts}</select>
                            <div id="${u}_pages" style="display:flex;align-items:center;gap:3px;"></div>
                        </div>
                    </div>`;
            }

            setAccounts(accounts) {
                this.accounts = accounts;
                this.filtered = [...accounts];
                this.page = 1;
                this._updateSearchCount();
                this.renderTable();
                this.renderPagination();
                this._updateInfo();
            }

            setProjects(projects) {
                this.projects = projects;
                const sel = document.getElementById(this.uid + '_project');
                if (sel) sel.innerHTML = '<option value="">Все проекты</option><option value="none">Без проекта</option>' +
                    projects.map(p => `<option value="${p.id}">${escapeHtml(p.name)}</option>`).join('');
            }

            setSelection(ids) {
                if (this.mode === 'multi') {
                    this.selected = new Set(ids);
                } else {
                    this.selectedId = ids;
                }
                this.renderTable();
                this._updateInfo();
            }

            filter() {
                const search = (document.getElementById(this.uid + '_search')?.value || '').toLowerCase();
                const project = document.getElementById(this.uid + '_project')?.value || '';
                const status = document.getElementById(this.uid + '_status')?.value || '';
                const task = document.getElementById(this.uid + '_task')?.value || '';
                this.filtered = this.accounts.filter(acc => {
                    if (this.excludeIds.has(acc.id)) return false;
                    if (search) {
                        const str = [acc.phone, acc.first_name, acc.last_name, acc.username].filter(Boolean).join(' ').toLowerCase();
                        if (!str.includes(search)) return false;
                    }
                    if (project === 'none' && acc.project_id) return false;
                    if (project && project !== 'none' && acc.project_id != project) return false;
                    // Единые теги с вкладкой «Аккаунты» (filter_tags с API)
                    if (status === 'active' && !apHasTag(acc, 'active')) return false;
                    if (status === 'online' && !apHasTag(acc, 'online')) return false;
                    if (status === 'offline' && !apHasTag(acc, 'offline')) return false;
                    if (status === 'spamblock' && !apHasTag(acc, 'spamblock')) return false;
                    if (status === 'problems' && !apHasAnyTag(acc, AP_PROBLEM_TAGS)) return false;
                    // Task filter — для рассылки актуальны только «Рассылка» и «Парсинг»
                    const inSending = acc.busy_in === 'sending' || acc.busy_in === 'broadcast' || acc.in_broadcast;
                    const inParsing = acc.busy_in === 'parsing' || acc.in_parsing;
                    const hasAnyTask = !!acc.busy_in || inSending || inParsing;
                    if (task === 'free' && hasAnyTask) return false;
                    if (task === 'sending' && !inSending) return false;
                    if (task === 'parsing' && !inParsing) return false;
                    return true;
                });
                this.page = 1;
                // Выбор сохраняется при смене фильтра — можно выбирать из разных проектов
                this._updateSearchCount();
                this.renderTable();
                this.renderPagination();
                this._updateInfo();
            }

            resetFilters() {
                const u = this.uid;
                const s = document.getElementById(u + '_search'); if (s) s.value = '';
                const p = document.getElementById(u + '_project'); if (p) p.value = '';
                const st = document.getElementById(u + '_status'); if (st) st.value = '';
                const t = document.getElementById(u + '_task'); if (t) t.value = '';
                this.filter();
            }

            _isDisabled(acc) {
                if (this.existingIds.has(acc.id)) return true;
                if (acc.broadcast_blocked || acc.resting_active) return true;
                if (acc.resting_until && new Date(acc.resting_until).getTime() > Date.now()) return true;
                if (acc.daily_invite_limit && acc.invites_today >= acc.daily_invite_limit) return true;
                if (!acc.has_session) return true;
                if (apHasAnyTag(acc, AP_DEAD_TAGS)) return true;
                if (acc.busy_in) return true;
                if (this.customIsDisabled) return this.customIsDisabled(acc);
                return false;
            }

            renderTable() {
                const body = document.getElementById(this.uid + '_body');
                if (!body) return;
                const start = (this.page - 1) * this.perPage;
                const pageAccounts = this.filtered.slice(start, start + this.perPage);
                if (!pageAccounts.length) {
                    body.innerHTML = '<div style="padding:30px;text-align:center;color:var(--text-secondary);">Нет аккаунтов</div>';
                    return;
                }
                const _actMap = {
                    warmup:{t:'Прогрев',s:'background:rgba(33,150,243,.15);color:#2196f3;',i:'🔥'},
                    warming:{t:'Прогрев',s:'background:rgba(33,150,243,.15);color:#2196f3;',i:'🔥'},
                    group_warmer:{t:'Группа',s:'background:rgba(255,152,0,.15);color:#ff9800;',i:'🔥'},
                    group_warming:{t:'Группа',s:'background:rgba(255,152,0,.15);color:#ff9800;',i:'🔥'},
                    parsing:{t:'Парсинг',s:'background:rgba(156,39,176,.15);color:#9c27b0;',i:'🔍'},
                    inviting:{t:'Инвайт',s:'background:rgba(0,188,212,.15);color:#00bcd4;',i:'📩'},
                    sending:{t:'Рассылка',s:'background:rgba(233,30,99,.15);color:#e91e63;',i:'📨'},
                    monitoring:{t:'Мониторинг',s:'background:rgba(76,175,80,.15);color:#4caf50;',i:'🔍'},
                };
                const _bStyle = 'display:inline-block;font-size:.55rem;padding:1px 5px;border-radius:3px;margin:1px 2px;white-space:nowrap;';
                const u = this.uid, ac = this.accentColor;
                body.innerHTML = pageAccounts.map(acc => {
                    const isExisting = this.existingIds.has(acc.id);
                    const isResting = acc.resting_until && new Date(acc.resting_until).getTime() > Date.now();
                    const limitExhausted = acc.daily_invite_limit && acc.invites_today >= acc.daily_invite_limit;
                    const isBusy = !!acc.busy_in || !!acc.busy_reason;
                    const uiCat = acc.ui_category || acc.status || '';
                    const isDisabled = this._isDisabled(acc);
                    const isSelected = this.mode === 'multi' ? this.selected.has(acc.id) : this.selectedId === acc.id;
                    const avatarLetter = (acc.first_name || acc.phone || '?')[0].toUpperCase();
                    // avatar_url с бэка уже корневой ('/api/accounts/.../avatar') — НЕ префиксуем
                    // повторно API_URL, иначе получаем '/api/api/...' → 404.
                    const _avRaw = acc.avatar_url || '';
                    const avatarUrl = _avRaw
                        ? (/^(https?:)?\//.test(_avRaw) ? _avRaw : `${API_URL}${_avRaw}`)
                        : (acc.avatar_base64 ? `data:image/jpeg;base64,${acc.avatar_base64}` : null);
                    const isAuthAvatar = avatarUrl && avatarUrl.includes('/accounts/') && avatarUrl.includes('/avatar');
                    const avatar = avatarUrl
                        ? `<img ${isAuthAvatar ? `data-auth-src="${avatarUrl}" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"` : `src="${avatarUrl}"`} style="width:30px;height:30px;border-radius:50%;object-fit:cover;background:var(--bg-hover);${isDisabled ? 'opacity:0.4;' : ''}" loading="lazy" onerror="this.style.display='none';this.nextElementSibling.style.display='flex';"><div style="display:none;width:30px;height:30px;border-radius:50%;background:var(--bg-hover);align-items:center;justify-content:center;font-size:0.75rem;color:var(--text-secondary);">${avatarLetter}</div>`
                        : `<div style="width:30px;height:30px;border-radius:50%;background:${isDisabled ? 'var(--bg-hover)' : ac};display:flex;align-items:center;justify-content:center;color:${isDisabled ? 'var(--text-secondary)' : '#000'};font-weight:bold;font-size:11px;">${avatarLetter}</div>`;
                    // Build badges
                    let badges = '';
                    if (this.customStatusHtml) { badges = this.customStatusHtml(acc); }
                    else {
                        // Статус — единая метка с вкладки «Аккаунты»
                        if (isExisting) {
                            badges += `<span style="${_bStyle}background:rgba(245,158,11,.2);color:#f59e0b;">✓ ${escapeHtml(this.existingLabel)}</span>`;
                        } else {
                            const lbl = acc.status_label || '—';
                            badges += `<span style="${_bStyle}${apStatusBadgeStyle(uiCat)}">${escapeHtml(lbl)}</span>`;
                        }
                        // Activity badges (tasks)
                        if (acc.busy_in) {
                            const act = _actMap[acc.busy_in];
                            if (act) badges += `<span style="${_bStyle}${act.s}">${act.i} ${act.t}</span>`;
                        }
                        // Resting badge
                        if (isResting) {
                            const rd = new Date(acc.resting_until).toLocaleString('ru-RU',{hour:'2-digit',minute:'2-digit'});
                            badges += `<span style="${_bStyle}background:rgba(156,39,176,.2);color:#ab47bc;">😴 до ${rd}</span>`;
                        }
                        // Limit exhausted badge
                        if (limitExhausted) {
                            badges += `<span style="${_bStyle}background:rgba(255,107,107,.2);color:#ff6b6b;">🚫 Лимит</span>`;
                        }
                    }
                    const selectedBg = isSelected ? `background:rgba(245,158,11,0.1);${this.mode === 'single' ? 'border-left:3px solid ' + ac + ';' : ''}` : '';
                    const clickFn = isDisabled ? '' : `window._ap['${u}'].toggleSelect(${acc.id})`;
                    const inputHtml = this.mode === 'multi'
                        ? `<input type="checkbox" ${isSelected ? 'checked' : ''} ${isDisabled ? 'disabled' : ''} onclick="event.stopPropagation();window._ap['${u}'].toggleSelect(${acc.id})" style="cursor:${isDisabled ? 'not-allowed' : 'pointer'};width:14px;height:14px;accent-color:${ac};">`
                        : `<input type="radio" name="${u}_radio" value="${acc.id}" ${isSelected ? 'checked' : ''} ${isDisabled ? 'disabled' : ''} style="cursor:${isDisabled ? 'not-allowed' : 'pointer'};width:14px;height:14px;accent-color:${ac};">`;
                    const projCol = this.showProjectColumn ? `<div style="padding:0 8px;width:80px;font-size:0.68rem;color:var(--text-secondary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;">${escapeHtml(acc.project_name || '—')}</div>` : '';
                    const _busyLabels = {warming:'В прогреве',inviting:'В инвайтинге',parsing:'В парсинге',group_warming:'В прогреве группы',monitoring:'В мониторинге',warmup:'В прогреве',group_warmer:'В прогреве группы',broadcast:'В рассылке',sending:'В рассылке'};
                    let dTitle = '';
                    if (isExisting) dTitle = this.existingLabel;
                    else if (acc.busy_in && _busyLabels[acc.busy_in]) dTitle = _busyLabels[acc.busy_in];
                    else if (acc.status && _busyLabels[acc.status]) dTitle = _busyLabels[acc.status];
                    else if (isResting) dTitle = 'На отлёжке';
                    else if (limitExhausted) dTitle = 'Лимит исчерпан';
                    return `<div style="display:flex;align-items:center;border-bottom:1px solid var(--border);padding:6px 0;cursor:${isDisabled ? 'not-allowed' : 'pointer'};${isDisabled ? 'opacity:0.55;' : ''}${selectedBg}" ${clickFn ? `onclick="${clickFn}"` : ''} ${dTitle ? `title="${escapeHtml(dTitle)}"` : ''}>
                        <div style="padding:0 6px 0 12px;width:36px;">${inputHtml}</div>
                        <div style="flex:1;display:flex;align-items:center;gap:8px;padding:0 4px;min-width:0;">
                            ${avatar}
                            <div style="min-width:0;">
                                <div style="font-weight:500;font-size:0.82rem;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;">${escapeHtml(acc.first_name || '')} ${escapeHtml(acc.last_name || '')}</div>
                                <div style="font-size:0.72rem;color:var(--text-secondary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;">${acc.username ? '@' + escapeHtml(acc.username) + ' • ' : ''}${escapeHtml(acc.phone)}</div>
                            </div>
                        </div>
                        <div style="min-width:130px;max-width:200px;padding:0 4px;display:flex;flex-wrap:wrap;align-items:center;">${badges}</div>
                        ${projCol}
                    </div>`;
                }).join('');
                if (this.mode === 'multi') {
                    const cb = document.getElementById(u + '_selall');
                    if (cb) {
                        const freeOnPage = pageAccounts.filter(a => !this._isDisabled(a));
                        cb.checked = freeOnPage.length > 0 && freeOnPage.every(a => this.selected.has(a.id));
                    }
                }
                // Загружаем аватарки с авторизацией
                loadAuthAvatars();
            }

            toggleSelect(id) {
                const acc = this.accounts.find(a => a.id === id);
                if (acc && this._isDisabled(acc)) return;
                if (this.mode === 'single') {
                    this.selectedId = this.selectedId === id ? null : id;
                } else {
                    if (this.selected.has(id)) { this.selected.delete(id); }
                    else {
                        if (this.maxSelect && this.selected.size >= this.maxSelect) return;
                        this.selected.add(id);
                    }
                }
                this.renderTable();
                this._updateInfo();
                this._notifyChange();
            }

            togglePageAll(checkbox) {
                const start = (this.page - 1) * this.perPage;
                this.filtered.slice(start, start + this.perPage).forEach(acc => {
                    if (this._isDisabled(acc)) return;
                    if (checkbox.checked) {
                        if (!this.maxSelect || this.selected.size < this.maxSelect) this.selected.add(acc.id);
                    } else { this.selected.delete(acc.id); }
                });
                this.renderTable();
                this._updateInfo();
                this._notifyChange();
            }

            selectPage() {
                const start = (this.page - 1) * this.perPage;
                this.filtered.slice(start, start + this.perPage).forEach(acc => {
                    if (!this._isDisabled(acc) && (!this.maxSelect || this.selected.size < this.maxSelect))
                        this.selected.add(acc.id);
                });
                this.renderTable(); this._updateInfo(); this._notifyChange();
            }

            selectAllFiltered() {
                this.filtered.forEach(acc => {
                    if (!this._isDisabled(acc) && (!this.maxSelect || this.selected.size < this.maxSelect))
                        this.selected.add(acc.id);
                });
                this.renderTable(); this._updateInfo(); this._notifyChange();
            }

            clearSelection() {
                if (this.mode === 'multi') this.selected.clear();
                else this.selectedId = null;
                this.renderTable(); this._updateInfo(); this._notifyChange();
            }

            getSelected() { return this.mode === 'multi' ? new Set(this.selected) : this.selectedId; }
            getSelectedCount() { return this.mode === 'multi' ? this.selected.size : (this.selectedId ? 1 : 0); }

            changePerPage() {
                this.perPage = parseInt(document.getElementById(this.uid + '_perpage').value);
                this.page = 1;
                this.renderTable(); this.renderPagination(); this._updateInfo();
            }

            goToPage(page) {
                const tp = Math.ceil(this.filtered.length / this.perPage) || 1;
                if (page < 1 || page > tp) return;
                this.page = page;
                this.renderTable(); this.renderPagination();
            }

            renderPagination() {
                const c = document.getElementById(this.uid + '_pages');
                if (!c) return;
                const tp = Math.ceil(this.filtered.length / this.perPage) || 1;
                if (tp <= 1) { c.innerHTML = ''; return; }
                const u = this.uid, ac = this.accentColor;
                let h = '';
                if (this.page > 1) h += `<button onclick="window._ap['${u}'].goToPage(${this.page-1})" style="padding:4px 8px;border:1px solid var(--border);background:var(--bg-card);color:var(--text);border-radius:4px;cursor:pointer;font-size:0.8rem;">&lt;</button>`;
                const mx = 5; let sp = Math.max(1, this.page - Math.floor(mx/2)); let ep = Math.min(tp, sp+mx-1);
                if (ep-sp < mx-1) sp = Math.max(1, ep-mx+1);
                for (let i = sp; i <= ep; i++) {
                    const a = i === this.page;
                    h += `<button onclick="window._ap['${u}'].goToPage(${i})" style="padding:4px 10px;border:1px solid ${a?ac:'var(--border)'};background:${a?ac:'var(--bg-card)'};color:${a?'#000':'var(--text)'};border-radius:4px;cursor:pointer;font-size:0.8rem;font-weight:${a?'600':'400'};">${i}</button>`;
                }
                if (ep < tp) { h += `<span style="color:var(--text-secondary);font-size:0.8rem;">...</span>`; h += `<button onclick="window._ap['${u}'].goToPage(${tp})" style="padding:4px 10px;border:1px solid var(--border);background:var(--bg-card);color:var(--text);border-radius:4px;cursor:pointer;font-size:0.8rem;">${tp}</button>`; }
                if (this.page < tp) h += `<button onclick="window._ap['${u}'].goToPage(${this.page+1})" style="padding:4px 8px;border:1px solid var(--border);background:var(--bg-card);color:var(--text);border-radius:4px;cursor:pointer;font-size:0.8rem;">&gt;</button>`;
                c.innerHTML = h;
            }

            _updateSearchCount() {
                const el = document.getElementById(this.uid + '_count');
                if (el) el.textContent = this.filtered.length;
            }

            _updateInfo() {
                const info = document.getElementById(this.uid + '_info');
                if (!info) return;
                if (this.mode === 'multi') {
                    const cnt = this.selected.size;
                    const freeTotal = this.filtered.filter(a => !this._isDisabled(a)).length;
                    info.innerHTML = `Выбрано: <b style="color:${this.accentColor};">${cnt}</b>`;
                    const sb = document.getElementById(this.uid + '_selbtn');
                    if (sb) sb.textContent = `Выбрать ${this.perPage}`;
                    const sa = document.getElementById(this.uid + '_selallbtn');
                    if (sa) sa.textContent = cnt === freeTotal && freeTotal > 0 ? `Все выбраны (${freeTotal})` : `Выбрать все (${freeTotal})`;
                } else {
                    if (this.selectedId) {
                        const acc = this.accounts.find(a => a.id === this.selectedId);
                        const label = acc ? (acc.username ? `@${acc.username}` : acc.phone) : '';
                        info.innerHTML = `<span style="color:${this.accentColor};">Выбран: ${escapeHtml(label)}</span>`;
                    } else { info.textContent = 'Выберите аккаунт'; }
                }
            }

            _notifyChange() {
                if (this.mode === 'multi') this.onSelectionChange(this.selected, this.selected.size);
                else this.onSelectionChange(this.selectedId, this.selectedId ? 1 : 0);
            }

            destroy() {
                delete window._ap[this.uid];
                if (this.container) this.container.innerHTML = '';
            }
        }