/**
 * @description Test class for DocusignCompositeEnvelopeBuilder (dfsle Apex Toolkit)
 * @author Paul Huliganga
 * @date 2026-02-25
 */
@isTest
private class DocusignCompositeEnvelopeBuilderTest {
    
    @isTest
    static void testSuccessfulCompositeEnvelope() {
        // Arrange
        dfsle.TestUtils.setMock(new dfsle.ESignatureAPIMock());
        
        DocusignEnvelopeRequest req = new DocusignEnvelopeRequest();
        req.templateIds = new List<String>{
            '01234567-abcd-ef01-2345-6789abcdef01',
            '01234567-abcd-ef01-2345-6789abcdef02',
            '01234567-abcd-ef01-2345-6789abcdef03'
        };
        req.recordId = '001000000ABC123';
        req.language = 'en';
        req.emailSubject = 'Please sign these forms';
        
        // Act
        Test.startTest();
        List<DocusignEnvelopeResult> results = 
            DocusignCompositeEnvelopeBuilder.sendCompositeEnvelope(
                new List<DocusignEnvelopeRequest>{req}
            );
        Test.stopTest();
        
        // Assert
        System.assertEquals(1, results.size(), 'Should return 1 result');
        System.assertEquals(true, results[0].success, 'Should be successful');
        System.assertNotEquals(null, results[0].envelopeId, 'Should have envelope ID');
        System.assertEquals(null, results[0].errorMessage, 'Should have no error');
    }
    
    @isTest
    static void testSingleTemplate() {
        // Arrange
        dfsle.TestUtils.setMock(new dfsle.ESignatureAPIMock());
        
        DocusignEnvelopeRequest req = new DocusignEnvelopeRequest();
        req.templateIds = new List<String>{'01234567-abcd-ef01-2345-6789abcdef01'};
        req.recordId = '001000000ABC123';
        
        // Act
        Test.startTest();
        List<DocusignEnvelopeResult> results = 
            DocusignCompositeEnvelopeBuilder.sendCompositeEnvelope(
                new List<DocusignEnvelopeRequest>{req}
            );
        Test.stopTest();
        
        // Assert
        System.assertEquals(true, results[0].success, 'Should succeed with 1 template');
    }
    
    @isTest
    static void testMaximumTemplates() {
        // Arrange
        dfsle.TestUtils.setMock(new dfsle.ESignatureAPIMock());
        
        List<String> templateIds = new List<String>();
        for (Integer i = 1; i <= 14; i++) {
            templateIds.add('01234567-abcd-ef01-2345-6789abcdef' + String.valueOf(i).leftPad(2, '0'));
        }
        
        DocusignEnvelopeRequest req = new DocusignEnvelopeRequest();
        req.templateIds = templateIds;
        req.recordId = '001000000ABC123';
        
        // Act
        Test.startTest();
        List<DocusignEnvelopeResult> results = 
            DocusignCompositeEnvelopeBuilder.sendCompositeEnvelope(
                new List<DocusignEnvelopeRequest>{req}
            );
        Test.stopTest();
        
        // Assert
        System.assertEquals(true, results[0].success, 'Should succeed with 14 templates');
    }
    
    @isTest
    static void testDuplicateTemplatesDeduped() {
        // Arrange
        dfsle.TestUtils.setMock(new dfsle.ESignatureAPIMock());
        
        DocusignEnvelopeRequest req = new DocusignEnvelopeRequest();
        req.templateIds = new List<String>{
            '01234567-abcd-ef01-2345-6789abcdef01',
            '01234567-abcd-ef01-2345-6789abcdef02',
            '01234567-abcd-ef01-2345-6789abcdef01'  // duplicate
        };
        req.recordId = '001000000ABC123';
        
        // Act
        Test.startTest();
        List<DocusignEnvelopeResult> results = 
            DocusignCompositeEnvelopeBuilder.sendCompositeEnvelope(
                new List<DocusignEnvelopeRequest>{req}
            );
        Test.stopTest();
        
        // Assert
        System.assertEquals(true, results[0].success, 'Should handle duplicates');
    }
    
    @isTest
    static void testNullRequest() {
        // Act
        Test.startTest();
        List<DocusignEnvelopeResult> results = 
            DocusignCompositeEnvelopeBuilder.sendCompositeEnvelope(null);
        Test.stopTest();
        
        // Assert
        System.assertEquals(false, results[0].success, 'Should fail with null request');
        System.assertEquals('No request provided', results[0].errorMessage, 'Should have error message');
    }
    
    @isTest
    static void testEmptyRequest() {
        // Act
        Test.startTest();
        List<DocusignEnvelopeResult> results = 
            DocusignCompositeEnvelopeBuilder.sendCompositeEnvelope(
                new List<DocusignEnvelopeRequest>()
            );
        Test.stopTest();
        
        // Assert
        System.assertEquals(false, results[0].success, 'Should fail with empty request');
    }
    
    @isTest
    static void testValidationNoTemplates() {
        // Arrange
        DocusignEnvelopeRequest req = new DocusignEnvelopeRequest();
        req.templateIds = new List<String>();
        req.recordId = '001000000ABC123';
        
        // Act
        Test.startTest();
        List<DocusignEnvelopeResult> results = 
            DocusignCompositeEnvelopeBuilder.sendCompositeEnvelope(
                new List<DocusignEnvelopeRequest>{req}
            );
        Test.stopTest();
        
        // Assert
        System.assertEquals(false, results[0].success, 'Should fail validation');
        System.assert(results[0].errorMessage.containsIgnoreCase('template'), 'Should mention templates');
    }
    
    @isTest
    static void testValidationTooManyTemplates() {
        // Arrange
        List<String> templateIds = new List<String>();
        for (Integer i = 1; i <= 15; i++) {
            templateIds.add('01234567-abcd-ef01-2345-6789abcdef' + String.valueOf(i).leftPad(2, '0'));
        }
        
        DocusignEnvelopeRequest req = new DocusignEnvelopeRequest();
        req.templateIds = templateIds;
        req.recordId = '001000000ABC123';
        
        // Act
        Test.startTest();
        List<DocusignEnvelopeResult> results = 
            DocusignCompositeEnvelopeBuilder.sendCompositeEnvelope(
                new List<DocusignEnvelopeRequest>{req}
            );
        Test.stopTest();
        
        // Assert
        System.assertEquals(false, results[0].success, 'Should fail validation');
        System.assert(results[0].errorMessage.contains('Maximum 14'), 'Should mention limit');
    }
    
    @isTest
    static void testValidationNoRecordId() {
        // Arrange
        DocusignEnvelopeRequest req = new DocusignEnvelopeRequest();
        req.templateIds = new List<String>{'01234567-abcd-ef01-2345-6789abcdef01'};
        req.recordId = '';
        
        // Act
        Test.startTest();
        List<DocusignEnvelopeResult> results = 
            DocusignCompositeEnvelopeBuilder.sendCompositeEnvelope(
                new List<DocusignEnvelopeRequest>{req}
            );
        Test.stopTest();
        
        // Assert
        System.assertEquals(false, results[0].success, 'Should fail validation');
        System.assert(results[0].errorMessage.contains('record ID'), 'Should mention record ID');
    }
    
    @isTest
    static void testValidationBlankTemplateId() {
        // Arrange
        DocusignEnvelopeRequest req = new DocusignEnvelopeRequest();
        req.templateIds = new List<String>{'01234567-abcd-ef01-2345-6789abcdef01', ''};
        req.recordId = '001000000ABC123';
        
        // Act
        Test.startTest();
        List<DocusignEnvelopeResult> results = 
            DocusignCompositeEnvelopeBuilder.sendCompositeEnvelope(
                new List<DocusignEnvelopeRequest>{req}
            );
        Test.stopTest();
        
        // Assert
        System.assertEquals(false, results[0].success, 'Should fail validation');
        System.assert(results[0].errorMessage.contains('blank'), 'Should mention blank');
    }
    
    @isTest
    static void testWithEmailSubject() {
        // Arrange
        dfsle.TestUtils.setMock(new dfsle.ESignatureAPIMock());
        
        DocusignEnvelopeRequest req = new DocusignEnvelopeRequest();
        req.templateIds = new List<String>{'01234567-abcd-ef01-2345-6789abcdef01'};
        req.recordId = '001000000ABC123';
        req.emailSubject = 'Custom: Please review and sign';
        
        // Act
        Test.startTest();
        List<DocusignEnvelopeResult> results = 
            DocusignCompositeEnvelopeBuilder.sendCompositeEnvelope(
                new List<DocusignEnvelopeRequest>{req}
            );
        Test.stopTest();
        
        // Assert
        System.assertEquals(true, results[0].success, 'Should succeed with custom subject');
    }
    
    @isTest
    static void testWithoutEmailSubject() {
        // Arrange
        dfsle.TestUtils.setMock(new dfsle.ESignatureAPIMock());
        
        DocusignEnvelopeRequest req = new DocusignEnvelopeRequest();
        req.templateIds = new List<String>{'01234567-abcd-ef01-2345-6789abcdef01'};
        req.recordId = '001000000ABC123';
        req.emailSubject = null;
        
        // Act
        Test.startTest();
        List<DocusignEnvelopeResult> results = 
            DocusignCompositeEnvelopeBuilder.sendCompositeEnvelope(
                new List<DocusignEnvelopeRequest>{req}
            );
        Test.stopTest();
        
        // Assert
        System.assertEquals(true, results[0].success, 'Should succeed without subject');
    }
}
