import { useState, useMemo } from 'react';
import { useUsers } from '../../../api/queries/admin/rbac';
import type { UserDetail, GroupDetail } from '../../../api/queries/admin/rbac';
import { useGroups } from '../../../api/queries/admin/rbac';
import styles from './RbacPage.module.css';

function getInitials(name: string): string {
  const parts = name.trim().split(/\s+/);
  if (parts.length >= 2) return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();
  return name.slice(0, 2).toUpperCase();
}

function formatDate(iso: string): string {
  try {
    return new Date(iso).toLocaleDateString(undefined, {
      year: 'numeric',
      month: '2-digit',
      day: '2-digit',
    });
  } catch {
    return iso;
  }
}

function buildGroupPath(user: UserDetail, groupMap: Map<string, GroupDetail>): string {
  if (user.directGroups.length === 0) return '(no groups)';
  const names = user.directGroups.map((g) => g.name);
  // Try to find a parent -> child path
  for (const g of user.directGroups) {
    const detail = groupMap.get(g.id);
    if (detail?.parentGroupId) {
      const parent = groupMap.get(detail.parentGroupId);
      if (parent) return `${parent.name} > ${g.name}`;
    }
  }
  return names.join(', ');
}

export function UsersTab() {
  const users = useUsers();
  const groups = useGroups();
  const [selected, setSelected] = useState<string | null>(null);
  const [filter, setFilter] = useState('');

  const groupMap = useMemo(() => {
    const map = new Map<string, GroupDetail>();
    for (const g of groups.data ?? []) {
      map.set(g.id, g);
    }
    return map;
  }, [groups.data]);

  const filtered = useMemo(() => {
    const list = users.data ?? [];
    if (!filter) return list;
    const lower = filter.toLowerCase();
    return list.filter(
      (u) =>
        u.displayName.toLowerCase().includes(lower) ||
        u.email.toLowerCase().includes(lower) ||
        u.userId.toLowerCase().includes(lower)
    );
  }, [users.data, filter]);

  const selectedUser = useMemo(
    () => (users.data ?? []).find((u) => u.userId === selected) ?? null,
    [users.data, selected]
  );

  if (users.isLoading) {
    return <div className={styles.loading}>Loading...</div>;
  }

  return (
    <>
      <div className={styles.panelHeader}>
        <div>
          <div className={styles.panelTitle}>Users</div>
          <div className={styles.panelSubtitle}>
            Manage identities, group membership and direct roles
          </div>
        </div>
      </div>
      <div className={styles.split}>
        <div className={styles.listPane}>
          <div className={styles.searchBar}>
            <input
              className={styles.searchInput}
              placeholder="Search users..."
              value={filter}
              onChange={(e) => setFilter(e.target.value)}
            />
          </div>
          <div className={styles.entityList}>
            {filtered.map((user) => {
              const isSelected = user.userId === selected;
              return (
                <div
                  key={user.userId}
                  className={`${styles.entityItem} ${isSelected ? styles.entityItemSelected : ''}`}
                  onClick={() => setSelected(user.userId)}
                >
                  <div className={`${styles.avatar} ${styles.avatarUser}`}>
                    {getInitials(user.displayName)}
                  </div>
                  <div className={styles.entityInfo}>
                    <div className={styles.entityName}>
                      {user.displayName}
                      {user.provider !== 'local' && (
                        <span className={styles.oidcBadge}>{user.provider}</span>
                      )}
                    </div>
                    <div className={styles.entityMeta}>
                      {user.email} · {buildGroupPath(user, groupMap)}
                    </div>
                    <div className={styles.tagList}>
                      {user.directRoles.map((r) => (
                        <span key={r.id} className={`${styles.tag} ${styles.tagRole}`}>
                          {r.name}
                        </span>
                      ))}
                      {user.effectiveRoles
                        .filter((er) => !user.directRoles.some((dr) => dr.id === er.id))
                        .map((r) => (
                          <span
                            key={r.id}
                            className={`${styles.tag} ${styles.tagRole} ${styles.tagInherited}`}
                          >
                            {r.name}
                          </span>
                        ))}
                      {user.directGroups.map((g) => (
                        <span key={g.id} className={`${styles.tag} ${styles.tagGroup}`}>
                          {g.name}
                        </span>
                      ))}
                    </div>
                  </div>
                  <div
                    className={`${styles.statusDot} ${styles.statusActive}`}
                  />
                </div>
              );
            })}
          </div>
        </div>
        <div className={styles.detailPane}>
          {!selectedUser ? (
            <div className={styles.detailEmpty}>
              <span>Select a user to view details</span>
            </div>
          ) : (
            <UserDetail user={selectedUser} groupMap={groupMap} />
          )}
        </div>
      </div>
    </>
  );
}

function UserDetail({
  user,
  groupMap,
}: {
  user: UserDetail;
  groupMap: Map<string, GroupDetail>;
}) {
  // Build group tree for this user
  const groupTree = useMemo(() => {
    const tree: { name: string; depth: number; annotation: string }[] = [];
    for (const g of user.directGroups) {
      const detail = groupMap.get(g.id);
      if (detail?.parentGroupId) {
        const parent = groupMap.get(detail.parentGroupId);
        if (parent && !tree.some((t) => t.name === parent.name)) {
          tree.push({ name: parent.name, depth: 0, annotation: '' });
        }
        tree.push({ name: g.name, depth: 1, annotation: 'child group' });
      } else {
        tree.push({ name: g.name, depth: 0, annotation: '' });
      }
    }
    return tree;
  }, [user, groupMap]);

  const inheritedRoles = user.effectiveRoles.filter(
    (er) => !user.directRoles.some((dr) => dr.id === er.id)
  );

  return (
    <>
      <div className={`${styles.detailAvatar} ${styles.avatarUser}`}>
        {getInitials(user.displayName)}
      </div>
      <div className={styles.detailName}>
        {user.displayName}
        {user.provider !== 'local' && (
          <span className={styles.oidcBadge}>{user.provider}</span>
        )}
      </div>
      <div className={styles.detailEmail}>{user.email}</div>

      <div className={styles.fieldRow}>
        <span className={styles.fieldLabel}>Status</span>
        <span className={styles.fieldVal} style={{ color: 'var(--green)', fontSize: 12 }}>
          Active
        </span>
      </div>
      <div className={styles.fieldRow}>
        <span className={styles.fieldLabel}>ID</span>
        <span className={`${styles.fieldVal} ${styles.fieldMono}`}>{user.userId}</span>
      </div>
      <div className={styles.fieldRow}>
        <span className={styles.fieldLabel}>Created</span>
        <span className={styles.fieldVal}>{formatDate(user.createdAt)}</span>
      </div>

      <hr className={styles.divider} />

      <div className={styles.detailSection}>
        <div className={styles.detailSectionTitle}>
          Group membership <span>direct only</span>
        </div>
        {user.directGroups.length === 0 ? (
          <span style={{ fontSize: 12, color: 'var(--text-muted)' }}>No group membership</span>
        ) : (
          user.directGroups.map((g) => (
            <span key={g.id} className={`${styles.chip} ${styles.chipGroup}`}>
              {g.name}
            </span>
          ))
        )}
      </div>

      <div className={styles.detailSection}>
        <div className={styles.detailSectionTitle}>
          Effective roles <span>direct + inherited</span>
        </div>
        {user.directRoles.map((r) => (
          <span key={r.id} className={`${styles.chip} ${styles.chipRole}`}>
            {r.name}
          </span>
        ))}
        {inheritedRoles.map((r) => (
          <span key={r.id} className={`${styles.chip} ${styles.chipRole} ${styles.chipInherited}`}>
            {r.name}
            <span className={styles.chipSource}>
              {r.source ? `\u2191 ${r.source}` : ''}
            </span>
          </span>
        ))}
        {inheritedRoles.length > 0 && (
          <div className={styles.inheritNote}>
            Dashed roles are inherited transitively through group membership.
          </div>
        )}
      </div>

      {groupTree.length > 0 && (
        <div className={styles.detailSection}>
          <div className={styles.detailSectionTitle}>Group tree</div>
          {groupTree.map((node, i) => (
            <div key={i} className={styles.treeRow}>
              {node.depth > 0 && (
                <div className={styles.treeIndent}>
                  <div className={styles.treeCorner} />
                </div>
              )}
              {node.name}
              {node.annotation && (
                <span style={{ fontSize: 10, color: 'var(--text-muted)', marginLeft: 4 }}>
                  {node.annotation}
                </span>
              )}
            </div>
          ))}
        </div>
      )}
    </>
  );
}
