import { checkPostCode, setError } from '../../libs/httpServices';
import axios, { AxiosError } from 'axios';
import { AddressResponse } from '../../types/addressResponse';

jest.mock('axios')

describe('checkPostCode', () => {
  beforeEach(() => {
  })

  test('should return results when status is 200', async () => {
    const testData = [{
      "UPRN": "100110668168",
      "AddressLine1": "1 Mitford Gardens - Ineligible",
      "AddressLine2": "",
      "AddressLine3": "",
      "Town": "Stakeford, Choppington",
      "County": "Northumberland",
      "Postcode": "NE62 5YR"
    }];
    (axios.get as jest.Mock).mockResolvedValueOnce({ status: 200, data: testData });
    const result = await checkPostCode('aa123aa');
    expect(result.addresses).toEqual(testData);
  })

  test('Should set error in response when 500 response recieved from Address API', async () => {
    const expectedError = new Error('Something went wrong');
    (axios.get as jest.Mock).mockRejectedValueOnce(expectedError);
    const result = await checkPostCode('aa123aa');
    expect(result.error.status).toBe(500);
    expect(result.error.message).toBe('Something went wrong');
  })

})

// eslint-disable-next-line @typescript-eslint/no-explicit-any
describe('setStatusCode tests', () => {

  beforeEach(() => {
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    axios.isAxiosError = <T = any, D = any>(payload: any): payload is AxiosError<T, D> => {
      return (payload as AxiosError<T, D>).isAxiosError === true;
    };
  });

  afterEach(() => {
    jest.clearAllMocks();
  });

  test('should set axios status code 404 based on axios error response', () => {
    const error = {
      isAxiosError: true,
      status: 404,
      response: { status: 404 }
    } as Partial<AxiosError>;

    const res = {} as AddressResponse;

    setError(error as AxiosError, res);

    expect(res.error.status).toBe(404)
  });

  test('should set status code to 500 if there is no response', () => {
    const error: Partial<AxiosError> = { isAxiosError: true };
    const res = {} as AddressResponse;
    setError(error as AxiosError, res);
    expect(res.error.status).toBe(500);
  });

  test('Should set error code 500 for non axios errors', () => {
    const error = new Error('Test error');
    const res = {} as AddressResponse;
    setError(error, res);
    expect(res.error.status).toBe(500);
    expect(res.error.message).toBe('Test error')
  });
});