/***********************************************************************************************************
 * Name         : CA_RevertAccountToLeadHelper
 * Purpose      : Handles reverting CA Accounts to Lead records by converting them into Lead records,
 *                marking the Account and its Opportunities as reverted, and linking all related
 *                previously-reverted Accounts to the newly created Lead.
 **********************************************************************************************************/
public without sharing class CA_RevertAccountToLeadHelper {
    /**
     * Reverts a CA Account to a Lead by creating a corresponding Lead from its field data,
     * marking the Account and its Opportunities as reverted, and linking any previously
     * reverted Accounts (with the same Current_Account__c) to the new Lead.
     *
     * @param accountId The Id of the Account to revert. Must be a non-reverted CA Account.
     * @return The Id of the newly created Lead record.
     */
    @AuraEnabled
    public static ApexToLwcResponseWrapper revertToLead(Id accountId) {
        Savepoint sp = Database.setSavepoint();
        try {
            Set<String> acctFields = CA_Constants.ACCOUNT_LEAD_MAPPING.keySet();
            String selectFields = 'Id,' + String.join(new List<String>(acctFields), ',');

            String query =
                'SELECT Current_Account__c, ' +
                selectFields +
                ' FROM Account WHERE (Id = :accountId AND Is_Reverted_to_Lead__c = FALSE) OR Current_Account__c = :accountId';
            List<Account> allAccounts = (List<Account>) Database.query(query);
            Account currentAccount;
            for (Account acc : allAccounts) {
                if (acc.Id == accountId) {
                    currentAccount = acc;
                    break;
                }
            }

            if (currentAccount == null) {
                throw new AuraHandledException('Account already Reverted to Lead');
            }

            Lead newLead = new Lead(RecordTypeId = LeadTriggerHelper.CA_RECTYPE_ID);
            for (String field : acctFields) {
                newLead.put(CA_Constants.ACCOUNT_LEAD_MAPPING.get(field), currentAccount.get(field));
            }
            Database.DMLOptions dml = new Database.DMLOptions();
            dml.DuplicateRuleHeader.AllowSave = true;
            dml.OptAllOrNone = true;
            Database.insert(newLead, dml);
 
            Id newOwnerId = ConfigUtils.getConfigString(ConfigUtils.CA_REVERT_TO_LEAD_OWNER);
            for (Account acc : allAccounts) {
                acc.Is_Reverted_to_Lead__c = true;
                acc.Lead__c = newLead.Id;
                acc.CA_Ignore_Duplicate_Rules__c = Constants.YES;
                acc.OwnerId = newOwnerId;
            }

            TriggerControl.disableTrigger(AccountTriggerHandler.SELF);
            Database.update(allAccounts, dml);
            TriggerControl.enableTrigger(AccountTriggerHandler.SELF);

            List<Opportunity> opps = [SELECT Id FROM Opportunity WHERE AccountId = :accountId];
            for (Opportunity opp : opps) {
                opp.Is_Reverted_to_Lead__c = true;
                opp.OwnerId = newOwnerId;
            }

            TriggerControl.disableTrigger(OpportunityTriggerHandler.SELF);
            Database.update(opps, dml);
            TriggerControl.enableTrigger(OpportunityTriggerHandler.SELF);

            return new ApexToLwcResponseWrapper(newLead.Id, null);
        } catch (Exception ex) {
            Database.rollback(sp);
            ErrorLogger.logError(ex);
            return new ApexToLwcResponseWrapper(null, ex.getMessage());
        }
    }
}
