import React from 'react';
import {
  Menu,
  ActionIcon,
  Button,
  Group,
  Text,
  Divider,
} from '@mantine/core';
import {
  IconDots,
  IconEdit,
  IconTrash,
  IconEye,
  IconCopy,
  IconDownload,
  IconShare,
  IconArchive,
  IconRestore,
  IconSettings,
  IconPlayerPlay,
  IconPlayerPause,
  IconPlayerStop,
  IconRefresh,
  TablerIconsProps,
} from '@tabler/icons-react';
import { modals } from '@mantine/modals';
import { notifications } from '@mantine/notifications';

export interface ActionMenuItem {
  key: string;
  label: string;
  icon?: React.ComponentType<TablerIconsProps>;
  color?: string;
  disabled?: boolean;
  hidden?: boolean;
  onClick: (item?: any) => void | Promise<void>;
  
  // Confirmation dialog for destructive actions
  confirm?: {
    title: string;
    message: string;
    confirmLabel?: string;
    cancelLabel?: string;
  };
  
  // Show/hide based on item properties
  show?: (item: any) => boolean;
}

export interface ActionMenuProps {
  item?: any; // The data item this menu is for
  actions: ActionMenuItem[];
  
  // Menu trigger customization
  trigger?: 'dots' | 'button' | 'custom';
  triggerLabel?: string;
  triggerIcon?: React.ComponentType<TablerIconsProps>;
  triggerProps?: any;
  customTrigger?: React.ReactNode;
  
  // Menu positioning
  position?: 'bottom-end' | 'bottom-start' | 'top-end' | 'top-start';
  
  // Menu styling
  withArrow?: boolean;
  withinPortal?: boolean;
  
  // Accessibility
  'aria-label'?: string;
}

const ActionMenu: React.FC<ActionMenuProps> = ({
  item,
  actions,
  trigger = 'dots',
  triggerLabel = 'Actions',
  triggerIcon: TriggerIcon = IconDots,
  triggerProps = {},
  customTrigger,
  position = 'bottom-end',
  withArrow = false,
  withinPortal = true,
  'aria-label': ariaLabel,
}) => {
  // Filter actions based on show/hidden conditions
  const visibleActions = actions.filter(action => {
    if (action.hidden) return false;
    if (action.show && !action.show(item)) return false;
    return true;
  });

  // Group actions by type (with dividers)
  const groupedActions = groupActionsByType(visibleActions);

  // Don't render if no visible actions
  if (visibleActions.length === 0) {
    return null;
  }

  const handleActionClick = async (action: ActionMenuItem) => {
    try {
      // Show confirmation dialog for destructive actions
      if (action.confirm) {
        return new Promise<void>((resolve) => {
          modals.openConfirmModal({
            title: action.confirm!.title,
            children: (
              <Text size="sm">{action.confirm!.message}</Text>
            ),
            labels: { 
              confirm: action.confirm!.confirmLabel || 'Confirm', 
              cancel: action.confirm!.cancelLabel || 'Cancel' 
            },
            confirmProps: { color: action.color || 'red' },
            onConfirm: async () => {
              try {
                await action.onClick(item);
                resolve();
              } catch (error) {
                console.error(`Action ${action.key} failed:`, error);
                notifications.show({
                  title: 'Action Failed',
                  message: `Failed to ${action.label.toLowerCase()}`,
                  color: 'red',
                });
              }
            },
            onCancel: () => resolve(),
          });
        });
      } else {
        await action.onClick(item);
      }
    } catch (error) {
      console.error(`Action ${action.key} failed:`, error);
      notifications.show({
        title: 'Action Failed', 
        message: `Failed to ${action.label.toLowerCase()}`,
        color: 'red',
      });
    }
  };

  const renderTrigger = () => {
    if (customTrigger) {
      return customTrigger;
    }

    if (trigger === 'button') {
      return (
        <Button
          variant="light"
          size="xs"
          leftSection={<TriggerIcon size={16} />}
          {...triggerProps}
        >
          {triggerLabel}
        </Button>
      );
    }

    // Default dots trigger
    return (
      <ActionIcon
        variant="subtle"
        color="gray"
        size="sm"
        aria-label={ariaLabel || `${triggerLabel} menu`}
        {...triggerProps}
      >
        <TriggerIcon size={16} />
      </ActionIcon>
    );
  };

  const renderMenuItem = (action: ActionMenuItem) => {
    const IconComponent = action.icon;
    
    return (
      <Menu.Item
        key={action.key}
        leftSection={IconComponent && <IconComponent size={14} />}
        color={action.color}
        disabled={action.disabled}
        onClick={() => handleActionClick(action)}
      >
        {action.label}
      </Menu.Item>
    );
  };

  return (
    <Menu
      position={position}
      withArrow={withArrow}
      withinPortal={withinPortal}
    >
      <Menu.Target>
        {renderTrigger()}
      </Menu.Target>

      <Menu.Dropdown>
        {groupedActions.map((group, groupIndex) => (
          <React.Fragment key={groupIndex}>
            {group.map(renderMenuItem)}
            {groupIndex < groupedActions.length - 1 && <Menu.Divider />}
          </React.Fragment>
        ))}
      </Menu.Dropdown>
    </Menu>
  );
};

// Helper function to group actions by type for better UX
const groupActionsByType = (actions: ActionMenuItem[]): ActionMenuItem[][] => {
  const primaryActions: ActionMenuItem[] = [];
  const secondaryActions: ActionMenuItem[] = [];
  const destructiveActions: ActionMenuItem[] = [];

  actions.forEach(action => {
    if (action.color === 'red' || action.key.includes('delete') || action.key.includes('remove')) {
      destructiveActions.push(action);
    } else if (action.key.includes('edit') || action.key.includes('view') || action.key.includes('copy')) {
      primaryActions.push(action);
    } else {
      secondaryActions.push(action);
    }
  });

  const groups: ActionMenuItem[][] = [];
  if (primaryActions.length > 0) groups.push(primaryActions);
  if (secondaryActions.length > 0) groups.push(secondaryActions);
  if (destructiveActions.length > 0) groups.push(destructiveActions);

  return groups;
};

export default ActionMenu;

// Pre-built action creators for common operations
export const createViewAction = (onView: (item: any) => void): ActionMenuItem => ({
  key: 'view',
  label: 'View Details',
  icon: IconEye,
  onClick: onView,
});

export const createEditAction = (onEdit: (item: any) => void): ActionMenuItem => ({
  key: 'edit',
  label: 'Edit',
  icon: IconEdit,
  color: 'blue',
  onClick: onEdit,
});

export const createCopyAction = (onCopy: (item: any) => void): ActionMenuItem => ({
  key: 'copy',
  label: 'Duplicate',
  icon: IconCopy,
  onClick: onCopy,
});

export const createDeleteAction = (
  onDelete: (item: any) => void | Promise<void>,
  itemName = 'item'
): ActionMenuItem => ({
  key: 'delete',
  label: 'Delete',
  icon: IconTrash,
  color: 'red',
  onClick: onDelete,
  confirm: {
    title: 'Confirm Delete',
    message: `Are you sure you want to delete this ${itemName}? This action cannot be undone.`,
    confirmLabel: 'Delete',
    cancelLabel: 'Cancel',
  },
});

export const createArchiveAction = (onArchive: (item: any) => void): ActionMenuItem => ({
  key: 'archive',
  label: 'Archive',
  icon: IconArchive,
  color: 'orange',
  onClick: onArchive,
  confirm: {
    title: 'Archive Item',
    message: 'Are you sure you want to archive this item?',
  },
});

export const createRestoreAction = (onRestore: (item: any) => void): ActionMenuItem => ({
  key: 'restore',
  label: 'Restore',
  icon: IconRestore,
  color: 'green',
  onClick: onRestore,
});

// Context-specific action sets
export const getUserActions = (
  onEdit: (item: any) => void,
  onDelete: (item: any) => void,
  onViewDetails?: (item: any) => void
): ActionMenuItem[] => [
  ...(onViewDetails ? [createViewAction(onViewDetails)] : []),
  createEditAction(onEdit),
  createDeleteAction(onDelete, 'user'),
];

export const getApplicationActions = (
  onEdit: (item: any) => void,
  onDelete: (item: any) => void,
  onConfigure?: (item: any) => void
): ActionMenuItem[] => [
  createEditAction(onEdit),
  ...(onConfigure ? [{
    key: 'configure',
    label: 'Configure',
    icon: IconSettings,
    onClick: onConfigure,
  }] : []),
  createDeleteAction(onDelete, 'application'),
];

export const getFunctionActions = (
  onEdit: (item: any) => void,
  onDelete: (item: any) => void,
  onExecute?: (item: any) => void,
  onViewLogs?: (item: any) => void
): ActionMenuItem[] => [
  ...(onExecute ? [{
    key: 'execute',
    label: 'Execute',
    icon: IconPlayerPlay,
    color: 'green',
    onClick: onExecute,
  }] : []),
  ...(onViewLogs ? [{
    key: 'logs',
    label: 'View Logs',
    icon: IconEye,
    onClick: onViewLogs,
  }] : []),
  createEditAction(onEdit),
  createDeleteAction(onDelete, 'function'),
];

export const getTokenActions = (
  onRevoke: (item: any) => void,
  onCopy?: (item: any) => void,
  onRefresh?: (item: any) => void
): ActionMenuItem[] => [
  ...(onCopy ? [createCopyAction(onCopy)] : []),
  ...(onRefresh ? [{
    key: 'refresh',
    label: 'Refresh',
    icon: IconRefresh,
    onClick: onRefresh,
  }] : []),
  {
    key: 'revoke',
    label: 'Revoke',
    icon: IconPlayerStop,
    color: 'red',
    onClick: onRevoke,
    confirm: {
      title: 'Revoke Token',
      message: 'Are you sure you want to revoke this token? This action cannot be undone and will immediately disable the token.',
      confirmLabel: 'Revoke',
    },
  },
];