import BaseView from "/wp-content/plugins/acc-engine/assets/js/core/BaseView.js";
import { viewRegistry } from "/wp-content/plugins/acc-engine/assets/js/core/registries.js";

class PermissionManagerView extends BaseView {

    static title = "مدیریت دسترسی کاربران";

    constructor(options = {}) {
        super(options);

        this.api = options.api;

        this.state = {
            users: [],
            filteredUsers: [],
            selectedUser: null,
            permissions: [],
            loadingUsers: false,
            loadingPermissions: false,
            saving: false,
            searchQuery: "",
            expandedModules: {},
            userCache: null,
            permissionCache: {},
            saveQueue: {},
            saveTimers: {},

            roles: [],
            loadingRoles: false,
            selectedRole: null,

            userFilter: null   // 👈 جدید


        };
    }

    template() {
        return `

    
    <div class="acc-permission-manager">

    <div class="acc-pm-header">
        <div class="acc-pm-title">
            <h2>مدیریت دسترسی کاربران</h2>
            <p>انتخاب کاربر، مشاهده سطح دسترسی و ویرایش permission ها با ساختار ماژولار</p>
        </div>

        <div class="acc-pm-toolbar">
            <button class="acc-btn" data-ref="expandAllBtn" type="button">باز کردن همه</button>
            <button class="acc-btn" data-ref="collapseAllBtn" type="button">بستن همه</button>
            <button class="acc-btn" data-ref="refreshBtn" type="button">بروزرسانی</button>
        </div>
    </div>

    <div class="acc-layout">
        <div class="acc-sidebar">

            <div class="acc-user-search">
                <input
                    type="text"
                    placeholder="جستجوی کاربر..."
                    data-ref="searchInput"
                />
            </div>

            <div class="acc-user-list" data-ref="userList"></div>
        </div>

        <div class="acc-main">
            <div data-ref="permissionArea"></div>
        </div>
    </div>

</div>
`;
    }

    async afterRender() {
        this.$search = this.ref("searchInput");
        this.$list = this.ref("userList");
        this.$area = this.ref("permissionArea");
        this.$expandAllBtn = this.ref("expandAllBtn");
        this.$collapseAllBtn = this.ref("collapseAllBtn");
        this.$refreshBtn = this.ref("refreshBtn");

        this.searchTimer = null;

        this.on(this.$search, "input", () => {
            clearTimeout(this.searchTimer);

            this.searchTimer = setTimeout(() => {
                this.state.searchQuery = this.$search.value.trim().toLowerCase();
                this.filterUsers();
            }, 180);
        });

        this.on(this.$expandAllBtn, "click", () => {
            this.expandAllModules();
        });

        this.on(this.$collapseAllBtn, "click", () => {
            this.collapseAllModules();
        });

        this.on(this.$refreshBtn, "click", () => {
            if (this.state.selectedUser?.id) {
                this.loadPermissions(this.state.selectedUser.id, { force: true });
            } else {
                this.loadUsers({ force: true });
            }
        });

        //        await this.loadUsers();
        await this.loadRoles();

    }


    async loadRoles() {
        this.state.loadingRoles = true;
        this.$list.innerHTML = `<div class="acc-loading">در حال بارگذاری نقش‌ها...</div>`;

        try {
            const res = await this.api.get("/users/roles");
            this.state.roles = Array.isArray(res?.data) ? res.data : [];
            this.renderRoles();
        } catch (e) {
            console.error(e);
            this.$list.innerHTML = `<div class="acc-error">خطا در دریافت نقش‌ها</div>`;
        } finally {
            this.state.loadingRoles = false;
        }
    }

        // SELECT
        // SUBSTRING_INDEX(
        //     SUBSTRING_INDEX(um.meta_value, '"', 2),
        //     '"',
        //     -1
        // ) AS role,
        // COUNT(*) AS total_users
        //     FROM wp_users u
        //     JOIN wp_usermeta um ON um.user_id = u.ID
        //     WHERE um.meta_key = 'wp_capabilities'
        //     GROUP BY role
        //     ORDER BY total_users DESC



    renderRoles() {
        if (!this.state.roles.length) {
            this.$list.innerHTML = `<div class="acc-empty">نقشی یافت نشد</div>`;
            return;
        }

        this.$list.innerHTML = this.state.roles.map(r => {
            const active = this.state.selectedRole === r.role ? "active" : "";

            return `
                <div class="acc-user-item ${active}" data-role="${r.role}">
                    <div class="acc-user-name">${this.escape(r.role)}</div>
                    <div class="acc-user-meta">${r.total_users} کاربر</div>
                </div>
                `;
        }).join("");

        this.$list.querySelectorAll("[data-role]").forEach(el => {
            this.on(el, "click", () => {
                this.selectRole(el.dataset.role);
            });
        });
    }


    async selectRole(role) {
        this.state.selectedRole = role;
        this.state.selectedUser = null;
        this.$area.innerHTML = `<div class="acc-empty">یک کاربر را انتخاب کنید</div>`;
        await this.loadUsers({ force: true, role });
    }


    // async loadUsers(options = {}) {
    //     const { force = false, role = null } = options;

    //     this.state.loadingUsers = true;
    //     this.renderUserListLoading();

    //     try {
    //         const params = {};
    //         if (role) params.role = role;

    //         const res = await this.api.get("/users", params);

    //         const users = Array.isArray(res?.data)
    //             ? res.data
    //             : [];

    //         this.state.users = users;
    //         this.state.filteredUsers = users;
    //         this.renderUserList();
    //     } catch (e) {
    //         console.error(e);
    //         this.$list.innerHTML = `<div class="acc-error">خطا در دریافت کاربران</div>`;
    //     } finally {
    //         this.state.loadingUsers = false;
    //     }
    // }


    async loadUsers(options = {}) {
    const { force = false, role = null } = options;

    this.state.loadingUsers = true;
    this.renderUserListLoading();

    try {

        const qs = role ? `?role=${encodeURIComponent(role)}` : "";
        const res = await this.api.get(`/users${qs}`);

        const users = Array.isArray(res?.data) ? res.data : [];

        this.state.users = users;
        this.state.filteredUsers = users;
        this.renderUserList();

    } catch (e) {
        console.error(e);
        this.$list.innerHTML = `<div class="acc-error">خطا در دریافت کاربران</div>`;
    } finally {
        this.state.loadingUsers = false;
    }
    }

    // SELECT COUNT(*) FROM (
    //     SELECT u.ID

    //     FROM wp_users u
    //     INNER JOIN wp_usermeta um_cap
    //         ON um_cap.user_id = u.ID
    //        AND um_cap.meta_key = 'wp_capabilities'

    //     LEFT JOIN wp_erp_user_roles tur
    //         ON tur.user_id = u.ID

    //     LEFT JOIN wp_erp_role_permissions trp
    //         ON trp.role_id = tur.role_id

    //     LEFT JOIN wp_erp_object_permissions topm
    //         ON topm.user_id = u.ID

    //     LEFT JOIN wp_erp_ui_permissions tuip
    //         ON tuip.user_id = u.ID

    //     WHERE um_cap.meta_value LIKE '%"administrator"%'

    //     GROUP BY u.ID

    // ) AS t



    filterUsers() {

        const q = this.state.searchQuery;
        const filter = this.state.userFilter;

        let users = [...this.state.users];

        // search
        if (q) {

            users = users.filter(u => {

                const name = (u.name || "").toLowerCase();
                const username = (u.username || "").toLowerCase();
                const email = (u.email || "").toLowerCase();

                return name.includes(q) || username.includes(q) || email.includes(q);

            });

        }

        // summary filters
        if (filter === "enabled") {

            users = users.filter(u => (u.permission_count || 0) > 0);

        }

        if (filter === "modules") {

            users = users.filter(u => (u.module_count || 0) > 0);

        }

        if (filter === "rows") {

            users = users.filter(u => (u.row_count || 0) > 0);

        }

        this.state.filteredUsers = users;

        this.renderUserList();

    }


    renderUserListLoading() {
        this.$list.innerHTML = `<div class="acc-loading">در حال بارگذاری کاربران...</div>`;
    }

    renderUserList() {

        // دکمه بازگشت به نقش‌ها
        let backBtn = "";
        if (this.state.selectedRole) {
            backBtn = `
                <div class="acc-back-to-roles">
                    <button class="acc-btn acc-btn-sm" data-ref="backToRoles">
                        ← بازگشت به نقش‌ها
                    </button>
                </div>`;
        }

        if (!this.state.filteredUsers.length) {
            this.$list.innerHTML = backBtn + `<div class="acc-empty">کاربری یافت نشد</div>`;

            const backBtnEl = this.$list.querySelector("[data-ref='backToRoles']");
            if (backBtnEl) {
                this.on(backBtnEl, "click", async () => {
                    this.state.selectedRole = null;
                    this.state.selectedUser = null;
                    this.state.users = [];
                    this.state.filteredUsers = [];
                    this.$area.innerHTML = `<div class="acc-empty">یک نقش را انتخاب کنید</div>`;
                    await this.loadRoles();
                });
            }

            return;
        }

        this.$list.innerHTML = backBtn + this.state.filteredUsers.map(u => {
            const active = String(this.state.selectedUser?.id || "") === String(u.id) ? "active" : "";

            return `
                <div class="acc-user-item ${active}" data-user="${u.id}">
                    <div class="acc-user-name">${this.escape(u.name || u.username || `User #${u.id}`)}</div>
                    <div class="acc-user-meta">
                        ${this.escape(u.username || "")}
                        ${(u.email ? ` • ${this.escape(u.email)}` : "")}
                    </div>
                </div>
                `;
        }).join("");

        // رویداد انتخاب کاربر
        this.$list.querySelectorAll("[data-user]").forEach(el => {
            this.on(el, "click", () => {
                const id = el.dataset.user;
                this.selectUser(id);
            });
        });

        // رویداد دکمه بازگشت
        const backBtnEl = this.$list.querySelector("[data-ref='backToRoles']");
        if (backBtnEl) {
            this.on(backBtnEl, "click", async () => {
                this.state.selectedRole = null;
                this.state.selectedUser = null;
                this.state.users = [];
                this.state.filteredUsers = [];
                this.$area.innerHTML = `<div class="acc-empty">یک نقش را انتخاب کنید</div>`;
                await this.loadRoles();
            });
        }
    }


    async selectUser(id) {
        const found = this.state.users.find(u => String(u.id) === String(id)) || null;
        this.state.selectedUser = found;
        this.renderUserList();
        await this.loadPermissions(id);
    }

    async loadPermissions(id, options = {}) {
        const { force = false } = options;

        if (this.state.permissionCache[id] && !force) {
            this.state.permissions = this.clone(this.state.permissionCache[id]);
            this.ensureExpandedState();
            this.renderPermissions();
            return;
        }

        this.state.loadingPermissions = true;
        this.$area.innerHTML = `<div class="acc-loading">در حال بارگذاری دسترسی‌ها...</div>`;

        try {
            const res = await this.api.get(`/access/users/${id}`);

            this.state.selectedUser = res.user || this.state.selectedUser;
            this.state.permissions = res.permissions || [];

            this.state.permissionCache[id] = this.clone(this.state.permissions);

            this.ensureExpandedState();
            this.renderPermissions();
            this.renderUserList();
        } catch (e) {
            console.error(e);
            this.$area.innerHTML = `<div class="acc-error">خطا در دریافت دسترسی‌های کاربر</div>`;
        } finally {
            this.state.loadingPermissions = false;
        }
    }

    ensureExpandedState() {
        const grouped = this.getGroupedPermissions();

        Object.keys(grouped).forEach(module => {
            if (typeof this.state.expandedModules[module] === "undefined") {
                this.state.expandedModules[module] = true;
            }
        });
    }

    getGroupedPermissions() {
        const grouped = {};

        (this.state.permissions || []).forEach(p => {
            const key = p.module || "module";

            if (!grouped[key]) grouped[key] = [];
            grouped[key].push(p);
        });

        return grouped;
    }

    renderPermissions() {
        if (!this.state.selectedUser) {
            this.$area.innerHTML = `<div class="acc-empty">ابتدا یک کاربر را انتخاب کنید</div>`;
            return;
        }

        if (!this.state.permissions.length) {
            this.$area.innerHTML = `
            <div class="acc-selected-user">
                <div>
                    <h3>${this.escape(this.state.selectedUser?.name || this.state.selectedUser?.username || "کاربر")}</h3>
                    <p>هیچ permission ی برای این کاربر ثبت نشده است.</p>
                </div>
            </div>
            <div class="acc-empty">دسترسی ثبت نشده</div>
            `;
            return;
        }

        const grouped = this.getGroupedPermissions();
        const summary = this.getPermissionSummary();

        this.$area.innerHTML = `
            <div class="acc-selected-user">
                <div>
                    <h3>${this.escape(this.state.selectedUser?.name || this.state.selectedUser?.username || "کاربر")}</h3>
                    <p>
                        ${this.escape(this.state.selectedUser?.email || this.state.selectedUser?.username || "")}
                    </p>
                </div>

                <div class="acc-save-state" data-ref="saveState">
                    ${this.state.saving ? "در حال ذخیره..." : ""}
                </div>
            </div>

            <div class="acc-summary">
                <div class="acc-summary-card" data-summary="modules">
                    <strong>${summary.modules}</strong>
                    <span>ماژول</span>
                </div>
                <div class="acc-summary-card" data-summary="rows">
                    <strong>${summary.rows}</strong>
                    <span>رکورد permission</span>
                </div>
                <div class="acc-summary-card" data-summary="enabled">
                    <strong>${summary.enabled}</strong>
                    <span>دسترسی فعال</span>
                </div>
            </div>

                    ${Object.entries(grouped).map(([module, items]) => {
            const expanded = this.state.expandedModules[module] !== false;
            const activeCount = this.countEnabledForModule(items);

            return `
                    <div class="acc-module" data-module-wrap="${this.escapeAttr(module)}">
                        <div class="acc-module-header" data-module-toggle="${this.escapeAttr(module)}">
                            <div class="acc-module-title">
                                <strong>${this.escape(this.getModuleLabel(module, items))}</strong>
                                <span class="acc-badge green">${activeCount}</span>
                            </div>

                            <div class="acc-module-tools">
                                <button class="acc-mini-btn" type="button" data-select-all="${this.escapeAttr(module)}">فعال‌سازی همه</button>
                                <button class="acc-mini-btn" type="button" data-clear-all="${this.escapeAttr(module)}">غیرفعال‌سازی همه</button>
                                <button class="acc-mini-btn" type="button">${expanded ? "بستن" : "باز کردن"}</button>
                            </div>
                        </div>

                        <div class="acc-module-body" style="display:${expanded ? "block" : "none"}">
                            ${items.map((item, index) => this.renderPermissionRow(item, module, index)).join("")}
                        </div>
                    </div>
                    `;
        }).join("")}
        `;

        this.bindPermissionEvents();
        this.el.querySelectorAll("[data-summary]").forEach(el => {

            this.on(el, "click", () => {

                const type = el.dataset.summary;

                this.applyUserFilter(type);

            });

        });



    }

    applyUserFilter(type) {

        this.state.userFilter = type;

        this.filterUsers();

    };

    renderPermissionRow(item, module, index) {
        const actions = this.getActionList(item);
        const current = item.permissions || [];

        return `
            <div class="acc-permission-row">
                <div class="acc-permission-info">
                    <strong>${this.escape(item.label || item.name || item.code || module || `Permission ${index + 1}`)}</strong>
                    <small>${this.escape(item.description || item.code || item.module || "")}</small>
                </div>

                    <div class="acc-perm-actions">
                        ${actions.map(action => {
            const checked = current.includes(action);
            return `
                <label class="${checked ? "is-on" : ""}">
                    <input
                        type="checkbox"
                        data-module="${this.escapeAttr(item.module || module)}"
                        data-action="${this.escapeAttr(action)}"
                        data-row-index="${index}"
                        ${checked ? "checked" : ""}
                    />
                    ${this.escape(this.getActionLabel(action))}
                </label>
                `;
        }).join("")}
                    </div>
                </div>
                `;
    }

    bindPermissionEvents() {
        this.el.querySelectorAll("[data-module-toggle]").forEach(el => {
            this.on(el, "click", (e) => {
                if (e.target.closest("button")) return;
                const module = el.dataset.moduleToggle;
                this.toggleModule(module);
            });
        });

        this.el.querySelectorAll("[data-select-all]").forEach(el => {
            this.on(el, "click", (e) => {
                e.stopPropagation();
                this.bulkSetModule(el.dataset.selectAll, true);
            });
        });

        this.el.querySelectorAll("[data-clear-all]").forEach(el => {
            this.on(el, "click", (e) => {
                e.stopPropagation();
                this.bulkSetModule(el.dataset.clearAll, false);
            });
        });

        this.el.querySelectorAll("input[type=checkbox]").forEach(cb => {
            this.on(cb, "change", () => {
                const module = cb.dataset.module;
                const action = cb.dataset.action;
                const rowIndex = Number(cb.dataset.rowIndex);

                this.toggleLocalPermission(module, rowIndex, action, cb.checked);
                this.queuePermissionSave(module, action, cb.checked, rowIndex);
            });
        });
    }

    toggleModule(module) {
        this.state.expandedModules[module] = !this.state.expandedModules[module];
        this.renderPermissions();
    }

    expandAllModules() {
        const grouped = this.getGroupedPermissions();
        Object.keys(grouped).forEach(module => {
            this.state.expandedModules[module] = true;
        });
        this.renderPermissions();
    }

    collapseAllModules() {
        const grouped = this.getGroupedPermissions();
        Object.keys(grouped).forEach(module => {
            this.state.expandedModules[module] = false;
        });
        this.renderPermissions();
    }

    bulkSetModule(module, value) {
        const rows = this.state.permissions.filter(p => (p.module || "module") === module);

        rows.forEach((row, rowIndexInModule) => {
            const actions = this.getActionList(row);

            actions.forEach(action => {
                const current = Array.isArray(row.permissions) ? row.permissions : [];
                const has = current.includes(action);

                if (value && !has) {
                    current.push(action);
                    row.permissions = [...new Set(current)];
                    this.queuePermissionSave(module, action, true, rowIndexInModule, false);
                }

                if (!value && has) {
                    row.permissions = current.filter(a => a !== action);
                    this.queuePermissionSave(module, action, false, rowIndexInModule, false);
                }
            });
        });

        this.syncPermissionCache();
        this.renderPermissions();
    }

    toggleLocalPermission(module, rowIndex, action, value) {
        const rows = this.state.permissions.filter(p => (p.module || "module") === module);
        const row = rows[rowIndex];

        if (!row) return;

        const current = Array.isArray(row.permissions) ? [...row.permissions] : [];

        if (value && !current.includes(action)) current.push(action);
        if (!value) {
            row.permissions = current.filter(a => a !== action);
        } else {
            row.permissions = [...new Set(current)];
        }

        this.syncPermissionCache();
        this.renderPermissions();
    }

    queuePermissionSave(module, action, value, rowIndex = 0, rerender = true) {
        const userId = this.state.selectedUser?.id;
        if (!userId) return;

        const key = `${module}:${rowIndex}:${action}`;
        this.state.saveQueue[key] = { module, action, value };

        clearTimeout(this.state.saveTimers[key]);

        this.setSavingState(true);

        this.state.saveTimers[key] = setTimeout(async () => {
            const payload = this.state.saveQueue[key];
            delete this.state.saveQueue[key];

            try {
                await this.api.post(`/access/users/${userId}/permissions`, payload);
                this.setSaveMessage("ذخیره شد");
            } catch (e) {
                console.error(e);
                this.setSaveMessage("خطا در ذخیره", true);
                await this.loadPermissions(userId, { force: true });
            } finally {
                delete this.state.saveTimers[key];

                if (!Object.keys(this.state.saveTimers).length) {
                    this.setSavingState(false);
                }

                if (rerender) this.renderPermissions();
            }
        }, 250);
    }

    setSavingState(flag) {
        this.state.saving = flag;
        const saveEl = this.el.querySelector('[data-ref="saveState"]');
        if (saveEl) {
            saveEl.classList.remove("error");
            saveEl.textContent = flag ? "در حال ذخیره..." : "";
        }
    }

    setSaveMessage(message, isError = false) {
        const saveEl = this.el.querySelector('[data-ref="saveState"]');
        if (!saveEl) return;

        saveEl.textContent = message;
        saveEl.classList.toggle("error", !!isError);

        clearTimeout(this.saveMessageTimer);
        this.saveMessageTimer = setTimeout(() => {
            if (!this.state.saving && saveEl) {
                saveEl.textContent = "";
                saveEl.classList.remove("error");
            }
        }, 1800);
    }

    syncPermissionCache() {
        const userId = this.state.selectedUser?.id;
        if (!userId) return;

        this.state.permissionCache[userId] = this.clone(this.state.permissions);
    }

    getPermissionSummary() {
        let enabled = 0;

        (this.state.permissions || []).forEach(item => {
            enabled += (item.permissions || []).length;
        });

        return {
            modules: Object.keys(this.getGroupedPermissions()).length,
            rows: (this.state.permissions || []).length,
            enabled
        };
    }

    countEnabledForModule(items = []) {
        let total = 0;
        items.forEach(item => {
            total += (item.permissions || []).length;
        });
        return total;
    }

    getModuleLabel(module, items = []) {
        return items[0]?.moduleLabel || items[0]?.groupLabel || module;
    }

    getActionList(item) {
        if (Array.isArray(item.actions) && item.actions.length) {
            return item.actions;
        }

        return ["view", "create", "edit", "delete"];
    }

    getActionLabel(action) {
        const map = {
            view: "نمایش",
            create: "ایجاد",
            edit: "ویرایش",
            delete: "حذف",
            export: "خروجی",
            approve: "تأیید"
        };

        return map[action] || action;
    }

    clone(data) {
        return JSON.parse(JSON.stringify(data));
    }

    escapeAttr(value) {
        return this.escape(String(value ?? ""));
    }
}

viewRegistry.register("basesetpermission", PermissionManagerView);

export default PermissionManagerView;
