import { contextSrv } from 'app/core/core';
import { SavedQuery } from 'app/features/explore/QueryLibrary/types';

import { canEditQuery, canCreateQuery } from './identity';

// Mock contextSrv
jest.mock('app/core/core', () => ({
  contextSrv: {
    user: {
      uid: 'user123',
    },
    hasRole: jest.fn(),
    isEditor: true,
  },
}));

const mockContextSrv = jest.mocked(contextSrv);

describe('identity', () => {
  const mockQuery: SavedQuery = {
    uid: 'query1',
    datasourceName: 'Prometheus',
    datasourceRef: { type: 'prometheus', uid: 'prom1' },
    datasourceType: 'prometheus',
    createdAtTimestamp: 1716796800000,
    query: {
      refId: 'A',
      datasource: { type: 'prometheus', uid: 'prom1' },
    },
    queryText: 'http_requests_total',
    title: 'HTTP Requests',
    description: 'Monitor HTTP requests',
    isLocked: false,
    isVisible: true,
    user: {
      uid: 'user:user123',
      displayName: 'Current User',
    },
    tags: ['monitoring'],
  };

  beforeEach(() => {
    jest.clearAllMocks();
    mockContextSrv.user.uid = 'user123';
  });

  describe('canEditQuery', () => {
    it('should return true when user is the author and not a viewer', () => {
      mockContextSrv.hasRole.mockImplementation((role: string) => {
        if (role === 'Viewer') {
          return false;
        }
        if (role === 'Admin') {
          return false;
        }
        return false;
      });

      mockContextSrv.isEditor = true;
      const result = canEditQuery(mockQuery);

      expect(result).toBe(true);
      expect(mockContextSrv.hasRole).toHaveBeenCalledWith('Admin');
    });

    it('should return false when user is the author but is a viewer', () => {
      mockContextSrv.hasRole.mockImplementation((role: string) => {
        if (role === 'Viewer') {
          return true;
        }
        if (role === 'Admin') {
          return false;
        }
        return false;
      });

      mockContextSrv.isEditor = false;

      const result = canEditQuery(mockQuery);

      expect(result).toBe(false);
    });

    it('should return true when user is admin even if not the author', () => {
      mockContextSrv.hasRole.mockImplementation((role: string) => {
        if (role === 'Viewer') {
          return false;
        }
        if (role === 'Admin') {
          return true;
        }
        return false;
      });

      mockContextSrv.isEditor = true;

      const differentAuthorQuery: SavedQuery = {
        ...mockQuery,
        user: {
          uid: 'user:different-user',
          displayName: 'Different User',
        },
      };

      const result = canEditQuery(differentAuthorQuery);

      expect(result).toBe(true);
    });

    it('should return false when user is not the author and not admin', () => {
      mockContextSrv.hasRole.mockImplementation((role: string) => {
        if (role === 'Viewer') {
          return false;
        }
        if (role === 'Admin') {
          return false;
        }
        return false;
      });

      const differentAuthorQuery: SavedQuery = {
        ...mockQuery,
        user: {
          uid: 'user:different-user',
          displayName: 'Different User',
        },
      };

      const result = canEditQuery(differentAuthorQuery);

      expect(result).toBe(false);
    });
  });

  describe('canCreateQuery', () => {
    it('should return true when user is not a viewer', () => {
      mockContextSrv.hasRole.mockImplementation((role: string) => {
        if (role === 'Viewer') {
          return false;
        }
        return false;
      });

      const result = canCreateQuery();

      expect(result).toBe(true);
    });

    it('should return false when user is not an editor', () => {
      mockContextSrv.isEditor = false;
      const result = canCreateQuery();

      expect(result).toBe(false);
    });
  });
});
