import { ChevronDown, Hash, Volume2 } from "lucide-react"
import React from "react"
import { NavLink } from "react-router"
import { useShallow } from "zustand/react/shallow"
import { ChannelType, type ServerChannel } from "~/lib/api/types"
import { cn } from "~/lib/utils"
import { useChannelsVoiceStateStore } from "~/stores/channels-voice-state"
import { useGatewayStore } from "~/stores/gateway-store"
import { useUsersStore } from "~/stores/users-store"
import { Button } from "../ui/button"
import UserAvatar from "../user-avatar"

interface ChannelListItemProps {
    channel: ServerChannel
}

function ServerCategory({ channel }: ChannelListItemProps) {
    return (
        <div className="text-xs flex flex-row justify-between mt-4">
            <div className="grow">
                <div className="flex items-center gap-1">
                    {channel.name}
                    <ChevronDown className="size-4" />
                </div>
            </div>
        </div>
    )
}

function ServerVoice({ channel }: ChannelListItemProps) {
    const updateVoiceState = useGatewayStore(state => state.updateVoiceState)
    const channelVoiceState = useChannelsVoiceStateStore(state => state.channels[channel.id]) || {}
    const userIds = Object.keys(channelVoiceState.users ?? {})

    const { users, fetchUsersIfNotPresent } = useUsersStore(useShallow(state => ({
        users: state.users,
        fetchUsersIfNotPresent: state.fetchUsersIfNotPresent
    })))

    const channelUsers = React.useMemo(() => userIds.map(userId => users[userId]).filter(Boolean), [userIds, users])

    React.useEffect(() => {
        fetchUsersIfNotPresent(userIds)
    }, [userIds])

    const onClick = () => {
        updateVoiceState(channel.serverId, channel.id)
    }

    return (
        <>
            <Button variant="secondary" size="sm" className="justify-start" onClick={onClick}>
                <div className="flex items-center gap-2 max-w-72">
                    <div>
                        <Volume2 />
                    </div>
                    <div className="truncate">
                        {channel.name}
                    </div>
                </div>
            </Button>
            {channelUsers.length > 0 &&
                <div className="ml-2 border-l-2 flex flex-col gap-1">
                    {
                        channelUsers
                            .map(user => (
                                <div key={user.id} className="flex items-center gap-2 max-w-72 pl-4">
                                    <UserAvatar user={user} className="size-6" />
                                    {user.displayName || user.username}
                                </div>
                            ))
                    }
                </div>}
        </>
    )
}

function ServerText({ channel }: ChannelListItemProps) {
    return (
        <NavLink to={`/app/server/${channel.serverId}/${channel.id}`} discover="none" >
            {({ isActive }) => (
                <Button variant="secondary" size="sm" className={
                    cn(
                        "justify-start w-full",
                        isActive ? "bg-accent hover:bg-accent" : "bg-secondary"
                    )
                }>
                    <div className="flex items-center gap-2 max-w-72">
                        <div>
                            <Hash />
                        </div>
                        <div className="truncate">
                            {channel.name}
                        </div>
                    </div>
                </Button>
            )
            }
        </NavLink>
    )
}

export default function ServerChannelListItem({ channel }: ChannelListItemProps) {
    switch (channel.type) {
        case ChannelType.SERVER_CATEGORY:
            return <ServerCategory channel={channel} />
        case ChannelType.SERVER_VOICE:
            return <ServerVoice channel={channel} />
        case ChannelType.SERVER_TEXT:
            return <ServerText channel={channel} />
        default:
            return null
    }
}
