import { useState, useMemo, useEffect } from 'react';
import {
  Avatar,
  Badge,
  Button,
  Input,
  MonoText,
  SectionHeader,
  Tag,
  ConfirmDialog,
  SplitPane,
  EntityList,
  Spinner,
  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({ highlightId, onHighlightConsumed }: { highlightId?: string | null; onHighlightConsumed?: () => void }) {
  const { toast } = useToast();
  const { data: roles, isLoading } = useRoles();

  const [search, setSearch] = useState('');
  const [selectedId, setSelectedId] = useState<string | null>(null);
  const [creating, setCreating] = useState(false);
  const [deleteTarget, setDeleteTarget] = useState<RoleDetail | null>(null);

  // Auto-select highlighted item from cmd-k navigation
  useEffect(() => {
    if (highlightId && roles) {
      const match = roles.find((r) => r.id === highlightId);
      if (match) {
        setSelectedId(match.id);
        onHighlightConsumed?.();
      }
    }
  }, [highlightId, roles]); // eslint-disable-line react-hooks/exhaustive-deps

  // Create form state
  const [newName, setNewName] = useState('');
  const [newDesc, setNewDesc] = useState('');

  // Detail query
  const { data: detail, isLoading: detailLoading } = useRole(selectedId);

  // Mutations
  const createRole = useCreateRole();
  const deleteRole = useDeleteRole();

  const filtered = useMemo(() => {
    const list = roles ?? [];
    if (!search) return list;
    const q = search.toLowerCase();
    return list.filter(
      (r) =>
        r.name.toLowerCase().includes(q) ||
        r.description.toLowerCase().includes(q),
    );
  }, [roles, search]);

  const duplicateRoleName =
    newName.trim() !== '' &&
    (roles ?? []).some((r) => r.name === newName.trim().toUpperCase());

  function handleCreate() {
    if (!newName.trim()) return;
    createRole.mutate(
      { name: newName.trim().toUpperCase(), description: newDesc.trim() || undefined },
      {
        onSuccess: () => {
          toast({
            title: 'Role created',
            description: newName.trim().toUpperCase(),
            variant: 'success',
          });
          setCreating(false);
          setNewName('');
          setNewDesc('');
        },
        onError: () => {
          toast({ title: 'Failed to create role', variant: 'error', duration: 86_400_000 });
        },
      },
    );
  }

  function handleDelete() {
    if (!deleteTarget) return;
    deleteRole.mutate(deleteTarget.id, {
      onSuccess: () => {
        toast({
          title: 'Role deleted',
          description: deleteTarget.name,
          variant: 'warning',
        });
        if (selectedId === deleteTarget.id) setSelectedId(null);
        setDeleteTarget(null);
      },
      onError: () => {
        toast({ title: 'Failed to delete role', variant: 'error', duration: 86_400_000 });
        setDeleteTarget(null);
      },
    });
  }

  function getAssignmentCount(role: RoleDetail): number {
    return (
      (role.assignedGroups?.length ?? 0) + (role.directUsers?.length ?? 0)
    );
  }

  if (isLoading) return <Spinner size="md" />;

  return (
    <>
      <SplitPane
        list={
          <>
            {creating && (
              <div className={styles.createForm}>
                <Input
                  placeholder="Role name *"
                  value={newName}
                  onChange={(e) => setNewName(e.target.value)}
                />
                {duplicateRoleName && (
                  <span style={{ color: 'var(--error)', fontSize: 11 }}>
                    Role name already exists
                  </span>
                )}
                <Input
                  placeholder="Description"
                  value={newDesc}
                  onChange={(e) => setNewDesc(e.target.value)}
                />
                <div className={styles.createFormActions}>
                  <Button
                    size="sm"
                    variant="ghost"
                    onClick={() => setCreating(false)}
                  >
                    Cancel
                  </Button>
                  <Button
                    size="sm"
                    variant="primary"
                    onClick={handleCreate}
                    loading={createRole.isPending}
                    disabled={!newName.trim() || duplicateRoleName}
                  >
                    Create
                  </Button>
                </div>
              </div>
            )}

            <EntityList
              items={filtered}
              renderItem={(role) => (
                <>
                  <Avatar name={role.name} size="sm" />
                  <div className={styles.entityInfo}>
                    <div className={styles.entityName}>
                      {role.name}
                      {role.system && (
                        <Badge
                          label="system"
                          color="auto"
                          variant="outlined"
                          className={styles.providerBadge}
                        />
                      )}
                    </div>
                    <div className={styles.entityMeta}>
                      {role.description || '\u2014'} \u00b7{' '}
                      {getAssignmentCount(role)} assignments
                    </div>
                    <div className={styles.entityTags}>
                      {(role.assignedGroups ?? []).map((g) => (
                        <Badge key={g.id} label={g.name} color="success" />
                      ))}
                      {(role.directUsers ?? []).map((u) => (
                        <Badge
                          key={u.userId}
                          label={u.displayName}
                          color="auto"
                        />
                      ))}
                    </div>
                  </div>
                </>
              )}
              getItemId={(role) => role.id}
              selectedId={selectedId ?? undefined}
              onSelect={setSelectedId}
              searchPlaceholder="Search roles..."
              onSearch={setSearch}
              addLabel="+ Add role"
              onAdd={() => setCreating(true)}
              emptyMessage="No roles match your search"
            />
          </>
        }
        detail={
          selectedId && (detailLoading || !detail) ? (
            <Spinner size="md" />
          ) : detail ? (
            <RoleDetailPanel
              role={detail}
              onDeleteRequest={() => setDeleteTarget(detail)}
            />
          ) : null
        }
        emptyMessage="Select a role to view details"
      />

      <ConfirmDialog
        open={deleteTarget !== null}
        onClose={() => setDeleteTarget(null)}
        onConfirm={handleDelete}
        message={`Delete role "${deleteTarget?.name}"? This cannot be undone.`}
        confirmText={deleteTarget?.name ?? ''}
        loading={deleteRole.isPending}
      />
    </>
  );
}

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

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

function RoleDetailPanel({ role, onDeleteRequest }: RoleDetailPanelProps) {
  const directUserIds = new Set(
    (role.directUsers ?? []).map((u) => u.userId),
  );

  const assignedGroups = role.assignedGroups ?? [];
  const directUsers = role.directUsers ?? [];
  const effectivePrincipals = role.effectivePrincipals ?? [];

  return (
    <>
      <div className={styles.detailHeader}>
        <Avatar name={role.name} size="lg" />
        <div className={styles.detailHeaderInfo}>
          <div className={styles.detailName}>{role.name}</div>
          {role.description && (
            <div className={styles.detailEmail}>{role.description}</div>
          )}
        </div>
        {!role.system && (
          <Button size="sm" variant="danger" onClick={onDeleteRequest}>
            Delete
          </Button>
        )}
      </div>

      <div className={styles.metaGrid}>
        <span className={styles.metaLabel}>ID</span>
        <MonoText size="xs">{role.id}</MonoText>
        <span className={styles.metaLabel}>Scope</span>
        <span className={styles.metaValue}>{role.scope || '\u2014'}</span>
        {role.system && (
          <>
            <span className={styles.metaLabel}>Type</span>
            <span className={styles.metaValue}>System role (read-only)</span>
          </>
        )}
      </div>

      <SectionHeader>Assigned to groups</SectionHeader>
      <div className={styles.sectionTags}>
        {assignedGroups.map((g) => (
          <Tag key={g.id} label={g.name} color="success" />
        ))}
        {assignedGroups.length === 0 && (
          <span className={styles.inheritedNote}>(none)</span>
        )}
      </div>

      <SectionHeader>Assigned to users (direct)</SectionHeader>
      <div className={styles.sectionTags}>
        {directUsers.map((u) => (
          <Tag key={u.userId} label={u.displayName} color="auto" />
        ))}
        {directUsers.length === 0 && (
          <span className={styles.inheritedNote}>(none)</span>
        )}
      </div>

      <SectionHeader>Effective principals</SectionHeader>
      <div className={styles.sectionTags}>
        {effectivePrincipals.map((u) => {
          const isDirect = directUserIds.has(u.userId);
          return isDirect ? (
            <Badge
              key={u.userId}
              label={u.displayName}
              color="auto"
              variant="filled"
            />
          ) : (
            <Badge
              key={u.userId}
              label={u.displayName}
              color="auto"
              variant="dashed"
            />
          );
        })}
        {effectivePrincipals.length === 0 && (
          <span className={styles.inheritedNote}>(none)</span>
        )}
      </div>
      {effectivePrincipals.some((u) => !directUserIds.has(u.userId)) && (
        <span className={styles.inheritedNote}>
          Dashed entries inherit this role through group membership
        </span>
      )}
    </>
  );
}
