"use client"

import * as React from "react"
import { useQuery, useMutation, gql } from '@apollo/client';
import {
    IconUsers,
    IconShield,
    IconPlus,
    IconMinus,
    IconUserCheck,
    IconChevronDown,
} from "@tabler/icons-react"

import { Badge } from "@/components/ui/badge"
import { Button } from "@/components/ui/button"
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
import { Checkbox } from "@/components/ui/checkbox"
import {
    Command,
    CommandEmpty,
    CommandGroup,
    CommandInput,
    CommandItem,
    CommandList,
} from "@/components/ui/command"
import {
    Dialog,
    DialogContent,
    DialogDescription,
    DialogFooter,
    DialogHeader,
    DialogTitle,
    DialogTrigger,
} from "@/components/ui/dialog"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import {
    Popover,
    PopoverContent,
    PopoverTrigger,
} from "@/components/ui/popover"
import {
    Select,
    SelectContent,
    SelectItem,
    SelectTrigger,
    SelectValue,
} from "@/components/ui/select"
import { Avatar, AvatarFallback } from "@/components/ui/avatar"
import { toast } from "sonner"

const GET_USERS_WITH_GROUPS = gql`
    query GetUsersWithGroups($offset: Int, $limit: Int, $sortBy: String, $sortOrder: String, $filter: String) {
        usersWithGroups(offset: $offset, limit: $limit, sortBy: $sortBy, sortOrder: $sortOrder, filter: $filter) {
            user {
                id
                username
                email
                isActivate
                createdAt
                updatedAt
            }
            groups
        }
    }
`

const GET_ALL_ROLES = gql`
    query GetAllRoles {
        roles(pagination: { page: 1, perPage: 100 }) {
            items {
                id
                name
                code
                level
                isActive
            }
        }
    }
`

const ASSIGN_ROLE_TO_USER = gql`
    mutation AssignRoleToUser($userId: UUID!, $roleName: String!) {
        assignRoleToUser(userId: $userId, roleName: $roleName)
    }
`

const REMOVE_ROLE_FROM_USER = gql`
    mutation RemoveRoleFromUser($userId: UUID!, $roleName: String!) {
        removeRoleFromUser(userId: $userId, roleName: $roleName)
    }
`

const BATCH_ASSIGN_ROLES_TO_USER = gql`
    mutation BatchAssignRolesToUser($userId: UUID!, $roleIds: [UUID!]!) {
        batchAssignRolesToUser(userId: $userId, roleIds: $roleIds)
    }
`

interface UserWithGroups {
    user: User
    groups: string[]
}

interface User {
    id: string
    username: string
    email: string
    isActivate: boolean
    createdAt: string
    updatedAt: string
    groups: string[]
}

interface Role {
    id: string
    name: string
    code: string
    level: number
    isActive: boolean
}

function UserRoleCard({ user, allRoles, onRoleChange }: {
    user: User
    allRoles: Role[]
    onRoleChange: () => void
}) {
    const [assignRole] = useMutation(ASSIGN_ROLE_TO_USER)
    const [removeRole] = useMutation(REMOVE_ROLE_FROM_USER)
    const [open, setOpen] = React.useState(false)

    const availableRoles = allRoles.filter(role =>
        role.isActive && !user.groups.some(group => group.toLowerCase() === role.code.toLowerCase())
    )


    const handleAssignRole = async (roleId: string) => {
        const role = allRoles.find((r: Role) => r.id === roleId)
        if (!role) return

        try {
            await assignRole({
                variables: { userId: user.id, roleName: role.code }
            })
            toast.success("角色分配成功")
            onRoleChange()
        } catch (error) {
            toast.error("角色分配失败")
        }
    }

    const handleRemoveRole = async (roleName: string) => {
        const role = allRoles.find((r: Role) => r.code === roleName)
        if (!role) return

        try {
            await removeRole({
                variables: { userId: user.id, roleName: role.code }
            })
            toast.success("角色移除成功")
            onRoleChange()
        } catch (error) {
            toast.error("角色移除失败")
        }
    }

    const getInitials = (username: string) => {
        return username.slice(0, 2).toUpperCase()
    }

    return (
        <Card>
            <CardHeader className="pb-3">
                <div className="flex items-center gap-3">
                    <Avatar className="h-12 w-12">
                        <AvatarFallback>{getInitials(user.username)}</AvatarFallback>
                    </Avatar>
                    <div className="flex-1">
                        <CardTitle className="text-base">{user.username}</CardTitle>
                        <CardDescription>{user.email}</CardDescription>
                    </div>
                    <Badge variant={user.isActivate ? "default" : "secondary"}>
                        {user.isActivate ? "活跃" : "非活跃"}
                    </Badge>
                </div>
            </CardHeader>
            <CardContent>
                <div className="space-y-3">
                    <div className="flex items-center justify-between">
                        <Label className="text-sm font-medium">已分配角色</Label>
                        <Popover open={open} onOpenChange={setOpen}>
                            <PopoverTrigger asChild>
                                <Button variant="outline" size="sm" className="h-8">
                                    <IconPlus className="mr-1 h-3 w-3" />
                                    分配角色
                                    <IconChevronDown className="ml-1 h-3 w-3" />
                                </Button>
                            </PopoverTrigger>
                            <PopoverContent className="w-64 p-0" align="end">
                                <div className="w-64">
                                    {availableRoles.length === 0 ? (
                                        <div className="p-4 text-sm text-muted-foreground text-center">
                                            没有可分配的角色
                                        </div>
                                    ) : (
                                        <div className="p-1">
                                            <div className="text-xs font-medium text-muted-foreground px-2 py-1.5">
                                                可分配的角色
                                            </div>
                                            {availableRoles.map((role) => (
                                                <button
                                                    key={role.id}
                                                    className="w-full flex items-center gap-2 px-2 py-2 text-left hover:bg-accent hover:text-accent-foreground rounded-sm"
                                                    onClick={() => {
                                                        handleAssignRole(role.id)
                                                        setOpen(false)
                                                    }}
                                                >
                                                    <IconShield className="h-4 w-4" />
                                                    <div className="flex-1">
                                                        <div className="font-medium text-sm">{role.name}</div>
                                                        <div className="text-xs text-muted-foreground">{role.code}</div>
                                                    </div>
                                                </button>
                                            ))}
                                        </div>
                                    )}
                                </div>
                            </PopoverContent>
                        </Popover>
                    </div>

                    <div className="space-y-2">
                        {user.groups.length === 0 ? (
                            <div className="text-sm text-muted-foreground py-2 text-center">
                                未分配任何角色
                            </div>
                        ) : (
                            user.groups.map((groupCode) => {
                                const role = allRoles.find((r: Role) => r.code.toLowerCase() === groupCode.toLowerCase())
                                return (
                                    <div
                                        key={groupCode}
                                        className="flex items-center justify-between p-2 border rounded-lg bg-muted/30"
                                    >
                                        <div className="flex items-center gap-2">
                                            <IconShield className="h-4 w-4 text-primary" />
                                            <div>
                                                <div className="font-medium text-sm">
                                                    {role?.name || groupCode}
                                                </div>
                                                <div className="text-xs text-muted-foreground">{groupCode}</div>
                                            </div>
                                        </div>
                                        <div className="flex items-center gap-2">
                                            <Badge variant="outline" className="text-xs">
                                                {role ? `Level ${role.level}` : "角色"}
                                            </Badge>
                                            <Button
                                                variant="ghost"
                                                size="sm"
                                                className="h-6 w-6 p-0 text-muted-foreground hover:text-red-600"
                                                onClick={() => handleRemoveRole(groupCode)}
                                            >
                                                <IconMinus className="h-3 w-3" />
                                            </Button>
                                        </div>
                                    </div>
                                )
                            })
                        )}
                    </div>
                </div>
            </CardContent>
        </Card>
    )
}

function BatchAssignDialog({ selectedUsers, allRoles, onSuccess }: {
    selectedUsers: User[]
    allRoles: Role[]
    onSuccess: () => void
}) {
    const [open, setOpen] = React.useState(false)
    const [selectedRole, setSelectedRole] = React.useState("")
    const [loading, setLoading] = React.useState(false)
    const [batchAssignRoles] = useMutation(BATCH_ASSIGN_ROLES_TO_USER)

    const handleBatchAssign = async () => {
        if (!selectedRole || selectedUsers.length === 0) {
            toast.error("请选择角色和用户")
            return
        }

        const role = allRoles.find((r: Role) => r.id === selectedRole)
        if (!role) return

        setLoading(true)
        try {
            await Promise.all(
                selectedUsers.map(user =>
                    batchAssignRoles({
                        variables: { userId: user.id, roleIds: [role.id] }
                    })
                )
            )
            toast.success(`成功为 ${selectedUsers.length} 个用户分配角色`)
            setOpen(false)
            setSelectedRole("")
            onSuccess()
        } catch (error) {
            toast.error("批量分配失败")
        } finally {
            setLoading(false)
        }
    }

    return (
        <Dialog open={open} onOpenChange={setOpen}>
            <DialogTrigger asChild>
                <Button variant="outline" size="sm" disabled={selectedUsers.length === 0}>
                    <IconUserCheck className="mr-2 h-4 w-4" />
                    批量分配角色 ({selectedUsers.length})
                </Button>
            </DialogTrigger>
            <DialogContent>
                <DialogHeader>
                    <DialogTitle>批量分配角色</DialogTitle>
                    <DialogDescription>
                        为选中的 {selectedUsers.length} 个用户分配角色
                    </DialogDescription>
                </DialogHeader>
                <div className="space-y-4">
                    <div className="space-y-2">
                        <Label>选择角色</Label>
                        <Select value={selectedRole} onValueChange={setSelectedRole}>
                            <SelectTrigger>
                                <SelectValue placeholder="选择要分配的角色" />
                            </SelectTrigger>
                            <SelectContent>
                                {allRoles.filter(role => role.isActive).map((role) => (
                                    <SelectItem key={role.id} value={role.id}>
                                        <div className="flex items-center gap-2">
                                            <IconShield className="h-4 w-4" />
                                            {role.name} ({role.code})
                                        </div>
                                    </SelectItem>
                                ))}
                            </SelectContent>
                        </Select>
                    </div>
                    <div className="space-y-2">
                        <Label>选中的用户</Label>
                        <div className="max-h-32 overflow-y-auto space-y-1">
                            {selectedUsers.map((user) => (
                                <div key={user.id} className="flex items-center gap-2 text-sm">
                                    <Avatar className="h-6 w-6">
                                        <AvatarFallback className="text-xs">
                                            {user.username.slice(0, 2).toUpperCase()}
                                        </AvatarFallback>
                                    </Avatar>
                                    {user.username} ({user.email})
                                </div>
                            ))}
                        </div>
                    </div>
                </div>
                <DialogFooter>
                    <Button variant="outline" onClick={() => setOpen(false)}>
                        取消
                    </Button>
                    <Button onClick={handleBatchAssign} disabled={loading || !selectedRole}>
                        {loading ? "分配中..." : "确认分配"}
                    </Button>
                </DialogFooter>
            </DialogContent>
        </Dialog>
    )
}

export function UserRoleManagement() {
    const [searchTerm, setSearchTerm] = React.useState("")
    const [roleFilter, setRoleFilter] = React.useState("")
    const [selectedUsers, setSelectedUsers] = React.useState<User[]>([])
    const [pagination, setPagination] = React.useState({
        offset: 0,
        limit: 12,
    })

    const { data: usersData, loading: usersLoading, refetch: refetchUsers } = useQuery(GET_USERS_WITH_GROUPS, {
        variables: {
            offset: pagination.offset,
            limit: pagination.limit,
            sortBy: "created_at",
            sortOrder: "DESC",
            filter: searchTerm || undefined,
        },
        fetchPolicy: 'cache-and-network'
    })

    // 当搜索词或角色筛选改变时，重新获取数据
    React.useEffect(() => {
        refetchUsers()
    }, [searchTerm, refetchUsers])

    const { data: rolesData } = useQuery(GET_ALL_ROLES, {
        fetchPolicy: 'cache-and-network'
    })

    const rawUsersWithGroups = usersData?.usersWithGroups || []
    const users: User[] = rawUsersWithGroups.map((userWithGroups: UserWithGroups) => ({
        ...userWithGroups.user,
        groups: userWithGroups.groups
    }))
    const allRoles = rolesData?.roles?.items || []
    const totalUsers = users.length

    const handleUserSelect = (user: User, checked: boolean) => {
        if (checked) {
            setSelectedUsers(prev => [...prev, user])
        } else {
            setSelectedUsers(prev => prev.filter(u => u.id !== user.id))
        }
    }

    const handleSelectAll = (checked: boolean) => {
        if (checked) {
            setSelectedUsers(filteredUsers)
        } else {
            setSelectedUsers([])
        }
    }

    // 按角色筛选用户
    const filteredUsers = users.filter(user => {
        if (!roleFilter) return true
        const selectedRole = allRoles.find((r: Role) => r.id === roleFilter)
        return selectedRole ? user.groups.some(group => group.toLowerCase() === selectedRole.code.toLowerCase()) : true
    })

    return (
        <div className="space-y-4">
            <Card>
                <CardHeader>
                    <CardTitle>用户角色管理</CardTitle>
                    <CardDescription>
                        为用户分配和管理角色，支持单个和批量操作
                        {roleFilter && ` • 筛选角色: ${allRoles.find((r: Role) => r.id === roleFilter)?.name}`}
                        {searchTerm && ` • 搜索: "${searchTerm}"`}
                    </CardDescription>
                </CardHeader>
                <CardContent>
                    <div className="flex flex-col gap-4 mb-6">
                        <div className="flex items-center gap-2 flex-wrap">
                            <div className="flex-1 min-w-[200px]">
                                <Input
                                    placeholder="搜索用户..."
                                    value={searchTerm}
                                    onChange={(e) => setSearchTerm(e.target.value)}
                                    className="max-w-sm"
                                />
                            </div>
                            <Select value={roleFilter || "all"} onValueChange={(value) => setRoleFilter(value === "all" ? "" : value)}>
                                <SelectTrigger className="w-[180px]">
                                    <SelectValue placeholder="筛选角色" />
                                </SelectTrigger>
                                <SelectContent>
                                    <SelectItem value="all">全部角色</SelectItem>
                                    {allRoles.map((role: Role) => (
                                        <SelectItem key={role.id} value={role.id}>
                                            {role.name}
                                        </SelectItem>
                                    ))}
                                </SelectContent>
                            </Select>
                            {(searchTerm || roleFilter) && (
                                <Button
                                    variant="outline"
                                    size="sm"
                                    onClick={() => {
                                        setSearchTerm("")
                                        setRoleFilter("")
                                    }}
                                >
                                    清除筛选
                                </Button>
                            )}
                        </div>

                        <div className="flex items-center justify-between">
                            <div className="flex items-center gap-2">
                                <Checkbox
                                    checked={selectedUsers.length === filteredUsers.length && filteredUsers.length > 0}
                                    onCheckedChange={(checked) => handleSelectAll(!!checked)}
                                />
                                <Label className="text-sm">
                                    全选 ({selectedUsers.length}/{filteredUsers.length})
                                </Label>
                            </div>
                            <BatchAssignDialog
                                selectedUsers={selectedUsers}
                                allRoles={allRoles}
                                onSuccess={() => {
                                    refetchUsers()
                                    setSelectedUsers([])
                                }}
                            />
                        </div>
                    </div>

                    {usersLoading ? (
                        <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
                            {[...Array(6)].map((_, i) => (
                                <Card key={i} className="animate-pulse">
                                    <CardHeader>
                                        <div className="flex items-center gap-3">
                                            <div className="h-12 w-12 rounded-full bg-muted" />
                                            <div className="space-y-2 flex-1">
                                                <div className="h-4 bg-muted rounded w-2/3" />
                                                <div className="h-3 bg-muted rounded w-1/2" />
                                            </div>
                                        </div>
                                    </CardHeader>
                                    <CardContent>
                                        <div className="space-y-2">
                                            <div className="h-3 bg-muted rounded w-1/3" />
                                            <div className="h-8 bg-muted rounded" />
                                        </div>
                                    </CardContent>
                                </Card>
                            ))}
                        </div>
                    ) : filteredUsers.length === 0 ? (
                        <div className="text-center py-8">
                            <IconUsers className="mx-auto h-12 w-12 text-muted-foreground" />
                            <h3 className="mt-2 text-sm font-semibold text-gray-900">暂无用户</h3>
                            <p className="mt-1 text-sm text-gray-500">没有找到匹配的用户。</p>
                        </div>
                    ) : (
                        <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
                            {filteredUsers.map((user) => (
                                <div key={user.id} className="relative">
                                    <div className="absolute top-3 left-3 z-10">
                                        <Checkbox
                                            checked={selectedUsers.some(u => u.id === user.id)}
                                            onCheckedChange={(checked) => handleUserSelect(user, !!checked)}
                                        />
                                    </div>
                                    <UserRoleCard
                                        user={user}
                                        allRoles={allRoles}
                                        onRoleChange={refetchUsers}
                                    />
                                </div>
                            ))}
                        </div>
                    )}

                    {totalUsers >= pagination.limit && (
                        <div className="flex items-center justify-center gap-2 mt-6">
                            <Button
                                variant="outline"
                                size="sm"
                                onClick={() => setPagination(prev => ({ ...prev, offset: Math.max(0, prev.offset - prev.limit) }))}
                                disabled={pagination.offset === 0}
                            >
                                上一页
                            </Button>
                            <span className="text-sm text-muted-foreground">
                                显示 {pagination.offset + 1} - {pagination.offset + users.length} 项
                            </span>
                            <Button
                                variant="outline"
                                size="sm"
                                onClick={() => setPagination(prev => ({ ...prev, offset: prev.offset + prev.limit }))}
                                disabled={users.length < pagination.limit}
                            >
                                下一页
                            </Button>
                        </div>
                    )}
                </CardContent>
            </Card>
        </div>
    )
}