// noqa: js-006 - async init pattern is safe, loadData has try/catch
// static/admin/js/store-roles.js
/**
 * Admin store roles management page
 *
 * Super admins: merchant → store cascading selection.
 * Platform admins: store selection scoped to their platforms.
 *
 * Uses Tom Select for selection and permission catalog API for
 * displaying permissions with labels and descriptions.
 */

const storeRolesAdminLog = (window.LogConfig && window.LogConfig.createLogger)
    ? window.LogConfig.createLogger('adminStoreRoles', false)
    : console;

storeRolesAdminLog.info('Loading...');

function adminStoreRoles() {
    storeRolesAdminLog.info('adminStoreRoles() called');

    const config = window._adminStoreRolesConfig || {};
    const isSuperAdmin = config.isSuperAdmin || false;

    return {
        // Inherit base layout state
        ...data(),

        // Set page identifier
        currentPage: 'store-roles',

        // Selection state
        isSuperAdmin,
        selectedMerchant: null,
        selectedStore: null,
        merchantSelector: null,
        storeSelector: null,

        // Role state
        loading: false,
        roles: [],
        rolesLoading: false,
        saving: false,
        showRoleModal: false,
        editingRole: null,
        roleForm: { name: '', permissions: [] },
        permissionCategories: [],
        presetRoles: ['manager', 'staff', 'support', 'viewer', 'marketing'],

        async init() {
            // Guard against multiple initialization
            if (window._adminStoreRolesInitialized) {
                return;
            }
            window._adminStoreRolesInitialized = true;

            storeRolesAdminLog.info('Admin Store Roles init(), isSuperAdmin:', isSuperAdmin);

            this.$nextTick(() => {
                if (isSuperAdmin) {
                    this.initMerchantSelector();
                } else {
                    this.initStoreSelector();
                }
            });

            // Load permission catalog
            await this.loadPermissionCatalog();

            // Restore saved selection
            const savedStoreId = localStorage.getItem('admin_store_roles_selected_store_id');
            if (savedStoreId) {
                storeRolesAdminLog.info('Restoring saved store:', savedStoreId);
                setTimeout(async () => {
                    await this.restoreSavedStore(parseInt(savedStoreId));
                }, 300);
            }

            storeRolesAdminLog.info('Admin Store Roles initialization complete');
        },

        // =====================================================================
        // Permission Catalog
        // =====================================================================

        async loadPermissionCatalog() {
            try {
                const response = await apiClient.get('/admin/store-roles/permissions/catalog');
                this.permissionCategories = response.categories || [];
                storeRolesAdminLog.info('Loaded permission catalog:', this.permissionCategories.length, 'categories');
            } catch (error) {
                storeRolesAdminLog.warn('Failed to load permission catalog:', error);
            }
        },

        // =====================================================================
        // Merchant Selector (Super Admin only)
        // =====================================================================

        initMerchantSelector() {
            const el = this.$refs.merchantSelect;
            if (!el) {
                storeRolesAdminLog.warn('Merchant select element not found');
                return;
            }

            const self = this;

            waitForTomSelect(() => {
                self.merchantSelector = new TomSelect(el, {
                    valueField: 'id',
                    labelField: 'name',
                    searchField: ['name'],
                    maxOptions: 50,
                    placeholder: 'Search merchant by name...',
                    load: async function(query, callback) {
                        if (query.length < 2) { callback([]); return; }
                        try {
                            const response = await apiClient.get(
                                `/admin/merchants?search=${encodeURIComponent(query)}&limit=50`
                            );
                            const merchants = (response.merchants || []).map(m => ({
                                id: m.id,
                                name: m.name,
                                store_count: m.store_count || 0,
                            }));
                            callback(merchants);
                        } catch (error) {
                            storeRolesAdminLog.error('Merchant search failed:', error);
                            callback([]);
                        }
                    },
                    render: {
                        option: function(data, escape) {
                            return `<div class="flex justify-between items-center py-1">
                                <span class="font-medium">${escape(data.name)}</span>
                                <span class="text-xs text-gray-400 ml-2">${data.store_count} store(s)</span>
                            </div>`;
                        },
                        item: function(data, escape) {
                            return `<div>${escape(data.name)}</div>`;
                        },
                        no_results: function() {
                            return '<div class="no-results py-2 px-3 text-gray-500">No merchants found</div>';
                        },
                        loading: function() {
                            return '<div class="loading py-2 px-3 text-gray-500">Searching...</div>';
                        }
                    },
                    onChange: function(value) {
                        if (value) {
                            const selected = this.options[value];
                            if (selected) {
                                self.onMerchantSelected({
                                    id: parseInt(value),
                                    name: selected.name,
                                    store_count: selected.store_count,
                                });
                            }
                        } else {
                            self.onMerchantCleared();
                        }
                    },
                    loadThrottle: 150,
                    closeAfterSelect: true,
                    persist: true,
                    create: false,
                });

                storeRolesAdminLog.info('Merchant selector initialized');
            });
        },

        async onMerchantSelected(merchant) {
            storeRolesAdminLog.info('Merchant selected:', merchant.name);
            this.selectedMerchant = merchant;
            this.selectedStore = null;
            this.roles = [];
            localStorage.removeItem('admin_store_roles_selected_store_id');

            // Destroy previous store selector and reinit with merchant filter
            if (this.storeSelector) {
                if (typeof this.storeSelector.destroy === 'function') {
                    this.storeSelector.destroy();
                }
                this.storeSelector = null;
            }

            // Wait for DOM update (x-show toggles the store select container)
            await this.$nextTick();

            this.initStoreSelector(merchant.id);
        },

        onMerchantCleared() {
            storeRolesAdminLog.info('Merchant cleared');
            this.selectedMerchant = null;
            this.selectedStore = null;
            this.roles = [];
            localStorage.removeItem('admin_store_roles_selected_store_id');

            if (this.storeSelector) {
                if (typeof this.storeSelector.destroy === 'function') {
                    this.storeSelector.destroy();
                }
                this.storeSelector = null;
            }
        },

        // =====================================================================
        // Store Selector
        // =====================================================================

        initStoreSelector(merchantId = null) {
            const el = this.$refs.storeSelect;
            if (!el) {
                storeRolesAdminLog.warn('Store select element not found');
                return;
            }

            const apiEndpoint = merchantId
                ? `/admin/stores?merchant_id=${merchantId}`
                : '/admin/stores';

            this.storeSelector = initStoreSelector(el, {
                placeholder: merchantId ? 'Select store...' : 'Search store by name or code...',
                apiEndpoint: apiEndpoint,
                onSelect: async (store) => {
                    storeRolesAdminLog.info('Store selected:', store);
                    this.selectedStore = store;
                    localStorage.setItem('admin_store_roles_selected_store_id', store.id.toString());
                    await this.loadRoles();
                },
                onClear: () => {
                    storeRolesAdminLog.info('Store cleared');
                    this.selectedStore = null;
                    this.roles = [];
                    localStorage.removeItem('admin_store_roles_selected_store_id');
                }
            });
        },

        // =====================================================================
        // Restore / Clear
        // =====================================================================

        async restoreSavedStore(storeId) {
            try {
                const store = await apiClient.get(`/admin/stores/${storeId}`);
                if (!store) return;

                if (isSuperAdmin && store.merchant_id) {
                    // For super admin, restore the merchant first
                    try {
                        const merchant = await apiClient.get(`/admin/merchants/${store.merchant_id}`);
                        if (merchant && this.merchantSelector) {
                            this.merchantSelector.addOption({
                                id: merchant.id,
                                name: merchant.name,
                                store_count: merchant.store_count || 0,
                            });
                            this.merchantSelector.setValue(merchant.id, true);
                            this.selectedMerchant = { id: merchant.id, name: merchant.name };

                            // Wait for DOM, then init store selector and set value
                            await this.$nextTick();
                            this.initStoreSelector(merchant.id);
                            setTimeout(() => {
                                if (this.storeSelector) {
                                    this.storeSelector.setValue(store.id, store);
                                }
                                this.selectedStore = { id: store.id, name: store.name, store_code: store.store_code };
                                this.loadRoles();
                            }, 300);
                        }
                    } catch (error) {
                        storeRolesAdminLog.warn('Failed to restore merchant:', error);
                        localStorage.removeItem('admin_store_roles_selected_store_id');
                    }
                } else {
                    // Platform admin: just restore the store
                    if (this.storeSelector) {
                        this.storeSelector.setValue(store.id, store);
                    }
                    this.selectedStore = { id: store.id, name: store.name, store_code: store.store_code };
                    await this.loadRoles();
                }
                storeRolesAdminLog.info('Restored store:', store.name);
            } catch (error) {
                storeRolesAdminLog.warn('Failed to restore saved store:', error);
                localStorage.removeItem('admin_store_roles_selected_store_id');
            }
        },

        clearSelection() {
            if (isSuperAdmin) {
                if (this.merchantSelector) {
                    this.merchantSelector.clear();
                }
                this.selectedMerchant = null;
            }
            if (this.storeSelector) {
                if (typeof this.storeSelector.clear === 'function') {
                    this.storeSelector.clear();
                }
            }
            this.selectedStore = null;
            this.roles = [];
            localStorage.removeItem('admin_store_roles_selected_store_id');
        },

        // =====================================================================
        // Roles CRUD
        // =====================================================================

        async loadRoles() {
            if (!this.selectedStore) return;

            this.rolesLoading = true;
            try {
                const response = await apiClient.get(`/admin/store-roles?store_id=${this.selectedStore.id}`);
                this.roles = response.roles || [];
                storeRolesAdminLog.info('Loaded', this.roles.length, 'roles');
            } catch (error) {
                storeRolesAdminLog.error('Failed to load roles:', error);
                Utils.showToast(error.message || 'Failed to load roles', 'error');
            } finally {
                this.rolesLoading = false;
            }
        },

        isPresetRole(name) {
            return this.presetRoles.includes(name.toLowerCase());
        },

        openCreateModal() {
            this.editingRole = null;
            this.roleForm = { name: '', permissions: [] };
            this.showRoleModal = true;
        },

        openEditModal(role) {
            this.editingRole = role;
            this.roleForm = {
                name: role.name,
                permissions: [...(role.permissions || [])],
            };
            this.showRoleModal = true;
        },

        togglePermission(permId) {
            const idx = this.roleForm.permissions.indexOf(permId);
            if (idx >= 0) {
                this.roleForm.permissions.splice(idx, 1);
            } else {
                this.roleForm.permissions.push(permId);
            }
        },

        toggleCategory(category) {
            const perms = category.permissions || [];
            const permIds = perms.map(p => p.id);
            const allSelected = permIds.every(id => this.roleForm.permissions.includes(id));
            if (allSelected) {
                this.roleForm.permissions = this.roleForm.permissions.filter(id => !permIds.includes(id));
            } else {
                for (const id of permIds) {
                    if (!this.roleForm.permissions.includes(id)) {
                        this.roleForm.permissions.push(id);
                    }
                }
            }
        },

        isCategoryFullySelected(category) {
            const perms = category.permissions || [];
            return perms.length > 0 && perms.every(p => this.roleForm.permissions.includes(p.id));
        },

        async saveRole() {
            if (!this.selectedStore) return;

            this.saving = true;
            try {
                const storeParam = `store_id=${this.selectedStore.id}`;
                if (this.editingRole) {
                    await apiClient.put(`/admin/store-roles/${this.editingRole.id}?${storeParam}`, this.roleForm);
                } else {
                    await apiClient.post(`/admin/store-roles?${storeParam}`, this.roleForm);
                }

                this.showRoleModal = false;
                Utils.showToast('Role saved successfully', 'success');
                await this.loadRoles();
            } catch (error) {
                storeRolesAdminLog.error('Error saving role:', error);
                Utils.showToast(error.message || 'Failed to save role', 'error');
            } finally {
                this.saving = false;
            }
        },

        async confirmDelete(role) {
            if (!this.selectedStore) return;
            if (!confirm(`Delete role "${role.name}"? This cannot be undone.`)) return;

            try {
                await apiClient.delete(`/admin/store-roles/${role.id}?store_id=${this.selectedStore.id}`);
                Utils.showToast('Role deleted successfully', 'success');
                await this.loadRoles();
            } catch (error) {
                storeRolesAdminLog.error('Error deleting role:', error);
                Utils.showToast(error.message || 'Failed to delete role', 'error');
            }
        },
    };
}

storeRolesAdminLog.info('Module loaded');
