import { db } from './db.ts';
import { adminRoles, adminPermissions, adminRolePermissions } from '@/drizzle/schema.ts';

/**
 * Admin Role Definitions
 */
export const ADMIN_ROLES = {
  SUPER_ADMIN: 'super_admin',
  FINANCE_MANAGER: 'finance_manager',
  GAME_MANAGER: 'game_manager',
  SUPPORT_MANAGER: 'support_manager',
  MODERATOR: 'moderator',
} as const;

/**
 * Permission Definitions
 */
export const ADMIN_PERMISSIONS = {
  // Dashboard
  VIEW_DASHBOARD: 'view_dashboard',
  VIEW_ANALYTICS: 'view_analytics',
  
  // Games
  MANAGE_GAMES: 'manage_games',
  CREATE_GAMES: 'create_games',
  EDIT_GAMES: 'edit_games',
  DELETE_GAMES: 'delete_games',
  
  // Finance
  VIEW_PAYMENTS: 'view_payments',
  PROCESS_WITHDRAWALS: 'process_withdrawals',
  APPROVE_WITHDRAWALS: 'approve_withdrawals',
  MANAGE_TRANSACTIONS: 'manage_transactions',
  VIEW_REVENUE: 'view_revenue',
  
  // Users
  MANAGE_USERS: 'manage_users',
  BAN_USERS: 'ban_users',
  RESET_PASSWORDS: 'reset_passwords',
  VIEW_USER_DATA: 'view_user_data',
  
  // Tournaments
  MANAGE_TOURNAMENTS: 'manage_tournaments',
  CREATE_TOURNAMENTS: 'create_tournaments',
  EDIT_TOURNAMENTS: 'edit_tournaments',
  
  // Support
  VIEW_SUPPORT_TICKETS: 'view_support_tickets',
  RESPOND_TO_TICKETS: 'respond_to_tickets',
  CLOSE_TICKETS: 'close_tickets',
  
  // Moderation
  MODERATE_CHAT: 'moderate_chat',
  REMOVE_CONTENT: 'remove_content',
  
  // System
  MANAGE_SETTINGS: 'manage_settings',
  VIEW_AUDIT_LOGS: 'view_audit_logs',
  MANAGE_ADMINS: 'manage_admins',
} as const;

/**
 * Role-Permission Mapping
 */
export const ROLE_PERMISSIONS: Record<string, string[]> = {
  [ADMIN_ROLES.SUPER_ADMIN]: Object.values(ADMIN_PERMISSIONS),
  
  [ADMIN_ROLES.FINANCE_MANAGER]: [
    ADMIN_PERMISSIONS.VIEW_DASHBOARD,
    ADMIN_PERMISSIONS.VIEW_PAYMENTS,
    ADMIN_PERMISSIONS.PROCESS_WITHDRAWALS,
    ADMIN_PERMISSIONS.APPROVE_WITHDRAWALS,
    ADMIN_PERMISSIONS.MANAGE_TRANSACTIONS,
    ADMIN_PERMISSIONS.VIEW_REVENUE,
    ADMIN_PERMISSIONS.VIEW_AUDIT_LOGS,
  ],
  
  [ADMIN_ROLES.GAME_MANAGER]: [
    ADMIN_PERMISSIONS.VIEW_DASHBOARD,
    ADMIN_PERMISSIONS.MANAGE_GAMES,
    ADMIN_PERMISSIONS.CREATE_GAMES,
    ADMIN_PERMISSIONS.EDIT_GAMES,
    ADMIN_PERMISSIONS.DELETE_GAMES,
    ADMIN_PERMISSIONS.MANAGE_TOURNAMENTS,
    ADMIN_PERMISSIONS.CREATE_TOURNAMENTS,
    ADMIN_PERMISSIONS.EDIT_TOURNAMENTS,
    ADMIN_PERMISSIONS.VIEW_ANALYTICS,
  ],
  
  [ADMIN_ROLES.SUPPORT_MANAGER]: [
    ADMIN_PERMISSIONS.VIEW_DASHBOARD,
    ADMIN_PERMISSIONS.VIEW_SUPPORT_TICKETS,
    ADMIN_PERMISSIONS.RESPOND_TO_TICKETS,
    ADMIN_PERMISSIONS.CLOSE_TICKETS,
    ADMIN_PERMISSIONS.VIEW_USER_DATA,
    ADMIN_PERMISSIONS.MANAGE_USERS,
  ],
  
  [ADMIN_ROLES.MODERATOR]: [
    ADMIN_PERMISSIONS.VIEW_DASHBOARD,
    ADMIN_PERMISSIONS.MODERATE_CHAT,
    ADMIN_PERMISSIONS.REMOVE_CONTENT,
    ADMIN_PERMISSIONS.BAN_USERS,
  ],
};

/**
 * Check if user has permission
 */
export async function checkPermission(userId: string, permission: string): Promise<boolean> {
  try {
    // Get user's admin role
    const adminUser = await db.query.adminRoles.findFirst({
      where: (roles, { eq }) => eq(roles.userId, userId),
    });

    if (!adminUser) return false;

    // Get role permissions
    const permissions = ROLE_PERMISSIONS[adminUser.role] || [];
    return permissions.includes(permission);
  } catch (error) {
    console.error('[RBAC] Permission check failed:', error);
    return false;
  }
}

/**
 * Get user's role
 */
export async function getUserRole(userId: string): Promise<string | null> {
  try {
    const adminUser = await db.query.adminRoles.findFirst({
      where: (roles, { eq }) => eq(roles.userId, userId),
    });
    return adminUser?.role || null;
  } catch (error) {
    console.error('[RBAC] Get role failed:', error);
    return null;
  }
}

/**
 * Get user's permissions
 */
export async function getUserPermissions(userId: string): Promise<string[]> {
  try {
    const role = await getUserRole(userId);
    if (!role) return [];
    return ROLE_PERMISSIONS[role] || [];
  } catch (error) {
    console.error('[RBAC] Get permissions failed:', error);
    return [];
  }
}

/**
 * Assign role to user
 */
export async function assignRole(userId: string, role: string): Promise<boolean> {
  try {
    // Validate role
    if (!Object.values(ADMIN_ROLES).includes(role)) {
      throw new Error('Invalid role');
    }

    // Check if user already has a role
    const existing = await db.query.adminRoles.findFirst({
      where: (roles, { eq }) => eq(roles.userId, userId),
    });

    if (existing) {
      // Update existing role
      await db.update(adminRoles)
        .set({ role, updatedAt: new Date() })
        .where((t) => t.userId === userId);
    } else {
      // Create new role assignment
      await db.insert(adminRoles).values({
        userId,
        role,
        createdAt: new Date(),
        updatedAt: new Date(),
      });
    }

    console.log(`[RBAC] Assigned role ${role} to user ${userId}`);
    return true;
  } catch (error) {
    console.error('[RBAC] Assign role failed:', error);
    return false;
  }
}

/**
 * Remove admin role from user
 */
export async function removeAdminRole(userId: string): Promise<boolean> {
  try {
    await db.delete(adminRoles)
      .where((t) => t.userId === userId);
    
    console.log(`[RBAC] Removed admin role from user ${userId}`);
    return true;
  } catch (error) {
    console.error('[RBAC] Remove role failed:', error);
    return false;
  }
}

/**
 * Get all admin users
 */
export async function getAllAdmins(): Promise<any[]> {
  try {
    return await db.query.adminRoles.findMany();
  } catch (error) {
    console.error('[RBAC] Get admins failed:', error);
    return [];
  }
}

/**
 * Get admins by role
 */
export async function getAdminsByRole(role: string): Promise<any[]> {
  try {
    return await db.query.adminRoles.findMany({
      where: (roles, { eq }) => eq(roles.role, role),
    });
  } catch (error) {
    console.error('[RBAC] Get admins by role failed:', error);
    return [];
  }
}
