import React, { useState, useEffect } from 'react';
import {
  Stack,
  Group,
  Checkbox,
  Text,
  Box,
  Collapse,
  ActionIcon,
  Paper,
} from '@mantine/core';
import { IconChevronDown, IconChevronRight } from '@tabler/icons-react';

interface PermissionNode {
  id: string;
  label: string;
  description?: string;
  children?: PermissionNode[];
}

interface PermissionTreeProps {
  permissions: string[];
  onChange: (permissions: string[]) => void;
}

const permissionHierarchy: PermissionNode[] = [
  {
    id: 'app',
    label: 'Application',
    description: 'Access to application management',
    children: [
      {
        id: 'app.read',
        label: 'Read',
        description: 'Read application information',
      },
      {
        id: 'app.write',
        label: 'Write',
        description: 'Create and update applications',
      },
      {
        id: 'app.delete',
        label: 'Delete',
        description: 'Delete applications',
      },
    ],
  },
  {
    id: 'token',
    label: 'Token',
    description: 'Access to token management',
    children: [
      {
        id: 'token.read',
        label: 'Read',
        description: 'Read token information',
      },
      {
        id: 'token.create',
        label: 'Create',
        description: 'Create new tokens',
      },
      {
        id: 'token.revoke',
        label: 'Revoke',
        description: 'Revoke existing tokens',
      },
    ],
  },
  {
    id: 'repo',
    label: 'Repository',
    description: 'Access to repository operations',
    children: [
      {
        id: 'repo.read',
        label: 'Read',
        description: 'Read repository data',
      },
      {
        id: 'repo.write',
        label: 'Write',
        description: 'Write to repositories',
      },
      {
        id: 'repo.admin',
        label: 'Admin',
        description: 'Administrative access to repositories',
      },
    ],
  },
  {
    id: 'permission',
    label: 'Permission',
    description: 'Access to permission management',
    children: [
      {
        id: 'permission.read',
        label: 'Read',
        description: 'Read permission information',
      },
      {
        id: 'permission.write',
        label: 'Write',
        description: 'Create and update permissions',
      },
      {
        id: 'permission.grant',
        label: 'Grant',
        description: 'Grant permissions to tokens',
      },
      {
        id: 'permission.revoke',
        label: 'Revoke',
        description: 'Revoke permissions from tokens',
      },
    ],
  },
];

const PermissionTree: React.FC<PermissionTreeProps> = ({ permissions, onChange }) => {
  const [expandedNodes, setExpandedNodes] = useState<Set<string>>(new Set());

  // Expand all nodes by default
  useEffect(() => {
    const allParentIds = permissionHierarchy.map(node => node.id);
    setExpandedNodes(new Set(allParentIds));
  }, []);

  const toggleExpanded = (nodeId: string) => {
    setExpandedNodes(prev => {
      const newSet = new Set(prev);
      if (newSet.has(nodeId)) {
        newSet.delete(nodeId);
      } else {
        newSet.add(nodeId);
      }
      return newSet;
    });
  };

  const getNodeState = (node: PermissionNode): 'checked' | 'indeterminate' | 'unchecked' => {
    if (!node.children) {
      // For leaf nodes, check if they're explicitly selected
      return permissions.includes(node.id) ? 'checked' : 'unchecked';
    }

    // For parent nodes, check how many children are selected
    const checkedChildren = node.children.filter(child => 
      permissions.includes(child.id)
    );

    if (checkedChildren.length === 0) {
      return 'unchecked';
    } else if (checkedChildren.length === node.children.length) {
      return 'checked';
    } else {
      return 'indeterminate';
    }
  };

  const handleNodeChange = (node: PermissionNode, checked: boolean) => {
    let newPermissions = [...permissions];

    if (!node.children) {
      // Leaf node
      if (checked) {
        if (!newPermissions.includes(node.id)) {
          newPermissions.push(node.id);
        }
      } else {
        newPermissions = newPermissions.filter(p => p !== node.id);
      }
    } else {
      // Parent node - add/remove all child permissions individually
      if (checked) {
        // Add all child permissions
        node.children.forEach(child => {
          if (!newPermissions.includes(child.id)) {
            newPermissions.push(child.id);
          }
        });
      } else {
        // Remove all child permissions
        node.children.forEach(child => {
          newPermissions = newPermissions.filter(p => p !== child.id);
        });
      }
    }

    onChange(newPermissions);
  };

  const renderNode = (node: PermissionNode, depth = 0): React.ReactNode => {
    const state = getNodeState(node);
    const isExpanded = expandedNodes.has(node.id);
    const hasChildren = node.children && node.children.length > 0;

    return (
      <Box key={node.id}>
        <Paper
          p="xs"
          radius="sm"
          style={{
            border: '1px solid var(--mantine-color-gray-3)',
            marginBottom: '2px',
          }}
        >
          <Group gap="xs" wrap="nowrap" align="flex-start">
            {hasChildren ? (
              <ActionIcon
                variant="subtle"
                size="sm"
                onClick={() => toggleExpanded(node.id)}
                style={{ marginTop: '1px' }}
              >
                {isExpanded ? (
                  <IconChevronDown size={14} />
                ) : (
                  <IconChevronRight size={14} />
                )}
              </ActionIcon>
            ) : (
              <Box w={28} /> // Spacer for alignment
            )}
            
            <Checkbox
              checked={state === 'checked'}
              indeterminate={state === 'indeterminate'}
              onChange={(event) => handleNodeChange(node, event.currentTarget.checked)}
              size="sm"
              style={{ marginTop: '1px' }}
            />
            
            <Box style={{ flex: 1 }}>
              <Group gap="xs" wrap="nowrap">
                <Text 
                  size="sm" 
                  fw={hasChildren ? 600 : 500}
                >
                  {node.label}
                  {hasChildren && ' (all)'}
                </Text>
                {node.description && (
                  <Text 
                    size="xs" 
                    c="dimmed" 
                    style={{ whiteSpace: 'nowrap' }}
                  >
                    - {node.description}
                  </Text>
                )}
              </Group>
            </Box>
          </Group>
        </Paper>

        {hasChildren && (
          <Collapse in={isExpanded}>
            <Box pl="lg" mt="2px">
              <Stack gap="2px">
                {node.children!.map(child => renderNode(child, depth + 1))}
              </Stack>
            </Box>
          </Collapse>
        )}
      </Box>
    );
  };

  return (
    <Stack gap="xs">
      <Text size="sm" fw={500} mb="xs">
        Select permissions for this token
      </Text>
      {permissionHierarchy.map(node => renderNode(node))}
    </Stack>
  );
};

export default PermissionTree;