import React, { createContext, useContext, useMemo, useCallback, ReactNode } from 'react';
import { useQuery, useQueryClient } from '@tanstack/react-query';
import { useAuth } from './AuthContext';
import { permissionsApi } from '../services/permissions';

interface PermissionContextType {
  permissions: Set<string>;
  maintenance: Record<string, boolean>;
  isAdmin: boolean;
  isLoading: boolean;
  hasPermission: (perm: string) => boolean;
  hasAnyPermission: (...perms: string[]) => boolean;
  isFeatureEnabled: (featureGroup: string) => boolean;
  refetch: () => void;
}

const PermissionContext = createContext<PermissionContextType | undefined>(undefined);

interface PermissionProviderProps {
  children: ReactNode;
}

export const PermissionProvider: React.FC<PermissionProviderProps> = ({ children }) => {
  const { isAuthenticated } = useAuth();
  const queryClient = useQueryClient();

  const { data, isLoading } = useQuery({
    queryKey: ['my-permissions'],
    queryFn: permissionsApi.getMyPermissions,
    enabled: isAuthenticated,
    staleTime: 5 * 60 * 1000,
  });

  const permissions = useMemo(
    () => new Set(data?.permissions ?? []),
    [data?.permissions]
  );

  const maintenance = data?.maintenance ?? {};
  const isAdmin = data?.isAdmin ?? false;

  const isFeatureEnabled = useCallback(
    (featureGroup: string): boolean => {
      if (isAdmin) return true;
      return !maintenance[featureGroup];
    },
    [isAdmin, maintenance]
  );

  const hasPermission = useCallback(
    (perm: string): boolean => {
      if (isAdmin) return true;
      const featureGroup = perm.split(':')[0];
      if (!isFeatureEnabled(featureGroup)) return false;
      return permissions.has(perm);
    },
    [isAdmin, permissions, isFeatureEnabled]
  );

  const hasAnyPermission = useCallback(
    (...perms: string[]): boolean => {
      return perms.some(p => hasPermission(p));
    },
    [hasPermission]
  );

  const refetch = useCallback(() => {
    queryClient.invalidateQueries({ queryKey: ['my-permissions'] });
  }, [queryClient]);

  const value = useMemo(
    (): PermissionContextType => ({
      permissions,
      maintenance,
      isAdmin,
      isLoading: isAuthenticated ? isLoading : false,
      hasPermission,
      hasAnyPermission,
      isFeatureEnabled,
      refetch,
    }),
    [permissions, maintenance, isAdmin, isAuthenticated, isLoading, hasPermission, hasAnyPermission, isFeatureEnabled, refetch]
  );

  return (
    <PermissionContext.Provider value={value}>
      {children}
    </PermissionContext.Provider>
  );
};

export const usePermissionContext = (): PermissionContextType => {
  const context = useContext(PermissionContext);
  if (context === undefined) {
    throw new Error('usePermissionContext must be used within a PermissionProvider');
  }
  return context;
};
