import React from 'react';
import { useQuery } from 'convex/react';
import { api } from '../../../../convex/_generated/api';
import { useOnlineUsers } from '../contexts/PresenceContext';
import { useVoice } from '../contexts/VoiceContext';
import { CrownIcon, SharingIcon } from '../assets/icons';
import ColoredIcon from './ColoredIcon';

const USER_COLORS = ['#5865F2', '#EBA7CD', '#57F287', '#FEE75C', '#EB459E', '#ED4245'];

function getUserColor(name) {
    let hash = 0;
    for (let i = 0; i < name.length; i++) {
        hash = name.charCodeAt(i) + ((hash << 5) - hash);
    }
    return USER_COLORS[Math.abs(hash) % USER_COLORS.length];
}

const STATUS_COLORS = {
    online: '#3ba55c',
    idle: '#faa61a',
    dnd: '#ed4245',
    invisible: '#747f8d',
    offline: '#747f8d',
};

const MembersList = ({ channelId, visible, onMemberClick }) => {
    const members = useQuery(
        api.members.getChannelMembers,
        channelId ? { channelId } : "skip"
    ) || [];
    const { resolveStatus } = useOnlineUsers();
    const { voiceStates } = useVoice();

    const usersInVoice = new Set();
    const usersScreenSharing = new Set();
    Object.values(voiceStates).forEach(users => {
        users.forEach(u => {
            usersInVoice.add(u.userId);
            if (u.isScreenSharing) usersScreenSharing.add(u.userId);
        });
    });

    if (!visible) return null;

    const onlineMembers = members.filter(m => resolveStatus(m.status, m.id) !== 'offline');
    const offlineMembers = members.filter(m => resolveStatus(m.status, m.id) === 'offline');

    // Group online members by highest hoisted role
    const roleGroups = {};
    const ungrouped = [];

    onlineMembers.forEach(member => {
        const hoistedRole = member.roles.find(r => r.isHoist && r.name !== '@everyone' && r.name !== 'Owner');
        if (hoistedRole) {
            const key = `${hoistedRole.position}_${hoistedRole.name}`;
            if (!roleGroups[key]) {
                roleGroups[key] = { role: hoistedRole, members: [] };
            }
            roleGroups[key].members.push(member);
        } else {
            ungrouped.push(member);
        }
    });

    // Sort groups by position descending
    const sortedGroups = Object.values(roleGroups).sort((a, b) => b.role.position - a.role.position);

    const renderMember = (member) => {
        const displayRole = member.roles.find(r => r.name !== '@everyone' && r.name !== 'Owner') || null;
        const nameColor = displayRole ? displayRole.color : '#fff';
        const isOwner = member.roles.some(r => r.name === 'Owner');
        const effectiveStatus = resolveStatus(member.status, member.id);

        return (
            <div
                key={member.id}
                className="member-item"
                onClick={() => onMemberClick && onMemberClick(member)}
                style={effectiveStatus === 'offline' ? { opacity: 0.3 } : {}}
            >
                <div className="member-avatar-wrapper">
                    {member.avatarUrl ? (
                        <img
                            className="member-avatar"
                            src={member.avatarUrl}
                            alt={member.username}
                            style={{ objectFit: 'cover' }}
                        />
                    ) : (
                        <div
                            className="member-avatar"
                            style={{ backgroundColor: getUserColor(member.username) }}
                        >
                            {member.username.substring(0, 1).toUpperCase()}
                        </div>
                    )}
                    <div
                        className="member-status-dot"
                        style={{ backgroundColor: STATUS_COLORS[effectiveStatus] || STATUS_COLORS.offline }}
                    />
                </div>
                <div className="member-info">
                    <span className="member-name" style={{ color: nameColor, display: 'flex', alignItems: 'center', gap: '4px' }}>
                        {member.username}
                        {isOwner && <ColoredIcon src={CrownIcon} color="var(--text-feedback-warning)" size="14px" />}
                    </span>
                    {usersScreenSharing.has(member.id) ? (
                        <div className="member-screen-sharing-indicator">
                            <img src={SharingIcon} alt="" />
                            Sharing their screen
                        </div>
                    ) : usersInVoice.has(member.id) ? (
                        <div className="member-voice-indicator">
                            <svg viewBox="0 0 24 24" fill="#3ba55c">
                                <path d="M12 3a1 1 0 0 0-1-1h-.06a1 1 0 0 0-.74.32L5.92 7H3a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h2.92l4.28 4.68a1 1 0 0 0 .74.32H11a1 1 0 0 0 1-1zm3.1 17.75c-.58.14-1.1-.33-1.1-.92v-.03c0-.5.37-.92.85-1.05a7 7 0 0 0 0-13.5A1.11 1.11 0 0 1 14 4.2v-.03c0-.6.52-1.06 1.1-.92a9 9 0 0 1 0 17.5"/>
                                <path d="M15.16 16.51c-.57.28-1.16-.2-1.16-.83v-.14c0-.43.28-.8.63-1.02a3 3 0 0 0 0-5.04c-.35-.23-.63-.6-.63-1.02v-.14c0-.63.59-1.1 1.16-.83a5 5 0 0 1 0 9.02"/>
                            </svg>
                            In Voice
                        </div>
                    ) : member.customStatus ? (
                        <div style={{ fontSize: '12px', color: 'var(--text-muted)', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>
                            {member.customStatus}
                        </div>
                    ) : null}
                </div>
            </div>
        );
    };

    return (
        <div className="members-list">
            {sortedGroups.map(group => (
                <React.Fragment key={group.role.name}>
                    <div className="members-role-header">
                        {group.role.name} — {group.members.length}
                    </div>
                    {group.members.map(renderMember)}
                </React.Fragment>
            ))}
            {ungrouped.length > 0 && (
                <>
                    <div className="members-role-header">
                        ONLINE — {ungrouped.length}
                    </div>
                    {ungrouped.map(renderMember)}
                </>
            )}
            {offlineMembers.length > 0 && (
                <>
                    <div className="members-role-header">
                        OFFLINE — {offlineMembers.length}
                    </div>
                    {offlineMembers.map(renderMember)}
                </>
            )}
        </div>
    );
};

export default MembersList;
