import { prisma } from '@/lib/db'

// Default permissions that will be seeded
export const DEFAULT_PERMISSIONS = [
  // Dashboard
  { key: 'dashboard.access', name: 'Access Dashboard', category: 'dashboard' },
  { key: 'dashboard.view_stats', name: 'View Statistics', category: 'dashboard' },
  
  // Admin
  { key: 'admin.access', name: 'Access Admin Area', category: 'admin' },
  { key: 'admin.manage_users', name: 'Manage Users', category: 'admin' },
  { key: 'admin.manage_roles', name: 'Manage Roles', category: 'admin' },
  { key: 'admin.manage_settings', name: 'Manage Settings', category: 'admin' },
  { key: 'admin.view_audit', name: 'View Audit Logs', category: 'admin' },
  { key: 'admin.manage_updates', name: 'Manage Updates', category: 'admin' },
  
  // Job Panels
  { key: 'jobpanels.access', name: 'Access Job Panels', category: 'jobpanels' },
  { key: 'jobpanels.create', name: 'Create Job Panels', category: 'jobpanels' },
  { key: 'jobpanels.manage', name: 'Manage All Job Panels', category: 'jobpanels' },
  { key: 'jobpanels.delete', name: 'Delete Job Panels', category: 'jobpanels' },
  { key: 'jobpanels.assign_leaders', name: 'Assign Panel Leaders', category: 'jobpanels' },
  
  // Panel Builder
  { key: 'builder.access', name: 'Access Panel Builder', category: 'builder' },
  { key: 'builder.create', name: 'Create Custom Pages', category: 'builder' },
  { key: 'builder.manage', name: 'Manage All Pages', category: 'builder' },
  
  // Tickets
  { key: 'tickets.access', name: 'Access Tickets', category: 'tickets' },
  { key: 'tickets.manage', name: 'Manage All Tickets', category: 'tickets' },
  
  // Players
  { key: 'players.view', name: 'View Player Data', category: 'players' },
  { key: 'players.manage', name: 'Manage Player Data', category: 'players' },
  
  // Maintenance
  { key: 'maintenance.access', name: 'Access Maintenance', category: 'maintenance' },
  { key: 'maintenance.perform', name: 'Perform Maintenance Actions', category: 'maintenance' },
]

export const roleService = {
  // Initialize default permissions
  async initializePermissions() {
    for (const perm of DEFAULT_PERMISSIONS) {
      await prisma.permission.upsert({
        where: { key: perm.key },
        update: { name: perm.name, category: perm.category },
        create: {
          key: perm.key,
          name: perm.name,
          description: `Permission to ${perm.name.toLowerCase()}`,
          category: perm.category,
        },
      })
    }
    return { success: true, count: DEFAULT_PERMISSIONS.length }
  },

  // Get all permissions
  async getAllPermissions() {
    return prisma.permission.findMany({
      orderBy: [{ category: 'asc' }, { name: 'asc' }],
    })
  },

  // Get all custom roles
  async getAllRoles() {
    return prisma.customRole.findMany({
      include: {
        permissions: {
          include: {
            permission: true,
          },
        },
        _count: {
          select: { userRoles: true },
        },
      },
      orderBy: { priority: 'desc' },
    })
  },

  // Get role by ID
  async getRoleById(roleId: string) {
    return prisma.customRole.findUnique({
      where: { id: roleId },
      include: {
        permissions: {
          include: {
            permission: true,
          },
        },
        userRoles: true,
      },
    })
  },

  // Create custom role
  async createRole(data: {
    name: string
    displayName: string
    description?: string
    color?: string
    priority?: number
    permissionIds?: string[]
  }) {
    const role = await prisma.customRole.create({
      data: {
        name: data.name.toLowerCase().replace(/\s+/g, '_'),
        displayName: data.displayName,
        description: data.description,
        color: data.color || '#6B7280',
        priority: data.priority || 0,
      },
    })

    if (data.permissionIds?.length) {
      await prisma.rolePermission.createMany({
        data: data.permissionIds.map((permId) => ({
          roleId: role.id,
          permissionId: permId,
        })),
      })
    }

    return role
  },

  // Update role
  async updateRole(
    roleId: string,
    data: {
      displayName?: string
      description?: string
      color?: string
      priority?: number
      permissionIds?: string[]
    }
  ) {
    const role = await prisma.customRole.update({
      where: { id: roleId },
      data: {
        displayName: data.displayName,
        description: data.description,
        color: data.color,
        priority: data.priority,
      },
    })

    if (data.permissionIds !== undefined) {
      // Remove existing permissions
      await prisma.rolePermission.deleteMany({
        where: { roleId },
      })

      // Add new permissions
      if (data.permissionIds.length) {
        await prisma.rolePermission.createMany({
          data: data.permissionIds.map((permId) => ({
            roleId,
            permissionId: permId,
          })),
        })
      }
    }

    return role
  },

  // Delete role
  async deleteRole(roleId: string) {
    const role = await prisma.customRole.findUnique({
      where: { id: roleId },
    })

    if (!role) throw new Error('Role not found')
    if (role.isSystem) throw new Error('Cannot delete system role')

    return prisma.customRole.delete({
      where: { id: roleId },
    })
  },

  // Assign role to user
  async assignRoleToUser(discordId: string, roleId: string, assignedBy?: string) {
    return prisma.userCustomRole.create({
      data: {
        discordId,
        roleId,
        assignedBy,
      },
    })
  },

  // Remove role from user
  async removeRoleFromUser(discordId: string, roleId: string) {
    return prisma.userCustomRole.delete({
      where: {
        discordId_roleId: {
          discordId,
          roleId,
        },
      },
    })
  },

  // Get user's custom roles
  async getUserRoles(discordId: string) {
    return prisma.userCustomRole.findMany({
      where: { discordId },
      include: {
        role: {
          include: {
            permissions: {
              include: {
                permission: true,
              },
            },
          },
        },
      },
    })
  },

  // Check if user has permission
  async hasPermission(discordId: string, permissionKey: string, systemRole?: string) {
    // Superadmin always has all permissions
    if (systemRole === 'SUPERADMIN') return true

    // Admin has most permissions except specific superadmin-only ones
    if (systemRole === 'ADMIN') {
      const adminRestricted = ['admin.manage_updates', 'maintenance.perform']
      if (!adminRestricted.includes(permissionKey)) return true
    }

    // Check custom role permissions
    const userRoles = await prisma.userCustomRole.findMany({
      where: { discordId },
      include: {
        role: {
          include: {
            permissions: {
              include: {
                permission: true,
              },
            },
          },
        },
      },
    })

    for (const ur of userRoles) {
      const hasPermission = ur.role.permissions.some(
        (rp) => rp.permission.key === permissionKey
      )
      if (hasPermission) return true
    }

    return false
  },

  // Get all permissions for a user
  async getUserPermissions(discordId: string, systemRole?: string) {
    const permissions = new Set<string>()

    // Add system role permissions
    if (systemRole === 'SUPERADMIN') {
      DEFAULT_PERMISSIONS.forEach((p) => permissions.add(p.key))
    } else if (systemRole === 'ADMIN') {
      DEFAULT_PERMISSIONS.forEach((p) => {
        if (!['admin.manage_updates', 'maintenance.perform'].includes(p.key)) {
          permissions.add(p.key)
        }
      })
    }

    // Add custom role permissions
    const userRoles = await prisma.userCustomRole.findMany({
      where: { discordId },
      include: {
        role: {
          include: {
            permissions: {
              include: {
                permission: true,
              },
            },
          },
        },
      },
    })

    for (const ur of userRoles) {
      for (const rp of ur.role.permissions) {
        permissions.add(rp.permission.key)
      }
    }

    return Array.from(permissions)
  },
}

export default roleService
