public with sharing class AppraiserCaseDocGenService {
    public class DeficiencyDTO {
        @AuraEnabled public String deficiencyNumber;
        @AuraEnabled public String description;
        @AuraEnabled public String resolution;
        @AuraEnabled public Decimal sortOrder;
    }

    public class AppraiserCasePayload {
        @AuraEnabled public Id caseId;
        @AuraEnabled public String appraiserCaseNumber;
        @AuraEnabled public Date appraiserFieldReviewDate;
        @AuraEnabled public String propertyStreet;
        @AuraEnabled public String propertyCity;
        @AuraEnabled public String propertyStateProvince;
        @AuraEnabled public String propertyPostalCode;
        @AuraEnabled public String propertyCountry;
        @AuraEnabled public String propertyAddressSingleLine;
        @AuraEnabled public List<DeficiencyDTO> deficiencies;
    }

    @AuraEnabled(cacheable=false)
    public static String buildPayloadJson(Id appraiserCaseId) {
        return JSON.serialize(buildPayload(appraiserCaseId));
    }

    public static AppraiserCasePayload buildPayload(Id appraiserCaseId) {
        Appraiser_Case__c appraiserCase = [
            SELECT Id,
                   Name,
                   Appraiser_Field_Review_Date__c,
                   Property_Street__c,
                   Property_City__c,
                   Property_State_Province__c,
                   Property_Postal_Code__c,
                   Property_Country__c,
                   (SELECT Id,
                           Name,
                           Deficiency_Number__c,
                           Description__c,
                           Resolution__c,
                           Sort_Order__c
                      FROM Appraiser_Deficiencies__r
                      ORDER BY Sort_Order__c ASC, CreatedDate ASC)
              FROM Appraiser_Case__c
             WHERE Id = :appraiserCaseId
             LIMIT 1
        ];

        AppraiserCasePayload payload = new AppraiserCasePayload();
        payload.caseId = appraiserCase.Id;
        payload.appraiserCaseNumber = appraiserCase.Name;
        payload.appraiserFieldReviewDate = appraiserCase.Appraiser_Field_Review_Date__c;
        payload.propertyStreet = appraiserCase.Property_Street__c;
        payload.propertyCity = appraiserCase.Property_City__c;
        payload.propertyStateProvince = appraiserCase.Property_State_Province__c;
        payload.propertyPostalCode = appraiserCase.Property_Postal_Code__c;
        payload.propertyCountry = appraiserCase.Property_Country__c;
        payload.propertyAddressSingleLine = buildAddress(appraiserCase);
        payload.deficiencies = new List<DeficiencyDTO>();

        for (Appraiser_Deficiency__c deficiency : appraiserCase.Appraiser_Deficiencies__r) {
            DeficiencyDTO dto = new DeficiencyDTO();
            dto.deficiencyNumber = deficiency.Deficiency_Number__c;
            dto.description = deficiency.Description__c;
            dto.resolution = deficiency.Resolution__c;
            dto.sortOrder = deficiency.Sort_Order__c;
            payload.deficiencies.add(dto);
        }

        return payload;
    }

    private static String buildAddress(Appraiser_Case__c appraiserCase) {
        List<String> parts = new List<String>();
        if (String.isNotBlank(appraiserCase.Property_Street__c)) parts.add(appraiserCase.Property_Street__c);

        List<String> cityLine = new List<String>();
        if (String.isNotBlank(appraiserCase.Property_City__c)) cityLine.add(appraiserCase.Property_City__c);
        if (String.isNotBlank(appraiserCase.Property_State_Province__c)) cityLine.add(appraiserCase.Property_State_Province__c);
        if (String.isNotBlank(appraiserCase.Property_Postal_Code__c)) cityLine.add(appraiserCase.Property_Postal_Code__c);
        if (!cityLine.isEmpty()) parts.add(String.join(cityLine, ', '));

        if (String.isNotBlank(appraiserCase.Property_Country__c)) parts.add(appraiserCase.Property_Country__c);
        return String.join(parts, ' | ');
    }

    @AuraEnabled(cacheable=false)
    public static Map<String, Object> buildDocGenRequest(Id appraiserCaseId, String templateKey) {
        AppraiserCasePayload payload = buildPayload(appraiserCaseId);
        Map<String, Object> requestBody = new Map<String, Object>();
        requestBody.put('templateKey', templateKey);
        requestBody.put('recordId', appraiserCaseId);
        requestBody.put('sourceObject', 'Appraiser_Case__c');
        requestBody.put('mergeData', payload);
        return requestBody;
    }

    @AuraEnabled(cacheable=false)
    public static String buildDocGenRequestJson(Id appraiserCaseId, String templateKey) {
        return JSON.serialize(buildDocGenRequest(appraiserCaseId, templateKey));
    }
}
