/***********************************************************************************************************
 * Name         : SnowflakeRelatedListHelper
 * Purpose      : Apex methods for snowflakeRelatedList lwc
 **********************************************************************************************************/
public with sharing class SnowflakeRelatedListHelper {
    private final static String FR_QUERY =
        'SELECT FR.CREATED_DATE AS \\"createdDate\\",' +
        ' FAN.ID AS \\"fanId\\",' +
        ' FR.ID AS \\"frId\\",' +
        ' FR.IS_DELETED AS \\"frIsDeleted\\",' +
        ' FR.DSP_C AS \\"frDsp\\",' +
        ' FR.EMAIL_C AS \\"frEmail\\",' +
        ' FAN.EMAIL_C AS \\"fanEmail\\",' +
        ' FORM.ID AS \\"formId\\",' +
        ' FORM.FORM_NAME_C AS \\"formName\\",' +
        ' FR.PROMO_ID_C AS \\"promoId\\",' +
        ' P.NAME AS \\"promoName\\",' +
        ' FORM.TLA_ID_C AS \\"tlaId\\",' +
        ' TLA.NAME AS \\"tlaName\\",' +
        ' FORM.FORM_TOOL_NAME_C AS \\"formToolName\\" FROM FORM_RESPONSE_C FR' +
        ' INNER JOIN FAN_C FAN' +
        ' ON FAN.ID = FR.FAN_ID_C' +
        ' INNER JOIN FORM_C FORM' +
        ' ON FR.FORM_ID_C = FORM.ID' +
        ' LEFT JOIN PROMOTION_C P' +
        ' ON FR.PROMO_ID_C = P.ID' +
        ' INNER JOIN TLA_C TLA' +
        ' ON TLA.ID = FORM.TLA_ID_C' +
        ' WHERE FAN.ID = \'$FANID$\'' +
        ' ORDER BY FR.CREATED_DATE DESC';

    @TestVisible
    private final static String FR_COLUMNS =
        '[' +
        '{ "label": "Deleted", "fieldName": "frIsDeleted", "type": "boolean", ' +
        '"initialWidth": 80, "cellAttributes": { "alignment": "center" }},' +
        '{ "label": "Form Response ID", "fieldName": "frId" },' +
        '{ "label": "Form Id", "fieldName": "formId", "type": "url", "typeAttributes": ' +
        '{ "label": { "fieldName": "formName" }, "target": "_blank"} },' +
        '{ "label": "Promo ID", "fieldName": "promoUrl", "type": "url", "typeAttributes": ' +
        '{ "label": { "fieldName": "promoName" }, "target": "_blank"} },' +
        '{ "label": "Source", "fieldName": "formToolName" },' +
        '{ "label": "Created Date", "fieldName": "createdDate", ' +
        '"initialWidth": 150, "cellAttributes": { "alignment": "center" }},' +
        '{ "label": "TLA ID", "fieldName": "tlaId", "type": "url", "typeAttributes": ' +
        '{ "label": { "fieldName": "tlaName" }, "target": "_blank"} },' +
        '{ "label": "DSP", "fieldName": "frDsp", "initialWidth": 100 }' +
        ']';

    private final static String SH_QUERY =
        'SELECT SH.ID AS \\"shId\\",' +
        ' SH.ACTION_C AS \\"shAction\\",' +
        ' SH.IS_DELETED AS \\"shIsDeleted\\",' +
        ' SH.UNSUB_REASON_C AS \\"shUnsubReason\\",' +
        ' SH.MAILING_LIST_ID_C AS \\"mlId\\",' +
        ' ML.MAILING_LIST_NAME_C AS \\"mlName\\",' +
        ' SH.SOURCE_C AS \\"shSource\\",' +
        ' SH.TLA_ID_C AS \\"tlaId\\",' +
        ' TLA.NAME AS \\"tlaName\\",' +
        ' SH.PROMO_ID_C AS \\"promoId\\",' +
        ' P.NAME AS \\"promoName\\",' +
        ' SH.CREATED_DATE AS \\"createdDate\\",' +
        ' T.TERRITORY_C AS \\"shTerritory\\",' +
        ' SH.DSP_C AS \\"shDsp\\",' +
        ' FROM SUBSCRIPTION_HISTORY_C SH' +
        ' INNER JOIN MAILING_LIST_C ML' +
        ' ON SH.MAILING_LIST_ID_C = ML.ID' +
        ' LEFT JOIN PROMOTION_C P' +
        ' ON SH.PROMO_ID_C = P.ID' +
        ' INNER JOIN TLA_C TLA' +
        ' ON TLA.ID = SH.TLA_ID_C' +
        ' INNER JOIN TL_C TL' +
        ' ON TL.ID = TLA.TL_ID_C' +
        ' INNER JOIN TERRITORY_C T' +
        ' ON TL.TERRITORY_ID_C = T.ID' +
        ' WHERE SH.FAN_ID_C = \'$FANID$\'' +
        ' ORDER BY SH.CREATED_DATE DESC';

    @TestVisible
    private final static String SH_COLUMNS =
        '[' +
        '{ "label": "Deleted", "fieldName": "shIsDeleted", "type": "boolean", ' +
        '"initialWidth": 80, "cellAttributes": { "alignment": "center" }},' +
        '{ "label": "Sub History ID", "fieldName": "shId" },' +
        '{ "label": "Action", "fieldName": "shAction", "cellAttributes": { "alignment": "center" }},' +
        '{ "label": "Unsub Reason", "fieldName": "shUnsubReason", ' +
        '"initialWidth": 100, "cellAttributes": { "alignment": "center" }},' +
        '{ "label": "Mailing List Id", "fieldName": "mlId", "type": "url", "typeAttributes": ' +
        '{ "label": { "fieldName": "mlName" }, "target": "_blank"} },' +
        '{ "label": "Source", "fieldName": "shSource" },' +
        '{ "label": "TLA ID", "fieldName": "tlaId", "type": "url", "typeAttributes": ' +
        '{ "label": { "fieldName": "tlaName" }, "target": "_blank"} },' +
        '{ "label": "Promo ID", "fieldName": "promoId", "type": "url", "typeAttributes": ' +
        '{ "label": { "fieldName": "promoName" }, "target": "_blank"} },' +
        '{ "label": "Created Date", "fieldName": "createdDate", ' +
        '"initialWidth": 150, "cellAttributes": { "alignment": "center" }},' +
        '{ "label": "Territory", "fieldName": "shTerritory" },' +
        '{ "label": "DSP", "fieldName": "shDsp", "initialWidth": 100 }' +
        ']';

    /**
     * @description Retrieves Fan related records from Snowflake
     * @param  recordId     Fan Id
     * @param  sObjectType  SObject whose Related List should be created
     * @return SnowflakeRelatedListWrapper  wrapper containing the columns and data related to the Related List
     */
    @AuraEnabled
    public static SnowflakeRelatedListWrapper getRecords(String recordId, String sObjectType) {
        String query;
        String columns;
        switch on sObjectType {
            when 'Subscription_History__c' {
                query = SH_QUERY;
                columns = SH_COLUMNS;
            }
            when else {
                query = FR_QUERY;
                columns = FR_COLUMNS;
            }
        }
        NodeJsHelper.DecryptedResponseWrapper result = NodeJsHelper.performQuery(query.replace('$FANID$', recordId));
        return new SnowflakeRelatedListWrapper(result, columns);
    }

    public class SnowflakeRelatedListWrapper {
        @AuraEnabled
        public String columns;
        @AuraEnabled
        public Integer count;
        @AuraEnabled
        public List<Map<String, Object>> rows;

        public SnowflakeRelatedListWrapper(
            NodeJsHelper.DecryptedResponseWrapper decryptedResponseWrapper,
            String columns
        ) {
            this.count = decryptedResponseWrapper.count;
            this.rows = decryptedResponseWrapper.rows;
            this.columns = columns;
            formatDates();
        }

        private void formatDates() {
            for (Map<String, Object> row : this.rows) {
                String snowflakeTimestampWithTZ = String.valueOf(row.get('createdDate'));
                if (!snowflakeTimestampWithTZ.endsWith('.000 +0000')) {
                    continue;
                }
                String snowflakeTimestamp = snowflakeTimestampWithTZ.split('\\.')[0];
                String[] datetimeParts = snowflakeTimestamp.split(' ');
                String[] dateValue = datetimeParts[0].split('-');
                String[] timeValue = datetimeParts[1].split(':');
                Datetime utcDate = Datetime.newInstanceGmt(
                    Integer.valueOf(dateValue[0]),
                    Integer.valueOf(dateValue[1]),
                    Integer.valueOf(dateValue[2]),
                    Integer.valueOf(timeValue[0]),
                    Integer.valueOf(timeValue[1]),
                    Integer.valueOf(timeValue[2])
                );
                row.put('createdDate', utcDate.format());
            }
        }
    }
}
