/*
 * Author: Bubba Li
 * Created Date: 01/19/2022
 * Purpose: Utility class for describe layouts
 * Test Class: NewAndEditLeadController
 * History:
 *      01/19/2022 - Bubba Li - Initial Code.
 *
 * */
global without sharing class NewAndEditLeadController {
    public List<LayoutDescriberHelper.LayoutSection> layoutSections { get; set; }
    public String awsToken { get; set; }
    public static Map<String, Schema.SObjectType> schemaMap = Schema.getGlobalDescribe();
    public static String sobjectTypeValue = 'Lead';
    public Boolean isNewMode { get; set; }
    public Boolean isCloneMode { get; protected set; }
    public String rtTypeId { get; set; }
    public String AWSDataId { get; set; }
    public String AWSDataIdInquiryForm { get; set; }
    public String contactId { get; set; } //For Lookup field
    public List<String> encryptedAPIList { get; set; }
    public String staticResource { get; set; }
    public String staticResourceContact { get; set; }
    public String staticResourceInquiryForm { get; set; }
    public String requiredFieldAPIListStr { get; set; }
    public String fieldAPIToLabelMapStr { get; set; }
    public String Input_Required_Field_Msg { get; set; }
    public String PIPL_Name_Label { get; set; }
    public String PIPL_Input_Account_Error_Msg { get; set; }
    public String sobjectPrefix { get; set; }
    public String sobjecttypeForFrontEnd { get; set; }
    public String contactsInfo { get; set; } //key sfid;value awsid
    public Inquiry_form__c ifc { get; private set; }
    public String contactDataId { get; set; }
    public String layoutSectionsStr { get; set; }
    public String isDecryptContact { get; set; }
    public final string ApiPrefix { get; private set; } //Add By Li Jun 20220403
    public Map<string, string> AWSToSobjectEncryptedMap { get; private set; }
    public string AWSToSobjectEncryptedMapJson {
        get {
            return JSON.serialize(AWSToSobjectEncryptedMap);
        }
    }
    public String LeadCreatedDate { get; set; } // XLIU-CFE8M7 20220624 ssm
    public String VLookUpFieldsJson { get; private set; }
    //zhj MEBG新方案改造 2022-11-29 start
    public String staticResourceV2 { get; set; }
    //zhj MEBG新方案改造 2022-11-29 end

    public NewAndEditLeadController(ApexPages.StandardController controller) {
        ApiPrefix = 'PIBackApi';
        isDecryptContact = '0';
        isNewMode = true;
        isCloneMode = false;
        Input_Required_Field_Msg = Label.Input_Required_Field_Msg;
        PIPL_Name_Label = Label.PIPL_Name_Label;
        PIPL_Input_Account_Error_Msg = label.PIPL_Input_Account_Error_Msg;
        sobjecttypeForFrontEnd = sobjectTypeValue;
        Map<string, string> mso = ApexPages.currentPage().getParameters();
        if (mso != null && mso.containsKey('newclone')) {
            isCloneMode = true;
        }
        //获取所有字段
        List<String> fieldList = new List<String>(Schema.getGlobalDescribe().get('Lead').getDescribe().fields.getMap().keyset());
        // Add fields to controller. This is to avoid the SOQL error in visualforce page
        if (!Test.isRunningTest()) {
            controller.addFields(fieldList);
        }
        SObject obj = controller.getRecord();

        // XLIU-CFE8M7 20220624 ssm
        this.LeadCreatedDate = obj.get('CreatedDate') != null
            ? Date.newInstance(
                      ((Datetime) obj.get('CreatedDate')).year(),
                      ((Datetime) obj.get('CreatedDate')).month(),
                      ((Datetime) obj.get('CreatedDate')).day()
                  )
                  .format()
            : Date.today().format();
        // this.LeadCreatedDate = Date.today().format();

        if (ApexPages.currentPage().getParameters().get('CF00N1000000962np_lkid') != null) {
            System.debug('CF00N1000000962np_lkid');
            //产品咨询单过来的
            String InquiryFormId = ApexPages.currentPage().getParameters().get('CF00N1000000962np_lkid');
            ifc = [
                SELECT
                    Id,
                    AWS_Data_Id__c,
                    Contact_Name__c,
                    Contact_Id__c,
                    Hospital_Name__c,
                    Hospital_ID__c,
                    Department_Class__c,
                    Department_ID__c,
                    Opp_Name_Search__c,
                    Opp_Name_Search_ID__c,
                    Campaign__c,
                    Campaign_ID__c,
                    Name,
                    Cancel_Reason__c,
                    Phone__c,
                    Email__c,
                    Last_Name__c,
                    LeadSource__c,
                    Opportunity_Division__c,
                    Request1__c,
                    Urgent__c,
                    Inquiry_Num__c,
                    Product_Owner__c
                FROM Inquiry_form__c
                WHERE id = :InquiryFormId
            ];
            System.debug('ifc = ' + ifc);
            if (ifc.Contact_Id__c != null && ifc.Contact_Id__c != '') {
                Contact c = [
                    SELECT AWS_Data_Id__c
                    FROM Contact
                    WHERE id = :ifc.Contact_Id__c
                ];
                contactDataId = c.AWS_Data_Id__c;
            }
            AWSDataIdInquiryForm = ifc.AWS_Data_Id__c;
            System.debug('ifc = ' + ifc);
            rtTypeId = ApexPages.currentPage().getParameters().get('RecordType');
            obj.put('OwnerId', UserInfo.getUserId());
            obj.put('Inquiry_Num__c', ifc.Inquiry_Num__c); // 20220413 SWAG-CBUB2W you
            obj.put('owner_not_automatically_update__c', ifc.Product_Owner__c);
            controller.getRecord().put('LeadSource', ifc.LeadSource__c);
            // controller.getRecord().put('Lead_Inquiry_form__c', ifc.Id);
        } else if (obj.Id != null) {
            //更新
            isNewMode = false;
            Lead leadData = [
                SELECT Id, RecordTypeId, AWS_Data_Id__c, Contact_Name__r.Id, Contact_Name__r.AWS_Data_Id__c
                FROM Lead
                WHERE id = :obj.Id
            ];
            rtTypeId = leadData.RecordTypeId;
            AWSDataId = leadData.AWS_Data_Id__c;
            Map<String, String> sfIdToAWSIdMap = new Map<String, String>();
            if (leadData.Contact_Name__r.Id != null) {
                sfIdToAWSIdMap.put(String.valueof(leadData.Contact_Name__r.Id).subString(0, 15), leadData.Contact_Name__r.AWS_Data_Id__c);
            }
            contactsInfo = JSON.serialize(sfIdToAWSIdMap);
        } else {
            //看链接中有无带过来的参数(客户人员)
            // Map<string,string> mso = ApexPages.currentPage().getParameters();
            for (String key : mso.keySet()) {
                System.debug('key=' + key + ',value=' + mso.get(key));
            }
            //联系人
            if (mso.containsKey('CF00N10000006ps6f_lkid')) {
                isDecryptContact = '1';
                String contactId = mso.get('CF00N10000006ps6f_lkid');
                //查询AWS_Data_Id__c
                List<Contact> contactList = new List<Contact>([SELECT AWS_Data_Id__c FROM Contact WHERE id = :contactId]);
                Contact c = new Contact();
                if (contactList != null && contactList.size() > 0) {
                    c = contactList[0];
                }
                if (c != null && c.AWS_Data_Id__c != '') {
                    contactDataId = c.AWS_Data_Id__c;
                }
                //查询战略科室分类
                List<Contact> cs = [
                    SELECT Account.Department_Class__c
                    FROM Contact
                    WHERE id = :contactId
                ];
                if (cs.size() > 0) {
                    controller.getRecord().put('Department_Class__c', cs[0].Account.Department_Class__c);
                }
                controller.getRecord().put('Contact_Name__c', mso.get('CF00N10000006ps6f_lkid'));
            }
            //医院名
            if (mso.containsKey('CF00N10000002CvC5_lkid')) {
                controller.getRecord().put('Hospital_Name__c', mso.get('CF00N10000002CvC5_lkid'));
                //通过医院id查询战略科室分类
                String hospitalId = mso.get('CF00N10000002CvC5_lkid');
                List<Account> hospitalAccount = [
                    SELECT Department_Class__c
                    FROM Account
                    WHERE Id = :hospitalId
                ];
                if (hospitalAccount.size() > 0) {
                    List<Account> departmentAccount = [
                        SELECT Id
                        FROM Account
                        WHERE Id = :hospitalAccount[0].Department_Class__c
                    ];
                    if (departmentAccount.size() > 0) {
                        System.debug('Department_Class__c = ' + departmentAccount[0].Id);
                        controller.getRecord().put('Department_Class__c', departmentAccount[0].Id);
                    }
                }
            }
            //公司（科室）
            if (mso.containsKey('CF00N10000002CvC5')) {
                controller.getRecord().put('Company', mso.get('CF00N10000002CvC5'));
            }
            //战略科室CF00N10000006qNtt_lkid
            // if(mso.containsKey('CF00N10000006qNtt_lkid ')){
            //     controller.getRecord().put('Department_Class__c',mso.get('CF00N10000006qNtt_lkid '));
            // }
            // 2022-04-13 来源 jz start 0414 lt
            if (mso.containsKey('LeadSource')) {
                controller.getRecord().put('LeadSource', mso.get('LeadSource'));
            }
            if (mso.containsKey(System.Label.Opportunity_stage)) {
                controller.getRecord().put('Opportunity_stage__c', mso.get(System.Label.Opportunity_stage));
            }
            //20220505 lt 注释掉
            // if (mso.containsKey('00N10000006qOF0')) {
            //     controller.getRecord().put('Close_Forecasted_Date__c', Date.parse(mso.get('00N10000006qOF0')));
            // }
            if (mso.containsKey(System.Label.Opp_Name)) {
                controller.getRecord().put('Opp_Name__c', mso.get(System.Label.Opp_Name));
            }
            // if (mso.containsKey('00N100000048UBf')) {
            //     controller.getRecord().put('Contact__c', mso.get('00N100000048UBf'));
            // }
            if (mso.containsKey(System.Label.Purchase_Reason)) {
                controller.getRecord().put('Purchase_Reason__c', mso.get(System.Label.Purchase_Reason));
            }
            if (mso.containsKey(System.Label.Fund_Basis)) {
                controller.getRecord().put('Fund_Basis__c', mso.get(System.Label.Fund_Basis));
            }
            if (mso.containsKey(System.Label.Purchase_Type)) {
                controller.getRecord().put('Purchase_Type__c', mso.get(System.Label.Purchase_Type));
            }
            //20220427
            if (mso.containsKey(System.Label.Tender_information)) {
                //招标项目Id
                controller.getRecord().put('Tender_information__c', mso.get(System.Label.Tender_information));
            }
            if (mso.containsKey(System.Label.Agency_Opportunity)) {
                //经销商询价Id
                controller.getRecord().put('Agency_Opportunity__c', mso.get(System.Label.Agency_Opportunity));
            }
            if (mso.containsKey(System.Label.Sales_Method)) {
                //经销商询价--招标方式
                controller.getRecord().put('Sales_Method__c', mso.get(System.Label.Sales_Method));
            }
            if (mso.containsKey(System.Label.Request)) {
                controller.getRecord().put('Request__c', mso.get(System.Label.Request));
            }
            if (mso.containsKey(System.Label.Request_Detail)) {
                controller.getRecord().put('Request_Detail__c', mso.get(System.Label.Request_Detail));
            }
            // 2022-04-13 来源 jz end 0414 lt
            rtTypeId = ApexPages.currentPage().getParameters().get('RecordType');
            // 20220420 lt OBSAP start
            if (String.isBlank(rtTypeId) && mso.containsKey('RecordTypeId')) {
                rtTypeId = mso.get('RecordTypeId');
            }
            // 20220420 lt OBSAP end
            obj.put('OwnerId', UserInfo.getUserId());
        }
        system.debug('RecordTypeId:' + rtTypeId);
        LayoutDescriberHelper.LayoutWrapper LayoutWrapperValue = LayoutDescriberHelper.describeSectionWithFieldsWrapper(
            rtTypeId,
            'Lead',
            'classic'
        );
        layoutSections = LayoutWrapperValue.layoutSections;
        List<String> requiredFieldAPIList = LayoutWrapperValue.requiredFieldAPIList;
        Map<String, String> fieldAPIToLabelMap = LayoutWrapperValue.fieldAPIToLabelMap;
        requiredFieldAPIListStr = JSON.serialize(requiredFieldAPIList);
        fieldAPIToLabelMapStr = JSON.serialize(fieldAPIToLabelMap);
        PIHelper.PIIntegration piIntegration = PIHelper.getPIIntegrationInfo('Lead');
        staticResource = JSON.serialize(piIntegration);
        staticResourceContact = JSON.serialize(PIHelper.getPIIntegrationInfo('Contact'));
        staticResourceInquiryForm = JSON.serialize(PIHelper.getPIIntegrationInfo('Inquiry_form__c'));
        //zhj MEBG新方案改造 2022-11-29 start
        staticResourceV2 = JSON.serialize(PIHelper.getPIIntegrationInfo('LeadV2'));
        //zhj MEBG新方案改造 2022-11-29 end
        encryptedAPIList = piIntegration.PIFields;
        sobjectPrefix = piIntegration.sobjectPrefix;
        layoutSectionsStr = JSON.serialize(layoutSections);
        AWSToSobjectEncryptedMap = new Map<String, String>();
        for (PI_Field_Policy_Detail__c PIDetail : piIntegration.PIDetails) {
            AWSToSobjectEncryptedMap.put(PIDetail.AWS_Field_API__c, PIDetail.SF_Field_API_Name__c);
        }
        //获取lookup字段
        List<String> VLookUpFields = new List<String>();
        for (LayoutDescriberHelper.LayoutSection ls : layoutSections) {
            for (LayoutDescriberHelper.LayoutField lf : ls.layoutFields) {
                if (lf.fieldAPI != '' && lf.fieldType == 'reference') {
                    VLookUpFields.add(lf.fieldAPI);
                }
            }
        }
        VLookUpFieldsJson = Json.serialize(VLookUpFields);
    }

    global class Response {
        public String recordId { get; set; }
        public String message { get; set; }
        public String status { get; set; }
    }

    @RemoteAction
    global static Response saveLead(String leadJson, String transId, Boolean isNew) {
        System.debug('Lead Info:' + JSON.serialize(leadJson));
        //1. Prepare the payload for  Lead
        Schema.SObjectType leadSchema = schemaMap.get(sobjectTypeValue);
        Map<String, Schema.SObjectField> fieldAPIToTypeMap = leadSchema.getDescribe().fields.getMap();
        Map<String, Object> fieldValueMap = (Map<String, Object>) JSON.deserializeUntyped(leadJson);
        Lead leadInfo = new Lead();
        String status = 'success';
        Response resp = new Response();
        Savepoint sp = Database.setSavepoint();
        Boolean isClone = false;
        String rid = '';
        String awsDataId = '';
        try {
            //自定义格式转换
            for (String fieldAPI : fieldValueMap.keySet()) {
                system.debug('field API=' + fieldAPI);
                if (!fieldAPIToTypeMap.containskey(fieldAPI)) {
                    continue;
                }
                Schema.DisplayType fielddataType = fieldAPIToTypeMap.get(fieldAPI).getDescribe().getType();
                String fieldValue = String.valueOf(fieldValueMap.get(fieldAPI));
                system.debug('Field Type:' + fielddataType + ' field Value=' + fieldValue);
                if (String.valueOf(fielddataType) == 'DATE') {
                    leadInfo.put(
                        fieldAPI,
                        (String.isBlank(fieldValue) || String.isEmpty(fieldValue)) ? null : Date.valueOf(fieldValue.replace('/', '-'))
                    );
                } else if (String.valueOf(fielddataType) == 'DATETIME') {
                    if (String.isNotBlank(fieldValue) && fieldValue.contains('T')) {
                        fieldValue = fieldValue.replace('T', ' ');
                        leadInfo.put(fieldAPI, Datetime.valueOfGmt(fieldValue));
                    } else {
                        leadInfo.put(fieldAPI, null);
                    }
                } else if (
                    String.valueof(fielddataType) == 'CURRENCY' ||
                    String.valueof(fielddataType) == 'PERCENT' ||
                    String.valueOf(fielddataType) == 'Number' ||
                    String.valueOf(fielddataType) == 'DOUBLE'
                ) {
                    leadInfo.put(
                        fieldAPI,
                        (String.isBlank(fieldValue) || String.isEmpty(fieldValue)) ? null : Decimal.valueOf(fieldValue.replace(',', ''))
                    );
                } else if (String.valueof(fielddataType) == 'BOOLEAN') {
                    leadInfo.put(fieldAPI, fieldValueMap.get(fieldAPI));
                } else {
                    leadInfo.put(fieldAPI, fieldValue);
                }
            }

            //2. Save Record Process

            System.debug('abcde');
            awsDataId = (String) leadInfo.get('AWS_Data_Id__c');
            System.debug('awsDataId = ' + awsDataId);
            Lead[] leads = [SELECT id FROM Lead WHERE AWS_Data_Id__c = :awsDataId];

            if (!isNew) {
                isClone = leads.size() == 0;
            }
            System.debug('isClone---------' + isClone);
            //2022-6-10 yjk SWAG-CEY8GZ start
            if (leadInfo.Hospital_Name__c != null) {
                Account acc = [
                    SELECT id, Hospital__c
                    FROM Account
                    WHERE id = :leadInfo.Hospital_Name__c
                ];
                leadInfo.hospital__c = acc.Hospital__c;
            }
            //2022-6-10 yjk SWAG-CEY8GZ end
            if (isNew || isClone) {
                System.debug('leadInfozhj = ' + leadInfo);
                if (!Test.isRunningTest()) {
                    insert leadInfo;
                }
            } else {
                System.debug('into update');
                // String awsDataId = (String)leadInfo.get('AWS_Data_Id__c');
                // System.debug('awsDataId = ' + awsDataId);
                // Lead[] leads = [select id from Lead where AWS_Data_Id__c =:awsDataId];
                System.debug('leads[0].id = ' + leads[0].id);
                leadInfo.put('Id', leads[0].id); //For testing;
                if (!Test.isRunningTest()) {
                    update leadInfo;
                }
            }
            rid = leadInfo.Id;
            PIHelper.saveTransLog(sobjectTypeValue, (String) leadInfo.get('AWS_Data_Id__c'), rid, transId, leadJson, status, '');
            resp.recordId = leadInfo.Id;
            resp.message = '';
            resp.status = status;
            System.debug('resp from sfdx back-end' + resp);
            return resp;
        } catch (DmlException e) {
            Integer index = 0;
            System.debug(e.getNumDml());
            System.debug(e.getDmlFields(index));
            System.debug(e.getDmlId(index));
            System.debug(e.getDmlIndex(index));
            System.debug(e.getDmlMessage(index));
            System.debug(e.getDmlStatusCode(index));
            System.debug(e.getDmlType(index));
            system.debug(e.getMessage());
            system.debug(e.getStackTraceString());

            System.debug('into catch' + e.getMessage());
            Database.rollback(sp);
            resp.status = 'Exception';
            resp.message = '保存失败，原因:' + e.getDmlMessage(index);
            PIHelper.saveTransLog(
                sobjectTypeValue,
                (String) leadInfo.get('AWS_Data_Id__c'),
                rid,
                transId,
                leadJson,
                status,
                e.getMessage() + e.getStackTraceString()
            );
            return resp;
        } catch (Exception e) {
            System.debug('into catch' + e.getMessage());
            Database.rollback(sp);
            status = 'fail';
            PIHelper.saveTransLog(
                sobjectTypeValue,
                (String) leadInfo.get('AWS_Data_Id__c'),
                rid,
                transId,
                leadJson,
                status,
                e.getMessage()
            );
            resp.message = e.getMessage();
            resp.status = status;
            return resp;
        }
    }

    @RemoteAction
    global static String queryAccount(String accountTypes, String accountId) {
        System.debug('accountType=' + accountTypes);
        System.debug('accountId=' + accountId);
        List<Object> types = (List<Object>) JSON.deserializeUntyped(accountTypes);
        System.debug('types=' + types);
        String soql = 'select Id,Name,';
        for (Object t : types) {
            soql += (String) t + ',';
        }
        soql = soql.substring(0, soql.length() - 1);
        soql += ' from Account where id=\'' + accountId + '\'';
        System.debug('soql=' + soql);
        Sobject account = new Account();
        if (!Test.isRunningTest()) {
            account = Database.query(soql);
        } else {
            account.put('Id', '000000000000000');
        }

        Map<String, Map<String, String>> m = new Map<String, Map<String, String>>();

        System.debug('account=' + account);
        for (Object ty : types) {
            String t = (String) ty;
            if (account.get(t) != null || Test.isRunningTest()) {
                Sobject acc = new Account();
                if (Test.isRunningTest()) {
                    acc.put('Id', '000000000000000');
                    acc.put('Name', 'Name');
                } else {
                    acc = Database.query('select Id,Name from Account where id=\'' + account.get(t) + '\'');
                }
                Map<String, String> n = new Map<String, String>();
                n.put('Id', (String) acc.get('Id'));
                n.put('Name', (String) acc.get('Name'));
                m.put(t, n);
            }
        }
        // if (account.get('Hospital__c') != null){
        //     m.put('Hospital__c', (String)account.get('Hospital__c'));
        //     m.put('Hospital__r.Name', (String)account.get('Hospital__r.Name'));
        // }
        // if (account.get('Department_Class__c') != null){
        //     m.put('Department_Class__c', (String)account.get('Department_Class__c'));
        //     m.put('Department_Class__r.Name', (String)account.get('Department_Class__r.Name'));
        // }
        System.debug('m=' + m);
        return JSON.serialize(m);

        // return (String)account.get('Hospital__c');
    }

    public static Integer ControllerUtil() {
        Integer i = 0;
        return i;
    }
}
