/**
 * BaseView.js
 * کلاس پایه برای تمامی ویوها در معماری جدید.
 * مدیریت lifecycle، header، refs و event cleanup
 */

import acl from "./AclService.js";

export default class BaseView {

    constructor({ eventBus, store, tab } = {}) {

        this.eventBus = eventBus || null;
        this.store = store || null;
        this.tab = tab || null;

        this.container = null;
        this.el = null;
        this.$el = null; // برای ویوهایی که jQuery استفاده می‌کنند

        this.boundEvents = [];
        this.busEvents = [];

        this.refs = {};
        this.isDestroyed = false;
        this._eventsBound = false;
    }

    /* -------------------------------------------------------
       LIFECYCLE
    ------------------------------------------------------- */

    async render(container) {

        if (!container) {
            console.error(`[BaseView] Render failed: container undefined (${this.constructor.name})`);
            return this;
        }

        this.container = container;
        this.el = container;

        if (typeof window.jQuery !== "undefined") {
            this.$el = window.jQuery(container);
        }

        // hook
        if (typeof this.beforeRender === "function") {
            await this.beforeRender();
        }

        const bodyContentHtml = await this.template();

        const finalLayout = `
            ${this._renderModuleHeader()}
            <div class="view-body" data-ref="body">
                ${bodyContentHtml || ""}
            </div>
        `;

        this.container.innerHTML = finalLayout;

        this._bindRefs();
        this._bindModuleHeaderEvents();

        if (typeof this.afterRender === "function") {
            await this.afterRender();
        }

        if (!this._eventsBound && typeof this.bindEvents === "function") {
            this.bindEvents();
            this._eventsBound = true;
        }

        // اعمال ACL خودکار روی DOM
        try { this.applyAclToDom(); } catch (e) { /* ignore */ }

        return this;
    }


    /**
     * برای سازگاری با ویوهای قدیمی که mount دارند
     */
    async mount(container) {
        return this.render(container);
    }

    /**
     * template پیشفرض
     */
    async template() {
        return `<div>در حال واکشی اطلاعات</div>`;
    }

    /* -------------------------------------------------------
       MODULE HEADER — هدر خودکار داخل محتوای هر ویو
       شامل: عنوان | نام کاربر + سطح دسترسی | ⟳ رفرش + × بستن
    ------------------------------------------------------- */

    _renderModuleHeader() {
        const title   = this.constructor.title || this.tab?.title || '';
        const isFixed = this.tab?.fixed ?? false;

        // اطلاعات کاربر
        const userContext = this.tab?.userContext ?? null;
        const authUser    = this.store?.get?.('auth')?.user ?? null;

        let userName = '';
        if (userContext) {
            userName = userContext.display_name || userContext.fullname || userContext.username || '';
        } else if (authUser) {
            userName = authUser.display_name || authUser.username || '';
        }

        // نقش
        let roleBadge = '';
        try {
            if (acl?.roles?.length) {
                const r = acl.roles[0];
                const colors = {
                    super_admin:'#dc2626', manager:'#7c3aed', accountant:'#0891b2',
                    warehouse_keeper:'#ea580c', sales_user:'#16a34a', purchase_user:'#0d9488',
                    gis_user:'#2563eb', project_manager:'#c026d3', viewer:'#64748b'
                };
                const c = colors[r.slug] || '#475569';
                roleBadge = `<span class="bv-hdr__role" style="background:${c}22;color:${c};border:1px solid ${c}44;">${this.escape(r.name)}</span>`;
            }
        } catch { /* ignore */ }

        return `
        <div class="bv-hdr">
            <span class="bv-hdr__title">${this.escape(title)}</span>
            <div class="bv-hdr__user">
                ${userName ? `<span class="bv-hdr__uname">👤 ${this.escape(userName)}</span>` : ''}
                ${roleBadge}
            </div>
            <div class="bv-hdr__actions">
                <button class="bv-hdr__btn bv-hdr__btn--refresh" data-ref="bvRefresh" title="بارگذاری مجدد">⟳</button>
                ${!isFixed ? `<button class="bv-hdr__btn bv-hdr__btn--close" data-ref="bvClose" title="بستن تب">×</button>` : ''}
            </div>
        </div>`;
    }

    _bindModuleHeaderEvents() {
        const btnRefresh = this.ref('bvRefresh');
        const btnClose   = this.ref('bvClose');

        if (btnRefresh && this.eventBus) {
            this.on(btnRefresh, 'click', () => {
                this.eventBus.emit('tabs:refreshActive');
            });
        }

        if (btnClose && this.eventBus && this.tab?.id) {
            this.on(btnClose, 'click', () => {
                this.eventBus.emit('tabs:closeById', this.tab.id);
            });
        }
    }

    /* -------------------------------------------------------
       HEADER
    ------------------------------------------------------- */

    /* -------------------------------------------------------
       TABBAR RIGHT SLOT — عنوان + یوزر + نقش در یک خط
    ------------------------------------------------------- */

    _updateTabbarRight() {
        const slot = document.getElementById('acc-tabbar-right');
        if (!slot) return;

        const title = this.constructor.title || '';

        const userContext = this.tab?.userContext ?? null;
        const authUser    = this.store?.get?.('auth')?.user ?? null;

        let userName = 'system';
        let userId   = null;

        if (userContext) {
            if (typeof userContext === 'string') {
                userName = userContext;
            } else {
                userName = userContext.display_name || userContext.fullname || userContext.username || 'system';
                userId   = userContext.id || null;
            }
        } else if (authUser) {
            userName = authUser.display_name || authUser.username || 'system';
            userId   = authUser.id || null;
        }

        // نقش اول (اگر موجود)
        let roleBadge = '';
        try {
            if (acl?.roles?.length) {
                const r = acl.roles[0];
                const colors = { super_admin:'#dc2626', manager:'#7c3aed', accountant:'#0891b2',
                    warehouse_keeper:'#ea580c', sales_user:'#16a34a', purchase_user:'#0d9488',
                    gis_user:'#2563eb', project_manager:'#c026d3', viewer:'#64748b' };
                const c = colors[r.slug] || '#475569';
                roleBadge = `<span class="tbr-role" style="background:${c}22;color:${c};border:1px solid ${c}55;">${this.escape(r.name)}</span>`;
            }
        } catch { /* ignore */ }

        slot.innerHTML = `
            ${title ? `<span class="tbr-title">${this.escape(title)}</span>` : ''}
            <span class="tbr-user">👤 ${this.escape(userName)}${userId ? ` <small>(#${userId})</small>` : ''}</span>
            ${roleBadge}
            <button class="tbr-switch" data-ref="switchUserBtn" title="تغییر کاربر">⚙</button>
        `;

        // bind کردن دکمه switch
        const btn = slot.querySelector('.tbr-switch');
        if (btn && this.eventBus) {
            btn.addEventListener('click', () => {
                this.eventBus.emit('view:switchUser', { view: this, user: this.tab?.userContext || null });
            });
        }
    }

    _renderRoleBadges() {
        try {
            if (!acl?.roles?.length) return '';
            const colors = {
                super_admin:      '#dc2626',
                manager:          '#7c3aed',
                accountant:       '#0891b2',
                warehouse_keeper: '#ea580c',
                sales_user:       '#16a34a',
                purchase_user:    '#0d9488',
                gis_user:         '#2563eb',
                project_manager:  '#c026d3',
                viewer:           '#64748b',
            };
            const badges = acl.roles.map(r => {
                const color = colors[r.slug] || '#475569';
                const scope = r.scope_type === 'global'
                    ? ''
                    : `<small style="opacity:.7;margin-right:3px;">[${r.scope_type}${r.scope_id ? ':'+r.scope_id : ''}]</small>`;
                return `<span class="view-role-badge" style="background:${color}1a;color:${color};border:1px solid ${color}55;padding:2px 8px;border-radius:10px;font-size:11px;font-weight:700;margin-right:4px;" title="نقش: ${this.escape(r.name)} | scope: ${r.scope_type}">
                    🛡️ ${this.escape(r.name)}${scope}
                </span>`;
            }).join('');
            return `<span class="view-roles" style="display:inline-flex;flex-wrap:wrap;gap:2px;margin-right:8px;">${badges}</span>`;
        } catch { return ''; }
    }

    _renderHeader() {
        const title = this.constructor.title || "Untitled";

        const userContext = this.tab?.userContext ?? null;
        const authUser    = this.store?.get?.("auth")?.user ?? null;

        let userName = "system";
        let userId   = null;

        if (userContext) {
            if (typeof userContext === "string") {
                userName = userContext;
            } else if (typeof userContext === "object") {
                userName =
                    userContext.display_name ||
                    userContext.fullname     ||
                    userContext.username     ||
                    "system";
                userId = userContext.id || null;
            }
        } else if (authUser) {
            userName = authUser.display_name || authUser.username || "system";
            userId   = authUser.id || null;
        }

        const contextProject = this.store?.get("context.project") ?? null;
        const contextBadge   = contextProject
            ? `<span class="view-context-badge" data-ref="contextBadge" title="پروژه فعال فیلتر">
                   <span class="view-context-badge__label">📁 ${this.escape(contextProject.title || contextProject.name || '#' + contextProject.id)}</span>
                   <button class="view-context-badge__clear" data-action="clear-context" aria-label="حذف فیلتر پروژه">✕</button>
               </span>`
            : `<span class="view-context-badge view-context-badge--empty" data-ref="contextBadge"></span>`;

        return `
        <div class="view-header">

            <h2 class="view-title">${title}</h2>

            ${this.useContextBadge ? contextBadge : ""}

            <div class="view-user-context">

                <span class="user-name">
                    👤 ${userName}
                    ${userId ? `<small class="user-id">(#${userId})</small>` : ""}
                </span>

                ${this._renderRoleBadges()}

                <button
                    class="switch-user-btn"
                    data-ref="switchUserBtn"
                    type="button"
                    title="تغییر کاربر"
                    aria-label="تغییر کاربر"
                >
                    <i class="fa-solid fa-user-gear" aria-hidden="true"></i>
                </button>

            </div>

        </div>`;
    }

    /* -------------------------------------------------------
       REFS
    ------------------------------------------------------- */

    _bindRefs() {

        if (!this.container) return;

        this.refs = {};

        const elements = this.container.querySelectorAll("[data-ref]");

        elements.forEach(el => {

            const name = el.dataset.ref;

            if (!name) return;

            this.refs[name] = el;

        });

    }

    ref(name) {
        return this.refs[name] || null;
    }

    /* -------------------------------------------------------
       EVENTS
    ------------------------------------------------------- */

    on(element, event, handler) {

        if (!element || !event || !handler) return;

        element.addEventListener(event, handler);

        this.boundEvents.push({
            element,
            event,
            handler
        });

    }

    listen(event, handler) {

        if (!this.eventBus) return;

        const off = this.eventBus.on(event, handler);

        if (off) {
            this.busEvents.push(off);
        }

    }

    bindEvents() {

        const btn = this.ref("switchUserBtn");

        if (btn && this.eventBus) {
            this.on(btn, "click", () => {
                this.eventBus.emit("view:switchUser", {
                    view: this,
                    user: this.tab?.userContext || null,
                });
            });
        }

        // دکمه حذف context پروژه
        if (this.useContextBadge && this.container) {
            const clearBtn = this.container.querySelector("[data-action='clear-context']");
            if (clearBtn) {
                this.on(clearBtn, "click", (e) => {
                    e.stopPropagation();
                    this.store?.set("context.project", null);
                });
            }
        }

        // واکنش به تغییر context.project برای re-render badge
        if (this.useContextBadge && this.store) {
            this.listen("store:changed:context.project", () => {
                this._refreshContextBadge();
            });
        }
    }

    _refreshContextBadge() {
        if (!this.container) return;
        const slot = this.container.querySelector("[data-ref='contextBadge']");
        if (!slot) return;

        const project = this.store?.get("context.project") ?? null;
        if (project) {
            slot.className = "view-context-badge";
            slot.innerHTML = `
                <span class="view-context-badge__label">📁 ${this.escape(project.title || project.name || "#" + project.id)}</span>
                <button class="view-context-badge__clear" data-action="clear-context" aria-label="حذف فیلتر پروژه">✕</button>`;

            const clearBtn = slot.querySelector("[data-action='clear-context']");
            if (clearBtn) {
                this.on(clearBtn, "click", (e) => {
                    e.stopPropagation();
                    this.store.set("context.project", null);
                });
            }
        } else {
            slot.className = "view-context-badge view-context-badge--empty";
            slot.innerHTML = "";
        }
    }

    /* -------------------------------------------------------
       DESTROY
    ------------------------------------------------------- */

    destroy() {

        if (this.isDestroyed) return;

        this.boundEvents.forEach(e => {

            try {
                e.element.removeEventListener(e.event, e.handler);
            } catch (err) { }

        });

        this.busEvents.forEach(off => {

            try {
                if (typeof off === "function") off();
            } catch (err) { }

        });

        this.boundEvents = [];
        this.busEvents = [];
        this.refs = {};

        this.container = null;
        this.el = null;
        this.$el = null;

        this._eventsBound = false;
        this.isDestroyed = true;
    }

    /* -------------------------------------------------------
       HELPERS
    ------------------------------------------------------- */

    api() {
        return this.tab?.api || null;
    }

    /* ── ACL helpers ─────────────────────────────────────── */

    /** بررسی مجوز کاربر فعلی */
    can(permissionKey, scopeType = null, scopeId = null) {
        return acl.can(permissionKey, scopeType, scopeId);
    }

    cannot(permissionKey, scopeType = null, scopeId = null) {
        return !acl.can(permissionKey, scopeType, scopeId);
    }

    /**
     * فیلتر/مخفی کردن المان‌های HTML با data-perm
     * بعد از render فراخوانی شود:
     *   this.applyAclToDom();
     *
     * در HTML:
     *   <button data-perm="gis.parcels.edit">ویرایش</button>
     *   <div   data-perm="inv.vouchers.confirm" data-perm-mode="disable">تأیید</div>
     */
    applyAclToDom(root = null) {
        const scope = root || this.container;
        if (!scope) return;

        scope.querySelectorAll('[data-perm]').forEach(el => {
            const key = el.dataset.perm;
            if (!key) return;
            if (acl.can(key)) return;

            const mode = el.dataset.permMode || 'hide';
            if (mode === 'disable') {
                el.setAttribute('disabled', 'disabled');
                el.style.opacity = '0.5';
                el.style.cursor  = 'not-allowed';
                el.title = '🚫 دسترسی ندارید';
            } else {
                el.style.display = 'none';
            }
        });
    }

    getCache(key) {
        return this.tab?.cache?.get?.(key);
    }

    setCache(key, value) {
        this.tab?.cache?.set?.(key, value);
    }

    /**
     * پروژه‌ای که در Store به عنوان context فعال است.
     * هر ویوی فرزند می‌تواند بلافاصله پس از render این را بخواند.
     */
    getContextProject() {
        return this.store?.get("context.project") ?? null;
    }

    /**
     * listener آماده برای واکنش به تغییر context.project.
     * در afterRender() صدا بزنید و callback را بدهید.
     */
    onContextProjectChange(callback) {
        this.listen("store:changed:context.project", callback);
    }

    escape(str) {
        if (str == null) return '';
        return String(str)
            .replace(/&/g, "&amp;")
            .replace(/</g, "&lt;")
            .replace(/>/g, "&gt;")
            .replace(/"/g, "&quot;")
            .replace(/'/g, "&#039;");
    }


}
