import { BrandingApi } from '../../api/brandingApi';
import * as sinon from 'sinon';

describe('BrandingApi Unit Test', () => {
    let brandingApiStub: sinon.SinonStubbedInstance<BrandingApi>;

    beforeEach(() => {
        brandingApiStub = sinon.createStubInstance(BrandingApi);
        brandingApiStub.createBrand = sinon.stub().resolves({ brandId: 'brand_id' });
        brandingApiStub.updateBrand = sinon.stub().resolves({
            success: true,
            message: 'Brand updated successfully',
        });
    });

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

    it('should mock and verify createBrand call', async () => {
        const mockBrandCreated = {
            brandId: 'brand_id',
        };

        const brandData = {
            brandName: "New Brand",
            brandLogo: Buffer.from("mock_logo_data"),
            backgroundColor: "#FFFFFF",
            buttonColor: "#000000",
            buttonTextColor: "#FFFFFF",
            emailDisplayName: "Brand Email",
            disclaimerDescription: "Disclaimer",
            disclaimerTitle: "Disclaimer Title",
            redirectUrl: "https://example.com",
            redirectUri: "https://example.com",
            isDefault: true,
            canHideTagLine: false,
            combineAuditTrail: true,
            excludeAuditTrailFromEmail: false,
            documentTimeZone: "UTC",
            completedEmailType: "email_type",
            emailSignedDocument: "email_signed_doc",
            showBuiltInFormFields: true,
            allowCustomFieldCreation: true,
            showSharedCustomFields: true,
            hideDecline: false,
            hideSave: false
        };

        const result = await brandingApiStub.createBrand(brandData);

        expect(result).toBeDefined();
        expect(result.brandId).toBe('brand_id');

        sinon.assert.calledOnceWithExactly(brandingApiStub.createBrand, brandData);
    });

    it('should mock and verify updateBrand call', async () => {
        const mockBrandUpdated = {
            success: true,
            message: 'Brand updated successfully',
        };

        const brandId = 'brand_id';
        const updatedBrandData = {
            name: 'Updated Corporate Theme',
            primaryColor: '#FF0000',
        };
        const result = await brandingApiStub.updateBrand(brandId, updatedBrandData);

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

        sinon.assert.calledOnceWithExactly(brandingApiStub.updateBrand, brandId, updatedBrandData);
    });

    it('should mock and verify listBrands call', async () => {
        const mockBrandList = [
            {
                brandId: 'brand_1',
                name: 'Brand One',
                primaryColor: '#FF0000',
            },
            {
                brandId: 'brand_2',
                name: 'Brand Two',
                primaryColor: '#00FF00',
            },
        ];

        brandingApiStub.listBrands = sinon.stub().resolves(mockBrandList);

        const result = await brandingApiStub.listBrands();

        expect(result).toBeDefined();
        expect(result.length).toBe(2);
        expect(result[0].brandId).toBe('brand_1');
        expect(result[0].name).toBe('Brand One');
        expect(result[0].primaryColor).toBe('#FF0000');

        sinon.assert.calledOnce(brandingApiStub.listBrands);
    });

    it('should mock and verify getBrand call', async () => {
        const brandId = 'brand_1';
        const mockBrandDetails = {
            brandId: 'brand_1',
            name: 'Brand One',
            primaryColor: '#FF0000',
            backgroundColor: '#FFFFFF',
            brandLogoUrl: 'https://example.com/logo.png',
        };

        brandingApiStub.getBrand = sinon.stub().resolves(mockBrandDetails);

        const result = await brandingApiStub.getBrand(brandId);

        expect(result).toBeDefined();
        expect(result.brandId).toBe('brand_1');
        expect(result.name).toBe('Brand One');
        expect(result.primaryColor).toBe('#FF0000');
        expect(result.backgroundColor).toBe('#FFFFFF');
        expect(result.brandLogoUrl).toBe('https://example.com/logo.png');

        sinon.assert.calledOnceWithExactly(brandingApiStub.getBrand, brandId);
    });

    it('should mock and verify deleteBrand call', async () => {
        const brandId = 'brand_1';

        const mockDeleteResponse = {
            success: true,
            message: 'Brand deleted successfully',
        };
    
        brandingApiStub.deleteBrand = sinon.stub().resolves(mockDeleteResponse);
    
        const result = await brandingApiStub.deleteBrand(brandId);
    
        expect(result).toBeDefined();
        expect(result.success).toBe(true);
        expect(result.message).toBe('Brand deleted successfully');
    
        sinon.assert.calledOnceWithExactly(brandingApiStub.deleteBrand, brandId);
    });

    it('should mock and verify resetBrandSettingsToDefault call', async () => {
        const brandId = 'brand_1';

        const mockResetResponse = { success: true, message: 'Brand settings reset to default' };

        brandingApiStub.resetBrandSettingsToDefault = sinon.stub().resolves(mockResetResponse);

        const result = await brandingApiStub.resetBrandSettingsToDefault(brandId);

        expect(result).toBeDefined();
        expect(result.success).toBe(true);
        expect(result.message).toBe('Brand settings reset to default');

        sinon.assert.calledOnceWithExactly(brandingApiStub.resetBrandSettingsToDefault, brandId);
    });
});