import { useMemo, useState } from 'react';
import { useConnection } from '../../context/ConnectionContext';
import { useServerData } from '../../context/ServerDataContext';
import { UserAvatar } from '../UserAvatar';

const ROLE_OPTIONS = [
  { value: 'member', label: 'Member' },
  { value: 'admin', label: 'Admin' },
];

const ROLE_RANK = { owner: 0, admin: 1, member: 2 };

function formatJoined(iso) {
  if (!iso) return 'Unknown';
  const date = new Date(iso);
  if (Number.isNaN(date.getTime())) return 'Unknown';
  return date.toLocaleDateString(undefined, { year: 'numeric', month: 'short', day: 'numeric' });
}

function deviceSummary(devices) {
  if (!devices.length) return 'No devices';
  return devices.map((d) => d.name).join(', ');
}

export function UserManagementPanel() {
  const { account, api } = useConnection();
  const { users, revisions, refreshUsers } = useServerData();
  const [busyUsername, setBusyUsername] = useState(null);
  const [error, setError] = useState(null);

  const self = account?.username.toLowerCase();

  const revisionCounts = useMemo(() => {
    const counts = {};
    for (const rev of revisions) {
      const key = rev.author?.toLowerCase();
      if (!key) continue;
      counts[key] = (counts[key] ?? 0) + 1;
    }
    return counts;
  }, [revisions]);

  const sortedUsers = useMemo(
    () =>
      [...users].sort((a, b) => {
        if (Boolean(a.removed) !== Boolean(b.removed)) return a.removed ? 1 : -1;
        const rankDiff = (ROLE_RANK[a.role] ?? 2) - (ROLE_RANK[b.role] ?? 2);
        if (rankDiff !== 0) return rankDiff;
        return a.displayName.localeCompare(b.displayName);
      }),
    [users]
  );

  const runAction = async (username, action) => {
    setBusyUsername(username);
    setError(null);
    const result = await action();
    if (!result.ok) setError(result.error ?? 'Action failed.');
    await refreshUsers();
    setBusyUsername(null);
  };

  return (
    <div className="user-mgmt-container">
      {error && <div className="user-mgmt-error">{error}</div>}
      <ul className="user-mgmt-list">
        {sortedUsers.map((user) => {
          const isSelf = user.username.toLowerCase() === self;
          const isOwner = user.role === 'owner';
          const isBusy = busyUsername === user.username;

          return (
            <li
              key={user.username}
              className={`user-mgmt-card${user.removed ? ' user-mgmt-card--disabled' : ''}`}
            >
              <UserAvatar
                user={{ avatarUrl: isSelf ? account.avatarUrl : api?.avatarUrl(user.avatar) }}
                size={40}
                className="user-mgmt-avatar"
              />
              <div className="user-mgmt-main">
                <div className="user-mgmt-name">
                  {user.displayName}
                  {isSelf && <span className="member-you-tag"> (you)</span>}
                  {user.removed && <span className="user-mgmt-disabled-tag">Disabled</span>}
                </div>
                <div className="user-mgmt-username">{user.username}</div>
                <div className="user-mgmt-meta">
                  <span>{deviceSummary(user.devices)}</span>
                  <span>
                    {revisionCounts[user.username.toLowerCase()] ?? 0} revision
                    {(revisionCounts[user.username.toLowerCase()] ?? 0) === 1 ? '' : 's'} submitted
                  </span>
                  <span>Joined {formatJoined(user.joinedAt)}</span>
                </div>
              </div>
              <div className="user-mgmt-actions">
                <select
                  className="user-mgmt-role"
                  value={isOwner ? 'owner' : user.role}
                  disabled={isOwner || isSelf || isBusy || user.removed}
                  onChange={(e) => runAction(user.username, () => api.adminSetRole(user.username, e.target.value))}
                  aria-label={`Role for ${user.displayName}`}
                >
                  {isOwner ? (
                    <option value="owner">Owner</option>
                  ) : (
                    ROLE_OPTIONS.map((opt) => (
                      <option key={opt.value} value={opt.value}>
                        {opt.label}
                      </option>
                    ))
                  )}
                </select>
                {!isOwner && !isSelf && !user.removed && (
                  <button
                    type="button"
                    className="user-mgmt-disable-btn"
                    disabled={isBusy}
                    onClick={() => runAction(user.username, () => api.adminDeleteUser(user.username))}
                  >
                    Disable
                  </button>
                )}
              </div>
            </li>
          );
        })}
      </ul>
    </div>
  );
}
