/**
 * Route Guards - Phase 8 Enterprise Pattern
 *
 * Validates route access, enforces permissions, and handles
 * authentication/authorization before allowing navigation.
 */

import store from '../stores/app-store.js';
import auditLogger from './audit-logger.js';

class RouteGuard {
  constructor() {
    this.guards = new Map();
    this.setupDefaultGuards();
  }

  /**
   * Register a guard for a specific route
   */
  register(route, guard) {
    this.guards.set(route, guard);
  }

  /**
   * Check if user can access route
   */
  canActivate(route) {
    const state = store.get();

    // Not authenticated
    if (!state.user) {
      auditLogger.logPermissionCheck('route_access', false, 'anonymous', `Unauthenticated access to ${route}`);
      return {
        allowed: false,
        reason: 'User must be logged in',
        redirect: '/#/login'
      };
    }

    // Check route-specific guard
    const guard = this.guards.get(route);
    if (guard) {
      const result = guard(state);
      if (!result.allowed) {
        auditLogger.logPermissionCheck('route_access', false, state.user.id, `Access denied to ${route}: ${result.reason}`);
      }
      return result;
    }

    auditLogger.logPermissionCheck('route_access', true, state.user.id, `Access granted to ${route}`);
    return { allowed: true };
  }

  /**
   * Check user permission
   */
  hasPermission(permission) {
    const state = store.get();
    if (!state.user) {
      auditLogger.logPermissionCheck('permission_check', false, 'anonymous', `Checking ${permission}`);
      return false;
    }

    const allowed = store.hasPermission(permission);
    auditLogger.logPermissionCheck('permission_check', allowed, state.user.id, `Checking ${permission}`);
    return allowed;
  }

  /**
   * Require permission before action
   */
  requirePermission(permission) {
    if (!this.hasPermission(permission)) {
      throw new Error(`Permission denied: ${permission}`);
    }
    return true;
  }

  /**
   * Setup default route guards
   */
  setupDefaultGuards() {
    // Settings page - requires TEAM_LEAD or SUPER_ADMIN
    this.register('settings', (state) => {
      const allowed = ['TEAM_LEAD', 'SUPER_ADMIN'].includes(state.role);
      return {
        allowed,
        reason: allowed ? '' : 'Settings access requires team lead or admin role'
      };
    });

    // Admin page - requires SUPER_ADMIN
    this.register('admin', (state) => {
      const allowed = state.role === 'SUPER_ADMIN';
      return {
        allowed,
        reason: allowed ? '' : 'Admin access requires super admin role'
      };
    });

    // Projects page - requires active team
    this.register('projects', (state) => {
      const allowed = !!state.team;
      return {
        allowed,
        reason: allowed ? '' : 'Must select a team first'
      };
    });

    // Figma integration - requires DEVELOPER or above
    this.register('figma', (state) => {
      const allowed = ['DEVELOPER', 'TEAM_LEAD', 'SUPER_ADMIN'].includes(state.role);
      return {
        allowed,
        reason: allowed ? '' : 'Figma integration requires developer or higher role'
      };
    });
  }

  /**
   * Validate action before execution
   */
  validateAction(action, resource) {
    const state = store.get();

    if (!state.user) {
      throw new Error('User must be authenticated');
    }

    const requiredPermission = this.getRequiredPermission(action, resource);
    if (!this.hasPermission(requiredPermission)) {
      throw new Error(`Permission denied: ${action} on ${resource}`);
    }

    auditLogger.logAction(`${action}_${resource}`, {
      user: state.user.id,
      role: state.role
    });

    return true;
  }

  /**
   * Map action to required permission
   */
  getRequiredPermission(action, resource) {
    const permissions = {
      'create_project': 'write',
      'delete_project': 'write',
      'sync_figma': 'write',
      'export_tokens': 'read',
      'modify_settings': 'write',
      'manage_team': 'manage_team',
      'view_audit': 'read',
    };

    return permissions[`${action}_${resource}`] || 'read';
  }

  /**
   * Get all available routes
   */
  getRoutes() {
    return Array.from(this.guards.keys());
  }

  /**
   * Check if route is protected
   */
  isProtected(route) {
    return this.guards.has(route);
  }
}

// Create and export singleton
const routeGuard = new RouteGuard();

export { RouteGuard };
export default routeGuard;
