import { CustomFieldApi } from '../../api/customFieldApi';
import * as sinon from 'sinon';

describe('CustomFieldsApi Unit Test', () => {
    let customFieldsApiStub: sinon.SinonStubbedInstance<CustomFieldApi>;

    beforeEach(() => {
        customFieldsApiStub = sinon.createStubInstance(CustomFieldApi);

        // Create a plain object stub with required methods manually
        customFieldsApiStub.createCustomField = sinon.stub().resolves({ customFieldId: 'field_id' });
        customFieldsApiStub.updateCustomField = sinon.stub().resolves({
            success: true,
            message: 'Custom field updated successfully',
        });
    });

    afterEach(() => {
        sinon.restore();
    });

    it('should mock and verify createCustomField call', async () => {
        const customFieldData = {
            name: 'Employee ID',
            type: 'text',
            required: true,
            defaultValue: '12345',
        };

        const result = await customFieldsApiStub.createCustomField(customFieldData);

        expect(result).toBeDefined();
        expect(result.customFieldId).toBe('field_id');

        sinon.assert.calledOnceWithExactly(customFieldsApiStub.createCustomField, customFieldData);
    });

    it('should mock and verify updateCustomField call', async () => {
        const customFieldId = 'field_id';
        const updatedFieldData = {
            name: 'Updated Employee ID',
            type: 'text',
            required: false,
            defaultValue: '00000',
        };

        const result = await customFieldsApiStub.updateCustomField(customFieldId, updatedFieldData);

        expect(result).toBeDefined();
        expect(result.success).toBe(true);
        expect(result.message).toBe('Custom field updated successfully');

        sinon.assert.calledOnceWithExactly(customFieldsApiStub.updateCustomField, customFieldId, updatedFieldData);
    });

    it('should mock and verify listCustomFields call', async () => {
        const mockCustomFieldList = [
            {
                customFieldId: 'field_1',
                name: 'Employee ID',
                type: 'text',
                required: true,
                defaultValue: '12345',
            },
            {
                customFieldId: 'field_2',
                name: 'Department',
                type: 'select',
                required: false,
                defaultValue: 'HR',
            },
        ];

        customFieldsApiStub.listCustomFields = sinon.stub().resolves(mockCustomFieldList);

        const result = await customFieldsApiStub.listCustomFields();

        expect(result).toBeDefined();
        expect(result.length).toBe(2);
        expect(result[0].customFieldId).toBe('field_1');
        expect(result[0].name).toBe('Employee ID');
        expect(result[1].customFieldId).toBe('field_2');
        expect(result[1].name).toBe('Department');

        sinon.assert.calledOnce(customFieldsApiStub.listCustomFields);
    });

    it('should mock and verify deleteCustomField call', async () => {
        const mockDeleteResponse = {
            success: true,
            message: 'Custom field deleted successfully',
        };

        const customFieldId = 'field_1';

        customFieldsApiStub.deleteCustomField = sinon.stub().resolves(mockDeleteResponse);

        const result = await customFieldsApiStub.deleteCustomField(customFieldId);

        expect(result).toBeDefined();
        expect(result.success).toBe(true);
        expect(result.message).toBe('Custom field deleted successfully');

        sinon.assert.calledOnceWithExactly(customFieldsApiStub.deleteCustomField, customFieldId);
    });

    it('should mock and verify createEmbeddedCustomFieldUrl call', async () => {
        const customFieldId = 'field_id';

        const mockEmbeddedUrlResponse = {
            success: true,
            url: 'https://example.com/embedded/customfield/field_id',
        };
        customFieldsApiStub.createEmbeddedCustomFieldUrl = sinon.stub().resolves(mockEmbeddedUrlResponse);
        const result = await customFieldsApiStub.createEmbeddedCustomFieldUrl(customFieldId);

        expect(result).toBeDefined();
        expect(result.success).toBe(true);
        expect(result.url).toBe('https://example.com/embedded/customfield/field_id');

        sinon.assert.calledOnceWithExactly(customFieldsApiStub.createEmbeddedCustomFieldUrl, customFieldId);
    });
});