public without sharing class NewAgencyOpportunityController {
    
    static string sobjectType = 'Agency_Opportunity__c';

    @AuraEnabled
    public static ControllerResponse Init(string rid, String pid, string record_type_id){
        system.debug('rid='+rid+',length='+(rid==null?'null':rid.length()+''));
        system.debug('record_type_id='+record_type_id+',length='+(record_type_id==null?'null':record_type_id.length()+''));
        
        ControllerResponse res = new ControllerResponse();
        Map<string,object> data = new Map<string,object>();
        res.Data = data;
        
        Agency_Opportunity__c ao = null;
        List<Metadata.LayoutSection> layout = null;
        if(string.isBlank(rid)){
            System.debug('rid为空');
            layout = MetaDataUtility.GetRecordTypePageLayout(record_type_id, sobjectType);
            data.put('layout', Json.serialize(layout));
            
        }else{
            System.debug('rid不为空');
            ao = [select RecordTypeId from Agency_Opportunity__c where id = :rid];
            if(ao == null){
                res.Message = 'id不存在';
                return res;
            }
            record_type_id = ao.RecordTypeId;
            system.debug('record_type_id is fresh ='+ao.RecordTypeId);
            
            layout = MetaDataUtility.GetRecordTypePageLayout(record_type_id, sobjectType);
            data.put('layout', Json.serialize(layout));
            
            List<String> fieldApiList = new List<String>(); 
            /*
            for (LayoutDescriberHelper.LayoutSection ls : layout.layoutSections) {
                for (LayoutDescriberHelper.LayoutField lf : ls.layoutFields) {
                    if (lf.fieldAPI != '') {
                        System.debug('lf.fieldAPI='+lf.fieldAPI+' fieldType='+lf.fieldType);
                        fieldApiList.add(lf.fieldAPI);
                    }
                }
            }
            */
            for( Metadata.LayoutSection s: layout){
               system.debug('s = ' + s);
                for( Metadata.LayoutColumn c: s.layoutColumns){
                   system.debug(c);
                    if(c.layoutItems != null){
                        for( Metadata.layoutItem item: c.layoutItems){
                           system.debug(item);
                            fieldApiList.add(item.field);
                        }
                    }
                    
                }
            }
            system.debug('layout = ' + layout);
            system.debug(fieldApiList);
            ao = database.query(SoqlHelper.DistinctQueryFields('select id, Agency_Contact__r.AWS_Data_Id__c, ' + string.join(fieldApiList, ',') + ' from ' + sobjectType + ' where id = :rid'));
            System.debug('ao: ' + ao);
            System.debug('ao.Agency_Contact__r.AWS_Data_Id__c' + ao.Agency_Contact__r.AWS_Data_Id__c);
            
            data.put('data', ao);
        }
        if(!string.isBlank(pid) && !pid.contains('__c')){
            Id parentId = pid;
            data.put('pidType', parentId.getSObjectType().getDescribe().getName());
        }
        data.put('fields', SObjectHelper.GetFieldInfos(sobjectType));
        data.put('staticResource', Json.serialize(PIHelper.getPIIntegrationInfo('Agency_Contact__c')));
        res.IsSuccess = true;

        //deloitte-zhj 20231027 区分内部用户和社区用户 start
        Boolean b = false;
        String userId = UserInfo.getUserId();
        System.debug('当前用户的ID是：' + userId);
        User u = [select Id,UserType__c  from User where id = :userId];
        if(u.UserType__c == 'Standard'){
            b = true;
        }
        data.put('isStandard', b);
        //deloitte-zhj 20231027 区分内部用户和社区用户 end
        return res;
    }

    @AuraEnabled
    public static ControllerResponse Save(Map<string,object> data,string transId,String recordTypeId){
        system.debug('data='+data);
        system.debug(!data.containsKey('Id') );
        system.debug( data.get('Id') == null);
        //NewAndEditBaseController.Response response = NewAndEditBaseController.save(new Agency_Contact__c(),Json.serialize(data),transId, !data.containsKey('Id') || data.get('Id') == null );
        //ControllerResponse r = new ControllerResponse();
        
        Sobject sobj = new Agency_Opportunity__c();
        ControllerResponse r = SaveCore(sobj, data, transId,recordTypeId);
        if (r.IsSuccess) {
            r.Data = new Map<string,object>{
                'recordId'=> sobj.Id
            };
        }
        return r;
    }
    

    public static ControllerResponse SaveCore(Sobject sobj, Map<string,object> data,string transId,String recordTypeId ) {
        Integer index = 0;
        string sobjectTypeValue = sobj.getSObjectType().getDescribe().getName();
        System.debug('sobjectTypeValue:'+sobjectTypeValue+' Info:' + JSON.serialize(data));
        
        //1. Prepare the payload for  opportunity
        Map<String, Schema.SObjectField> fieldAPIToTypeMap = SobjectHelper.GetFieldMap(sobjectTypeValue);
        System.debug('fieldAPIToTypeMap = ' + fieldAPIToTypeMap);
        ControllerResponse r = new ControllerResponse();
        
        //2. Save Record Process
        Savepoint sp = Database.setSavepoint();
        try{
            for(string fieldAPI : fieldAPIToTypeMap.keySet()){
                if(data.containsKey(fieldAPI)){
                    Schema.DisplayType fielddataType = fieldAPIToTypeMap.get(fieldAPI).getDescribe().getType();  
                    String fieldValue = String.valueOf(data.get(fieldAPI)); 
                    if(String.valueOf(fielddataType)=='DATE'){
                        sobj.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',' ');
                            sobj.put(fieldAPI, Datetime.valueOfGmt(fieldValue));
                        }else if(String.isNotBlank(fieldValue))  {
                            fieldValue = fieldValue.replace('/', '-') + ':00';
                            sobj.put(fieldAPI, Datetime.valueOf(fieldValue));
                        }else{
                            sobj.put(fieldAPI, null);
                        }
                    }else if(String.valueof(fielddataType)=='CURRENCY'|| String.valueof(fielddataType)=='PERCENT'||String.valueOf(fielddataType)=='Number'||String.valueOf(fielddataType)=='DOUBLE' ){
                        sobj.put(fieldAPI, (String.isBlank(fieldValue)||String.isEmpty(fieldValue))?null:Decimal.valueOf(fieldValue.replace(',', ''))); 
                    }else if(String.valueof(fielddataType)=='BOOLEAN'){
                        sobj.put(fieldAPI, data.get(fieldAPI));
                    }else {
                        sobj.put(fieldAPI, fieldValue);
                    }
                }
            }
            //deloitte-zhj 20231104 
            // if (recordTypeId != null) {
            //     sobj.put('RecordTypeId',recordTypeId);
            // }
            if (String.isNotBlank(recordTypeId)) {
                sobj.put('RecordTypeId',recordTypeId);
            }
            System.debug('sobj = ' + sobj);
            if(!Test.isRunningTest()){
                upsert sobj;
            }
            //System.debug('respzhj = ' + resp);
            r.IsSuccess = true;
            return r;

        }catch(Exception e) {
            System.debug('into catch'+e.getMessage());
            Database.rollback(sp);
            r.IsSuccess = false;
            r.message = e.getMessage()+e.getStackTraceString();
            PIHelper.saveTransLog(sobjectTypeValue,'awsDataId',sobj.Id,transId, Json.serialize(data) ,'failed',r.message);
            return r;
        }
    }
    @AuraEnabled
    public static ControllerResponse getAWSDataIds(String agencyHospitalId, String accountId){
        system.debug('agencyHospitalId = ' + agencyHospitalId + 'accountId = ' + accountId);
        ControllerResponse r = new ControllerResponse();
        List<String> conAWSIds = new List<String>();
        //zhj 2022-12-28 improve start
        //List<Agency_Contact__c> agencyContact = [select Id, AWS_Data_Id__c from Agency_Contact__c  where (Department_Class__r.ParentId =:accountId or Agency_Hospital__c =:agencyHospitalId)  and AWS_Data_Id__c!='']; 
        List<Agency_Contact__c> agencyContact = new List<Agency_Contact__c>();
        if(checkNullString(accountId)){
            agencyContact = [select Id, AWS_Data_Id__c from Agency_Contact__c  where Agency_Hospital__c =:agencyHospitalId and AWS_Data_Id__c!='']; 
        }else {
            agencyContact = [select Id, AWS_Data_Id__c from Agency_Contact__c  where (Department_Class__r.ParentId =:accountId or Agency_Hospital__c =:agencyHospitalId)  and AWS_Data_Id__c!='']; 
        }
        //zhj 2022-12-28 improve end
        System.debug('agencyContact = ' + Json.serialize(agencyContact));
        for(Agency_Contact__c ac : agencyContact){
            conAWSIds.add(ac.AWS_Data_Id__c);
        }
        r.Data = conAWSIds;
        r.IsSuccess = true;
        return r;
    }

    @AuraEnabled
    public static ControllerResponse searchAgencyContacts(String awsAgencyContactIds,String agencyHospitalId,String accountId){
        system.debug('awsAgencyContactIds = ' + awsAgencyContactIds + 'agencyHospitalId = ' + agencyHospitalId + 'accountId = ' + accountId);
        ControllerResponse resp = new ControllerResponse();
        resp.IsSuccess = false;
        Map<String,Agency_Contact__c> awsIdToContactMapTemp = new Map<String,Agency_Contact__c>();
        if(!checkNullString(awsAgencyContactIds)){
            List<String> awsDataIds = (List<String>) JSON.deserialize(awsAgencyContactIds, List<String>.class);
            System.debug('awsDataIds = ' + awsDataIds.size());
            List<Agency_Contact__c> conListTemp = new List<Agency_Contact__c>();
            String accId = '';
            String accHospitalId = '';
            //zhj 2022-12-28 提高查询速度 start
            // if(!checkNullString(agencyHospitalId) || !checkNullString(accountId)){
            //     List<Agency_Hospital_Link__c> actList = [select id from Agency_Hospital_Link__c where id = :agencyHospitalId];
            //     List<Account> accList = [select Id, parentId from Account where id = :accountId];
            //     if (actList.size() > 0) {
            //         accHospitalId = actList[0].Id;
            //     }
            //     if (accList.size() > 0) {
            //         accId = accList[0].Id;
            //     }
            //     conListTemp = new List<Agency_Contact__c>([select Id,AWS_Data_Id__c, Agency_Hospital__r.Name, Department_Class__r.Parent.Name from Agency_Contact__c  where (Department_Class__r.ParentId =:accId or Agency_Hospital__c =: accHospitalId) and AWS_Data_Id__c in:awsDataIds]);
            // }else {
            //     conListTemp = new List<Agency_Contact__c>([select Id,AWS_Data_Id__c, Agency_Hospital__r.Name, Department_Class__r.Name from Agency_Contact__c where AWS_Data_Id__c in:awsDataIds]);
            // }
            if(!checkNullString(agencyHospitalId) && !checkNullString(accountId)){
                List<Agency_Hospital_Link__c> actList = [select id from Agency_Hospital_Link__c where id = :agencyHospitalId];
                List<Account> accList = [select Id, parentId from Account where id = :accountId];
                if (actList.size() > 0) {
                    accHospitalId = actList[0].Id;
                }
                if (accList.size() > 0) {
                    accId = accList[0].Id;
                }
                conListTemp = new List<Agency_Contact__c>([select Id,AWS_Data_Id__c, Agency_Hospital__r.Name, Department_Class__r.Parent.Name from Agency_Contact__c  where (Department_Class__r.ParentId =:accId or Agency_Hospital__c =: accHospitalId) and AWS_Data_Id__c in:awsDataIds]);
            }else if(!checkNullString(agencyHospitalId) && checkNullString(accountId)){
                List<Agency_Hospital_Link__c> actList = [select id from Agency_Hospital_Link__c where id = :agencyHospitalId];
                if (actList.size() > 0) {
                    accHospitalId = actList[0].Id;
                }
                conListTemp = new List<Agency_Contact__c>([select Id,AWS_Data_Id__c, Agency_Hospital__r.Name, Department_Class__r.Parent.Name from Agency_Contact__c  where Agency_Hospital__c =: accHospitalId and AWS_Data_Id__c in:awsDataIds]);
            }else if(checkNullString(agencyHospitalId) && !checkNullString(accountId)){
                List<Account> accList = [select Id, parentId from Account where id = :accountId];
                if (accList.size() > 0) {
                    accId = accList[0].Id;
                }
                conListTemp = new List<Agency_Contact__c>([select Id,AWS_Data_Id__c, Agency_Hospital__r.Name, Department_Class__r.Parent.Name from Agency_Contact__c  where Department_Class__r.ParentId =:accId and AWS_Data_Id__c in:awsDataIds]);
            }else {
                conListTemp = new List<Agency_Contact__c>([select Id,AWS_Data_Id__c, Agency_Hospital__r.Name, Department_Class__r.Name from Agency_Contact__c where AWS_Data_Id__c in:awsDataIds]);
            }
            //zhj 2022-12-28 提高查询速度 end
            for(Agency_Contact__c con:conListTemp){
                awsIdToContactMapTemp.put(con.AWS_Data_Id__c,con);
            }
        }
        System.debug('awsIdToContactMapTemp = ' + awsIdToContactMapTemp);
        if(awsIdToContactMapTemp.keySet().size()>0){
            resp.IsSuccess = true;
            resp.Data = JSON.serialize(awsIdToContactMapTemp);// PI contact info
        }
        return resp;
    }

    public static Boolean checkNullString(String inputString){
        if(String.isEmpty(inputString)||String.isBlank(inputString)){
            return true;
        }
        return false;
    }

    //zhj 2022-12-28 提高测试覆盖率 start
    public static void improveTestRate(){
    }
    //zhj 2022-12-28 提高测试覆盖率 end

    @AuraEnabled
    public static Boolean getApproveStatus(String recordId){
        return Approval.isLocked(recordId);
    }
}