import { UserApi } from '../../api/userApi';
import { CreateUser } from '../../model';
import config from '../config';

describe('UsersTestcase', () => {
  let usersApi:UserApi;
  let createdUserId:any
  let emailId:any
  const generateRandomEmail = () => {
    const randomNum = Math.floor(1000 + Math.random() * 9000); 
    return `sdktesting${randomNum}@syncfusion.com`;
  };
  beforeAll(() => {
    createdUserId = null;
    emailId = null;
    const apiKey = config.apiKey;
    const baseUrl = config.baseUrl;
    if (!baseUrl || !apiKey) {
      throw new Error("Environment variables 'HOST_URL' or 'API_KEY' are not set.");
    }
    usersApi = new UserApi(baseUrl);
    usersApi.setApiKey(apiKey);
    emailId = generateRandomEmail();
    console.log(`Generated email: ${emailId}`);
  });
test('Test1:should create user successfully', async () => {
    const createUserRequest = new CreateUser();
    createUserRequest.emailId = emailId;
    createUserRequest.userRole = CreateUser.UserRoleEnum.Member;
    try {
        const response = await usersApi.createUser([createUserRequest]);
        console.log("User created successfully:", response);
        console.log("Created User ID:", createdUserId);
        expect(response).toBeDefined();
      } catch (error:any) {
        console.error("Error occurred while calling the API:", error.message);
        expect(error.message).toBeUndefined();
      }
  },20000);
  test('Test2:should retrieve list of users successfully', async () => {
    const page = 1;
    const pageSize = 20;
    const search = emailId;
    try {
      const response = await usersApi.listUsers(page, pageSize, search);
      console.log('Users list retrieved successfully:', response);
      const usersList = response?.result; 
      if (Array.isArray(usersList)) { 
        for (let user of usersList) {
          if (user.email === emailId) {
            createdUserId = String(user.userId);
            console.log("TestUserID: " + createdUserId);
            break;
          }
        }
      } else {
        console.error('Users list is not available or not an array.');
        throw new Error('Users list is invalid.');
      }
      expect(response).toBeDefined();
      console.log("Created User ID:", createdUserId);
    } catch (error:any) {
      console.error('Error occurred while retrieving users:', error.message);
      expect(error.message).toBeUndefined();
    }
  },20000);
  test('Test3:should fail to retrieve list of users with negative parameters', async () => {
    const page = -1;
    const pageSize = -10;
    const search = '';
    try {
      await usersApi.listUsers(page, pageSize, search);
      throw new Error('Expected API to fail with invalid parameters');
    } catch (error: any) {
      console.error('Error occurred while retrieving users:', error.message);
      expect(error.message).toBeDefined(); 
    }
  },20000);
  test('Test4:should fail to retrieve list of users with exceeded parameters', async () => {
    const page = 100;
    const pageSize = 10000;
    const search = '';
    try {
      await usersApi.listUsers(page, pageSize, search);
      throw new Error('Expected API to fail with invalid parameters');
    } catch (error: any) {
      console.error('Error occurred while retrieving users:', error);
      expect(error.response).toBeDefined();
      expect(error.response?.status).toBe(400);
      expect(error.response.statusText).toBe("Bad Request");
    }
  },20000);
  test('Test5:should return error while create user when invalid email is provided', async () => {
    const createUserRequest = new CreateUser();
    createUserRequest.emailId = "INVALID_EMAIL";
    try {
      await usersApi.createUser([createUserRequest]);
      throw new Error('Expected ApiException to be thrown due to invalid email ID');
    } catch (error:any) {
      console.log("Expected error occurred: " + error.message);
      expect(error.message).toBeDefined(); 
    }
  },20000);
  test('Test6:should return error while create user when empty email ID is provided', async () => {
    const createUserRequest = new CreateUser();
    createUserRequest.emailId = "";
    try {
      await usersApi.createUser([createUserRequest]);
      throw new Error("Expected API exception due to empty email ID");
    } catch (error:any) {
      console.log("Expected error occurred");
      expect(error.message).toBeDefined(); 
    }
  },20000);
  test('Test7:should return error while create user when already existing email is provided', async () => {
    const createUserRequest = new CreateUser();
    createUserRequest.emailId = emailId;
    try {
      await usersApi.createUser([createUserRequest]);
      throw new Error("Expected API exception due to empty email ID");
    } catch (error:any) {
      console.log("Expected error occurred");
      expect(error.response).toBeDefined();
      expect(error.response?.status).toBe(400);
      expect(error.response.statusText).toBe("Bad Request");
    }
  },20000);
  test('Test8:should return error while update user when invalid user ID is provided', async () => {
    const updateUserRequest = {
      userId: "INVALID_USERID"
    };
    try {
      await usersApi.updateUser(updateUserRequest);
      throw new Error('Expected error due to invalid user ID');
    } catch (error:any) {
      console.log('Expected error occurred: ' + error.message);
      expect(error.message).toBeDefined(); 
    }
  },20000);
  test('Test9:should retrieve user successfully', async () => {
    try {
      const response = await usersApi.getUser(createdUserId);
      console.log('User retrieved successfully:', response);
      expect(response).toBeDefined();
    } catch (error:any) {
      console.error("Error occurred while retrieving the user:", error.message);
    }  
  },20000);
  test('Test10:should return error while retrive user when invalid userId is provided', async () => {
    const userId = "INVALID_USERID";
    try {
      await usersApi.getUser(userId);
      throw new Error("Expected error due to invalid userId");
    } catch (error:any) {
      console.log("Expected error occurred: " + error.message);
      expect(error.response).toBeDefined(); 
      expect(error.response?.status).toBe(400); 
      expect(error.response.statusText).toBe("Bad Request");
    }
  },20000);
  test('Test11:should return error while retrive user when user id is empty', async () => {
    const userId = "";
    try {
      await usersApi.getUser(userId);
      throw new Error("Expected error due to invalid userId");
    } catch (error:any) {
      console.log("Expected error occurred: " + error.message);
      expect(error.response).toBeDefined();
      expect(error.response?.status).toBe(400);
      expect(error.response.statusText).toBe("Bad Request");
    }
  },20000);
  test('Test12:should return error while retrive user when invalid userId is provided', async () => {
    const userId = "INVALID_USERID";
    console.log("TestUserID: " + userId);
    try {
      await usersApi.getUser(userId);
      throw new Error("Expected error due to invalid userId");
    } catch (error:any) {
      console.log("Expected error occurred: " + error.message);
      expect(error.message).toBeDefined(); 
    }
  },20000);
  test('Test13: should resend invitation successfully', async () => {
    try {
      const response = await usersApi.resendInvitation(createdUserId);
      expect(response).toBeDefined(); 
      console.log('Invitation resent successfully!');
    } catch (error: any) {
      console.error('Error occurred while resending the invitation:', error.message);
      throw new Error('Invitation resend failed');
    }
  },20000);
  test('Test14:should fail to resend invitation with invalid user ID', async () => {
    const userId = "INVALID_USERID";
    try {
      await usersApi.resendInvitation(userId);
      throw new Error('Expected API to fail due to invalid user ID');
    } catch (error:any) {
      console.error('Error occurred while resending the invitation:', error.message);
      expect(error.message).toBeDefined();
    }
  },20000);
  test('Test15:should fail to resend invitation when user id is empty', async () => {
    const userId = "";
    try {
      await usersApi.resendInvitation(userId);
      throw new Error('Expected API to fail due to invalid user ID');
    } catch (error:any) {
      console.error('Error occurred while resending the invitation:', error);
      expect(error).toBeDefined();
      expect(error.response).toBeDefined(); 
      expect(error.response?.status).toBe(400); 
      expect(error.response.statusText).toBe("Bad Request");
    }
  },20000);
  test('Test16: should cancel invitation successfully', async () => {
    try {
      const response = await usersApi.cancelInvitation(createdUserId);
      expect(response).toBeDefined(); 
      console.log('Invitation canceled successfully!');
    } catch (error: any) {
      console.error('Error occurred while canceling the invitation:', error.message);
      expect(error.message).toBeUndefined();
    }
  },2000);
  test('Test17:should fail to cancel invitation due to invalid userId', async () => {
    const userId = "INVALID_USERID";
    try {
      await usersApi.cancelInvitation(userId);
      console.error('Unexpected success. Invitation should not have been canceled.');
      throw new Error('Test failed: Invitation should not have been canceled');
    } catch (error:any) {
      console.error('Expected error occurred while canceling the invitation:', error.message);
      expect(error.message).toBeDefined();
    }
  },20000);
  test('Test18:should fail to cancel invitation due to empty userId', async () => {
    const userId = "";
    try {
      await usersApi.cancelInvitation(userId);
      console.error('Unexpected success. Invitation should not have been canceled.');
      throw new Error('Test failed: Invitation should not have been canceled');
    } catch (error:any) {
      console.error('Expected error occurred while canceling the invitation', error);
      expect(error).toBeDefined();
      expect(error.response?.status).toBe(400); 
      expect(error.response.statusText).toBe("Bad Request");
    }
  },20000);
});