import { NextRequest, NextResponse } from 'next/server'
import { getCurrentUser } from '@/lib/auth'
import { prisma } from '@/lib/db'

export async function GET() {
  try {
    const currentUser = await getCurrentUser()
    if (!currentUser) {
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
    }

    // Only admins can view users
    if (!['ADMIN', 'SUPERADMIN'].includes(currentUser.role)) {
      return NextResponse.json({ error: 'Forbidden' }, { status: 403 })
    }
    let users: any[] = []
    try {
      users = await prisma.user.findMany({
        select: {
          id: true,
          username: true,
          discordId: true,
          avatar: true,
          role: true,
          isBanned: true,
          bannedAt: true,
          bannedReason: true,
          createdAt: true,
          lastLoginAt: true,
        },
        orderBy: {
          createdAt: 'desc',
        },
      })
    } catch (dbError) {
      console.error('[API] Admin users - Database error:', dbError)
      // Fallback: try raw query
      try {
        users = await prisma.$queryRaw`SELECT * FROM users ORDER BY createdAt DESC` as any[]
      } catch (rawError) {
        console.error('[API] Admin users - Raw query also failed:', rawError)
      }
    }

    // Get user group memberships using raw SQL
    let groupMemberships: any[] = []
    try {
      groupMemberships = await prisma.$queryRaw`
        SELECT ugm.userId, ugm.groupId, ug.name as groupName, ug.displayName, ug.color
        FROM user_group_members ugm
        JOIN user_groups ug ON ugm.groupId = ug.id
      ` as any[]
    } catch (e) {
      // Table may not exist yet
    }

    // Get all groups for the dropdown
    let groups: any[] = []
    try {
      groups = await prisma.$queryRaw`
        SELECT id, name, displayName, color, permissions FROM user_groups ORDER BY priority DESC
      ` as any[]
      groups = groups.map(g => ({
        ...g,
        permissions: typeof g.permissions === 'string' ? JSON.parse(g.permissions) : (g.permissions || [])
      }))
    } catch (e) {
      // Table may not exist yet
    }

    // Map lastLoginAt to lastLogin for frontend compatibility and add group info
    const mappedUsers = users.map(user => {
      const userMemberships = groupMemberships.filter(m => m.userId === user.id)
      return {
        ...user,
        lastLogin: user.lastLoginAt,
        // Keep legacy single group fields for backwards compatibility
        groupId: userMemberships[0]?.groupId || null,
        groupName: userMemberships[0]?.displayName || null,
        groupColor: userMemberships[0]?.color || null,
        // New: array of all user's groups
        groups: userMemberships.map(m => ({
          id: m.groupId,
          name: m.groupName,
          displayName: m.displayName,
          color: m.color,
        })),
      }
    })

    return NextResponse.json({ users: mappedUsers, groups })
  } catch (error) {
    console.error('[API] Failed to fetch users:', error)
    return NextResponse.json({ error: 'Failed to fetch users' }, { status: 500 })
  }
}

// PUT - Update user (role change, edit, assign group)
export async function PUT(request: NextRequest) {
  try {
    const currentUser = await getCurrentUser()
    if (!currentUser) {
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
    }

    // Only superadmins can change roles
    if (currentUser.role !== 'SUPERADMIN') {
      return NextResponse.json({ error: 'Only Superadmins can modify users' }, { status: 403 })
    }

    const body = await request.json()
    const { userId, action, role, username, reason, groupId, groupIds } = body

    if (!userId) {
      return NextResponse.json({ error: 'User ID required' }, { status: 400 })
    }

    // Prevent self-modification of role
    if (action === 'changeRole' && userId === currentUser.id) {
      return NextResponse.json({ error: 'Cannot change your own role' }, { status: 400 })
    }

    switch (action) {
      case 'changeRole':
        if (!role || !['USER', 'MODERATOR', 'ADMIN', 'SUPERADMIN'].includes(role)) {
          return NextResponse.json({ error: 'Invalid role' }, { status: 400 })
        }
        
        // Update user role
        await prisma.user.update({
          where: { id: userId },
          data: { role },
        })
        
        // Update user groups if provided
        if (groupIds !== undefined) {
          try {
            // Remove user from all groups first
            await prisma.$executeRaw`DELETE FROM user_group_members WHERE userId = ${userId}`
            
            // Add user to selected groups
            if (Array.isArray(groupIds) && groupIds.length > 0) {
              for (const gId of groupIds) {
                const memberId = crypto.randomUUID()
                await prisma.$executeRaw`
                  INSERT INTO user_group_members (id, userId, groupId, joinedAt) 
                  VALUES (${memberId}, ${userId}, ${gId}, NOW())
                `
              }
            }
          } catch (e) {
            console.error('[API] Failed to update groups:', e)
          }
        }
        
        return NextResponse.json({ success: true, message: `Role changed to ${role}` })

      case 'assignGroup':
        try {
          // First remove user from all groups
          await prisma.$executeRaw`DELETE FROM user_group_members WHERE userId = ${userId}`
          
          // If groupId provided, add to new group
          if (groupId) {
            const memberId = crypto.randomUUID()
            await prisma.$executeRaw`
              INSERT INTO user_group_members (id, userId, groupId, joinedAt) 
              VALUES (${memberId}, ${userId}, ${groupId}, NOW())
            `
          }
          return NextResponse.json({ success: true, message: 'Group assigned' })
        } catch (e: any) {
          console.error('[API] Failed to assign group:', e)
          return NextResponse.json({ error: 'Failed to assign group' }, { status: 500 })
        }

      case 'edit':
        const updateData: { username?: string } = {}
        if (username) updateData.username = username
        await prisma.user.update({
          where: { id: userId },
          data: updateData,
        })
        return NextResponse.json({ success: true, message: 'User updated' })

      case 'ban':
        await prisma.user.update({
          where: { id: userId },
          data: {
            isBanned: true,
            bannedAt: new Date(),
            bannedReason: reason || 'No reason provided',
          },
        })
        return NextResponse.json({ success: true, message: 'User banned' })

      case 'unban':
        await prisma.user.update({
          where: { id: userId },
          data: {
            isBanned: false,
            bannedAt: null,
            bannedReason: null,
          },
        })
        return NextResponse.json({ success: true, message: 'User unbanned' })

      default:
        return NextResponse.json({ error: 'Invalid action' }, { status: 400 })
    }
  } catch (error) {
    console.error('[API] Failed to update user:', error)
    return NextResponse.json({ error: 'Failed to update user' }, { status: 500 })
  }
}

// DELETE - Delete user
export async function DELETE(request: NextRequest) {
  try {
    const currentUser = await getCurrentUser()
    if (!currentUser) {
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
    }

    if (currentUser.role !== 'SUPERADMIN') {
      return NextResponse.json({ error: 'Only Superadmins can delete users' }, { status: 403 })
    }

    const { searchParams } = new URL(request.url)
    const userId = searchParams.get('userId')

    if (!userId) {
      return NextResponse.json({ error: 'User ID required' }, { status: 400 })
    }

    // Prevent self-deletion
    if (userId === currentUser.id) {
      return NextResponse.json({ error: 'Cannot delete yourself' }, { status: 400 })
    }

    await prisma.user.delete({
      where: { id: userId },
    })

    return NextResponse.json({ success: true, message: 'User deleted' })
  } catch (error) {
    console.error('[API] Failed to delete user:', error)
    return NextResponse.json({ error: 'Failed to delete user' }, { status: 500 })
  }
}
