import { useState } from 'react';
import {
  Avatar,
  Badge,
  Button,
  ConfirmDialog,
  Input,
  MonoText,
  Spinner,
  Tag,
  useToast,
} from '@cameleer/design-system';
import {
  useRoles,
  useRole,
  useCreateRole,
  useDeleteRole,
} from '../../api/queries/admin/rbac';
import type { RoleDetail } from '../../api/queries/admin/rbac';
import styles from './UserManagement.module.css';

export default function RolesTab() {
  const { data: roles, isLoading } = useRoles();
  const [selectedId, setSelectedId] = useState<string | null>(null);
  const [search, setSearch] = useState('');
  const [showCreate, setShowCreate] = useState(false);
  const [newName, setNewName] = useState('');
  const [newDescription, setNewDescription] = useState('');
  const [confirmDelete, setConfirmDelete] = useState(false);

  const { data: detail, isLoading: detailLoading } = useRole(selectedId);
  const createRole = useCreateRole();
  const deleteRole = useDeleteRole();
  const { toast } = useToast();

  const filtered = (roles ?? []).filter((r) =>
    r.name.toLowerCase().includes(search.toLowerCase()),
  );

  function handleCreate() {
    if (!newName.trim()) return;
    createRole.mutate(
      { name: newName.trim(), description: newDescription.trim() || undefined },
      {
        onSuccess: () => {
          toast({ title: 'Role created', variant: 'success' });
          setShowCreate(false);
          setNewName('');
          setNewDescription('');
        },
        onError: () => {
          toast({ title: 'Failed to create role', variant: 'error' });
        },
      },
    );
  }

  function handleDelete() {
    if (!selectedId) return;
    deleteRole.mutate(selectedId, {
      onSuccess: () => {
        toast({ title: 'Role deleted', variant: 'success' });
        setSelectedId(null);
        setConfirmDelete(false);
      },
      onError: () => {
        toast({ title: 'Failed to delete role', variant: 'error' });
        setConfirmDelete(false);
      },
    });
  }

  return (
    <div className={styles.splitPane}>
      {/* Left pane — list */}
      <div className={styles.listPane}>
        <div className={styles.listHeader}>
          <Input
            placeholder="Search roles…"
            value={search}
            onChange={(e) => setSearch(e.target.value)}
          />
          <Button
            variant="secondary"
            size="sm"
            onClick={() => setShowCreate((v) => !v)}
          >
            + Add Role
          </Button>
        </div>

        {showCreate && (
          <div className={styles.createForm}>
            <Input
              placeholder="Role name (e.g. EDITOR)"
              value={newName}
              onChange={(e) => setNewName(e.target.value.toUpperCase())}
              style={{ marginBottom: 8 }}
            />
            <Input
              placeholder="Description (optional)"
              value={newDescription}
              onChange={(e) => setNewDescription(e.target.value)}
            />
            <div className={styles.createFormActions}>
              <Button
                variant="ghost"
                size="sm"
                onClick={() => {
                  setShowCreate(false);
                  setNewName('');
                  setNewDescription('');
                }}
              >
                Cancel
              </Button>
              <Button
                variant="primary"
                size="sm"
                loading={createRole.isPending}
                disabled={!newName.trim()}
                onClick={handleCreate}
              >
                Create
              </Button>
            </div>
          </div>
        )}

        {isLoading ? (
          <Spinner />
        ) : (
          <div className={styles.entityList} role="listbox">
            {filtered.map((role) => {
              const assignmentCount =
                (role.assignedGroups?.length ?? 0) + (role.directUsers?.length ?? 0);
              return (
                <div
                  key={role.id}
                  className={
                    styles.entityItem +
                    (selectedId === role.id ? ' ' + styles.entityItemSelected : '')
                  }
                  role="option"
                  aria-selected={selectedId === role.id}
                  onClick={() => setSelectedId(role.id)}
                >
                  <Avatar name={role.name} size="sm" />
                  <div className={styles.entityInfo}>
                    <div className={styles.entityName}>
                      {role.name}
                      {role.system && <Badge label="system" variant="outlined" />}
                    </div>
                    <div className={styles.entityMeta}>
                      {role.description || '—'} · {assignmentCount} assignment
                      {assignmentCount !== 1 ? 's' : ''}
                    </div>
                    {((role.assignedGroups?.length ?? 0) > 0 ||
                      (role.directUsers?.length ?? 0) > 0) && (
                      <div className={styles.entityTags}>
                        {(role.assignedGroups ?? []).map((g) => (
                          <Tag key={g.id} label={g.name} color="success" />
                        ))}
                        {(role.directUsers ?? []).map((u) => (
                          <Tag key={u.userId} label={u.displayName} />
                        ))}
                      </div>
                    )}
                  </div>
                </div>
              );
            })}
          </div>
        )}
      </div>

      {/* Right pane — detail */}
      <div className={styles.detailPane}>
        {!selectedId ? (
          <div className={styles.emptyDetail}>Select a role to view details</div>
        ) : detailLoading || !detail ? (
          <Spinner />
        ) : (
          <RoleDetailPanel
            role={detail}
            onDeleteRequest={() => setConfirmDelete(true)}
          />
        )}
      </div>

      {detail && (
        <ConfirmDialog
          open={confirmDelete}
          onClose={() => setConfirmDelete(false)}
          onConfirm={handleDelete}
          title="Delete role"
          message={`Delete role "${detail.name}"? This cannot be undone.`}
          confirmText={detail.name}
          confirmLabel="Delete"
          variant="danger"
          loading={deleteRole.isPending}
        />
      )}
    </div>
  );
}

// ── Detail panel ──────────────────────────────────────────────────────────────

interface RoleDetailPanelProps {
  role: RoleDetail;
  onDeleteRequest: () => void;
}

function RoleDetailPanel({ role, onDeleteRequest }: RoleDetailPanelProps) {
  // Build a set of directly-assigned user IDs for distinguishing inherited principals
  const directUserIds = new Set((role.directUsers ?? []).map((u) => u.userId));

  return (
    <div>
      {/* Header */}
      <div className={styles.detailHeader}>
        <Avatar name={role.name} size="md" />
        <div style={{ flex: 1 }}>
          <div style={{ fontWeight: 700, fontSize: 16 }}>{role.name}</div>
          {role.description && (
            <div style={{ fontSize: 12, color: 'var(--text-muted)', marginTop: 2 }}>
              {role.description}
            </div>
          )}
        </div>
        <Button
          variant="danger"
          size="sm"
          disabled={role.system}
          onClick={onDeleteRequest}
        >
          Delete
        </Button>
      </div>

      {/* Metadata */}
      <div className={styles.metaGrid}>
        <span className={styles.metaLabel}>ID</span>
        <MonoText size="xs">{role.id}</MonoText>

        <span className={styles.metaLabel}>Scope</span>
        <span>{role.scope || '—'}</span>

        <span className={styles.metaLabel}>Type</span>
        <span>{role.system ? 'System role (read-only)' : 'Custom role'}</span>
      </div>

      {/* Assigned to groups */}
      <div className={styles.sectionTitle}>Assigned to groups</div>
      <div className={styles.sectionTags}>
        {(role.assignedGroups ?? []).length === 0 ? (
          <span style={{ fontSize: 12, color: 'var(--text-muted)' }}>None</span>
        ) : (
          (role.assignedGroups ?? []).map((g) => (
            <Tag key={g.id} label={g.name} color="success" />
          ))
        )}
      </div>

      {/* Assigned to users (direct) */}
      <div className={styles.sectionTitle}>Assigned to users (direct)</div>
      <div className={styles.sectionTags}>
        {(role.directUsers ?? []).length === 0 ? (
          <span style={{ fontSize: 12, color: 'var(--text-muted)' }}>None</span>
        ) : (
          (role.directUsers ?? []).map((u) => (
            <Tag key={u.userId} label={u.displayName} />
          ))
        )}
      </div>

      {/* Effective principals */}
      <div className={styles.sectionTitle}>Effective principals</div>
      <div className={styles.sectionTags}>
        {(role.effectivePrincipals ?? []).length === 0 ? (
          <span style={{ fontSize: 12, color: 'var(--text-muted)' }}>None</span>
        ) : (
          (role.effectivePrincipals ?? []).map((u) => {
            const isDirect = directUserIds.has(u.userId);
            return isDirect ? (
              <Badge key={u.userId} label={u.displayName} variant="filled" />
            ) : (
              <Badge
                key={u.userId}
                label={`↑ ${u.displayName}`}
                variant="dashed"
              />
            );
          })
        )}
      </div>
      {(role.effectivePrincipals ?? []).some((u) => !directUserIds.has(u.userId)) && (
        <div className={styles.inheritedNote}>
          Dashed entries inherit this role through group membership
        </div>
      )}
    </div>
  );
}
