/*
 * 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{set;get;}
    public String awsToken{set;get;}
    public static Map<String, Schema.SObjectType> schemaMap = Schema.getGlobalDescribe();
    public static String sobjectTypeValue = 'Lead';
    public Boolean isNewMode{set;get;}
    public Boolean isCloneMode{protected set;get;}
    public String rtTypeId {get; set;}
    public String AWSDataId{set;get;}
    public String AWSDataIdInquiryForm{set;get;}
    public String contactId{set;get;}//For Lookup field
    public List<String> encryptedAPIList{set;get;}
    // 当前页面中的加密字段集合
    public List<String> layoutEncryptedAPIList{private set;get;}
    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{set;get;}
    public String PIPL_Name_Label{set;get;}
    public String PIPL_Input_Account_Error_Msg{set;get;}
    public String sobjectPrefix{set;get;}
    public String sobjecttypeForFrontEnd{set;get;}
    public String contactsInfo {set;get;}//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;
        layoutEncryptedAPIList = new List<String>();
        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(System.label.lead_parameter_1) != null){ //niwu -lead_parameter_1 -CF00N1000000962np_lkid
            System.debug(System.label.lead_parameter_1);
            //产品咨询单过来的
            String InquiryFormId = ApexPages.currentPage().getParameters().get(System.label.lead_parameter_1);
            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(System.label.lead_parameter_2)){ //niwu-lead_parameter_2 -CF00N10000006ps6f_lkid
                isDecryptContact = '1';
                String contactId = mso.get(System.label.lead_parameter_2);
                //查询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(System.label.lead_parameter_2));
            }
            //医院名
            if(mso.containsKey(System.label.lead_parameter_3)){ //niwu  -CF00N10000002CvC5_lkid
                controller.getRecord().put('Hospital_Name__c',mso.get(System.label.lead_parameter_3));
                //通过医院id查询战略科室分类
                String hospitalId = mso.get(System.label.lead_parameter_3);
                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(System.label.lead_parameter_4)){ //niwu  CF00N10000002CvC5
                controller.getRecord().put('Company',mso.get(System.label.lead_parameter_4));
            }
            //战略科室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);
        }
        //2023 08 18 张赫阳 添加permissonset start
        Schema.SObjectType sobjectSchema = schemaMap.get(sobjectTypeValue);
        Map<String, Schema.SObjectField> fieldMap = sobjectSchema.getDescribe().fields.getMap(); 
        //2023 08 18 张赫阳 添加permissonset en
        //获取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);
                }
                //在view解密section中只需显示当前layout中的加密字段
                if (encryptedAPIList.contains(lf.fieldAPI)) {
                    //2023 08 18 张赫阳 添加permissonset start
                    if(fieldMap.get(lf.fieldAPI).getDescribe().isAccessible()){
                    //2023 08 18 张赫阳 添加permissonset end
                        layoutEncryptedAPIList.add(lf.fieldAPI);
                    }
                    
                }
            }
        }
        VLookUpFieldsJson = Json.serialize(VLookUpFields);
    }

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

    @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',System.label.Agency_ID_c);
        }
        

        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',System.label.Agency_ID_c);
                    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;
    }
}