import { ContactsApi } from '../../api/contactsApi';
import { ContactDetails, PhoneNumber } from '../../model';
import config from '../config';

describe('Test suite', () => {
  let contactsApi;
  let contactId;  
  let emailId;
  const generateRandomEmail = () => {
    const randomNum = Math.floor(1000 + Math.random() * 9000); 
    return `sdktesting${randomNum}@syncfusion.com`;
  };
  beforeAll(() => {
    contactId = 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");
    }
    emailId = generateRandomEmail();
    contactsApi = new ContactsApi(baseUrl);
    contactsApi.setApiKey(apiKey);
    console.log(`Generated email: ${emailId}`);
  });
test('Test1:should create a contact successfully', async () => {
    const contactDetails = new ContactDetails();
    contactDetails.name = "sdktesting";
    contactDetails.email = emailId;
    contactDetails.jobTitle = "HR";
    contactDetails.companyName = "Syncfusion";
    const phoneNumber = new PhoneNumber();
    phoneNumber.countryCode = "+91";
    phoneNumber.number = "6381261236";
    contactDetails.phoneNumber = phoneNumber;
    const contact = [contactDetails];
    try {
      const createContactResponse = await contactsApi.createContact(contact);
      console.log("Contact created successfully:", createContactResponse.createdContacts);
      contactId = createContactResponse.createdContacts[0].id;
      console.log("Created Contact ID: ", contactId);
    } catch (error:any) {
      console.error("Error occurred while calling the API:", error.message);
      throw new Error("API call failed");
    }
  }, 20000);
  test('Test2:should create a contact successfully only with required fields', async () => {
    const contactDetails = new ContactDetails();
    contactDetails.name = "sdktesting";
    contactDetails.email = emailId + String(45);
    const contact = [contactDetails];
    try {
      const createContactResponse = await contactsApi.createContact(contact);
      console.log("Contact created successfully:", createContactResponse.createdContacts);
      contactId = createContactResponse.createdContacts[0].id;
      console.log("Created Contact ID: ", contactId);
      expect(createContactResponse).toBeDefined();
    } catch (error) {
      console.error("Error occurred while calling the API:", error);
      expect(error).toBeUndefined();
    }
  }, 20000);
  test('Test3:should fail to create a contact with invalid email', async () => {
    const contactDetails = new ContactDetails();
    contactDetails.name = "sdktesting82";
    contactDetails.email = "invalid-email";
    contactDetails.jobTitle = "Developer";
    contactDetails.companyName = "CubeFlakes";
    const phoneNumber = new PhoneNumber();
    phoneNumber.countryCode = "+91";
    phoneNumber.number = "6381261236";
    contactDetails.phoneNumber = phoneNumber;
    const contact = [contactDetails];
    try {
      const createContactResponse = await contactsApi.createContact(contact);
      console.log("Contacts created successfully:", createContactResponse.createdContacts);
      expect(createContactResponse.createdContacts).toBeUndefined();
    } catch (error:any) {
      console.error("Error occurred while calling the API:", error.message);
      expect(error.message).toBeDefined();
    }
  }, 20000);
  test('Test4:should update a contact successfully', async () => {
    const updatedContactDetails = new ContactDetails();
    updatedContactDetails.name = "Test_Engineer";
    updatedContactDetails.email = emailId;
    updatedContactDetails.jobTitle = "Tester";
    updatedContactDetails.companyName = "Flakes";
    const updatedPhoneNumber = new PhoneNumber();
    updatedPhoneNumber.countryCode = "+91";
    updatedPhoneNumber.number = "8807799764";
    updatedContactDetails.phoneNumber = updatedPhoneNumber;
    try {
      const updateContactResponse = await contactsApi.updateContact(contactId, updatedContactDetails);
      console.log("Contact updated successfully:", updateContactResponse);
      expect(updateContactResponse).toBeDefined();
    } catch (error:any) {
      console.log("Error occurred while updating the contact:", error.message);
    }
  }, 20000);
  test('Test5:should fail to update contact due to missing required field (email)', async () => {
    const contactDetails = new ContactDetails();
    contactDetails.name = "TestEngineer";
    contactDetails.email = "";
    contactDetails.jobTitle = "Tester";
    contactDetails.companyName = "Flakes";
    const phoneNumber = new PhoneNumber();
    phoneNumber.countryCode = "+91";
    phoneNumber.number = "6381261236";
    contactDetails.phoneNumber = phoneNumber;
    try {
      const updateContactResponse = await contactsApi.updateContact(contactId, contactDetails);
      console.log("Unexpected success:", updateContactResponse);
      expect(updateContactResponse).toBeDefined();
    } catch (error:any) {
      console.error("Error occurred while calling the API:", error.message);
      expect(error.message).toBeDefined();
    }
  }, 20000);
  test('Test6:should fail to update contact due to invalid contact ID', async () => {
    const contactDetails = new ContactDetails();
    contactDetails.name = "Test_Engineer";
    contactDetails.email = "test1705@gmail.com";
    contactDetails.jobTitle = "Tester";
    contactDetails.companyName = "Flakes";
    const phoneNumber = new PhoneNumber();
    phoneNumber.countryCode = "+91";
    phoneNumber.number = "6381261236";
    contactDetails.phoneNumber = phoneNumber;
    try {
      const updateContactResponse = await contactsApi.updateContact("NON_EXISTENT_CONTACT_ID", contactDetails);
      console.log("Unexpected success:", updateContactResponse);
      expect(updateContactResponse).toBeDefined();
    } catch (error:any) {
      console.error("Error occurred while calling the API:", error.message);
      expect(error.message).toBeDefined();
    }
  }, 20000);
  test('Test7:should retrieve contact details successfully', async () => {
    try {
      const contactDetailsResponse = await contactsApi.getContact(contactId);
      console.log("Contact details retrieved successfully:", contactDetailsResponse);
      expect(contactDetailsResponse).toBeDefined();
      expect(contactDetailsResponse.id).toBe(contactId);
    } catch (error:any) {
      console.error("Error occurred while calling the API:", error.message);
      throw new Error("API call failed");
    }
  },20000);
  test('Test8:should return error for invalid contact ID in get contact', async () => {
    const invalidContactId = "INVALID_CONTACT_ID";
    try {
      const contactDetailsResponse = await contactsApi.getContact(invalidContactId);
      console.log("Unexpected success:", contactDetailsResponse);
      fail("API should not have succeeded with an invalid contact ID");
    } catch (error:any) {
      console.error("Expected error occurred while calling the API:", error.message);
      expect(error.message).toBeDefined();
    }
  },20000);
  test('Test9:should delete a contact successfully', async () => {
    try {
      const deleteResponse = await contactsApi.deleteContacts(contactId);
      console.log("Contact deleted successfully:", deleteResponse);
      expect(deleteResponse).toBeDefined();
      expect(deleteResponse.success).toBe(true);
    } catch (error:any) {
      console.log("Error occurred while calling the API:", error.message);
    }
  },20000);
  test('Test10:should fail to delete a contact with an invalid contact ID', async () => {
    const invalidContactId = "INVALID_CONTACT_ID";
    try {
      const deleteResponse = await contactsApi.deleteContacts(invalidContactId);
      console.error("Unexpected success response:", deleteResponse);
      throw new Error("Expected error, but the API call was successful.");
    } catch (error:any) {
      console.log("Error occurred as expected while calling the API:", error.message);
      expect(error.message).toBeDefined();
    }
  },20000);
  test('Test11:should retrieve contact list successfully', async () => {
    const page = 1;
    const pageSize = 10;
    try {
      const contactListResponse = await contactsApi.contactUserList(page, pageSize);
      console.log("Contact list retrieved successfully:", contactListResponse);
      expect(contactListResponse).toBeDefined();
      expect(contactListResponse.contacts).toBeDefined();
      expect(contactListResponse.contacts.length).toBeGreaterThan(0);
      expect(contactListResponse.page).toBe(page);
      expect(contactListResponse.pageSize).toBe(pageSize);
    } catch (error:any) {
      console.log("Error occurred while calling the API:", error.message);
    }
  },20000);
  test('Test12:should fail to retrieve contact list with invalid page', async () => {
    const page = -1;
    const pageSize = 10;
    try {
      const contactListResponse = await contactsApi.contactUserList(page, pageSize);
      console.log("Contact list retrieved unexpectedly:", contactListResponse);
      throw new Error("API call should have failed due to invalid pagination parameters");
    } catch (error:any) {
      console.error("Expected error occurred while calling the API:", error.message);
      expect(error.message).toBeDefined();
    }
  },20000);
  test('Test13:should fail to retrieve contact list with invalid page size', async () => {
    const page = 1;
    const pageSize = -10;
    try {
      const contactListResponse = await contactsApi.contactUserList(page, pageSize);
      throw new Error("API call should have failed due to invalid pagination parameters");
    } catch (error:any) {
      console.error("Expected error occurred while calling the API:", error);
      expect(error).toBeDefined();
      expect(error.response).toBeDefined();
      expect(error.response.status).toBe(400);
    }
  },20000);
});