@RestResource(urlMapping = '/NFM609/*')
global with sharing class NFM609Rest {
    public static final String LOG_TYPE = 'NFM609';

    global class GeData {

        public String CICstaff; //CIC所属人
        public String complaintID; //业务单号
        public String[] QuestionList; //询问内容
        public String InquireContent; //询问内容(数据不保存)
        public String InquirePlatform; //询问方式
        public String InquireProduct; //询问产品
        public String InquirerDate; //询问日期
        public String InquirerType; //询问方
        public String[] AnswerList; //回答内容
        public String answerContent; //回答内容(数据不保存)
        public String answerDate; //回答日期
        public String attachmentName; //附件名称
        public String attachmentfile; //附件
        public String dealMethod; //应对方法
        public String faultJudgment; //故障判断
        public String field; //所属领域
        public String mngCd; //投诉人管理编码
        public String province; //管辖部门
        public String questionType; //问题分类
        public String remarks; //备注
        public String status; //状态
        public String trackType; //跟踪
        public String unifiedUserID; //投诉人统一ID
    }

    @HttpPost
    global static void doPost() {
        //取得接口传输内容
        String strData = RestContext.request.requestBody.toString();
        List < GeData > ges = (List < GeData > ) JSON.deserializeStrict(strData, List < GeData > .class);

        if (ges == null) {
            return;
        }
        BatchIF_Log__c iflog = new BatchIF_Log__c();
        iflog.Type__c = LOG_TYPE;
        iflog.ErrorLog__c = '';
        iflog.Log__c = 'callout start\n';

        BatchIF_Log__c rowData = NFMUtil.makeRowData(iflog, LOG_TYPE, ges);
        insert rowdata;
        if (String.isBlank(rowData.Log__c) == false) {
            executefuture(rowData.Id);
        }

        //恢复JSON
        RestResponse res = RestContext.response;
        res.addHeader('Content-Type', 'application/json');
        res.statusCode = 200;

        String jsonResponse = '{"status":"Success","Message":"成功"}';
        res.responseBody = Blob.valueOf(jsonResponse);
        return;
    }

    @future(callout = true)
    global static void executefuture(String rowData_Id) {
        main(rowData_Id);
    }

    global static void main(String rowData_Id) {
        BatchIF_Log__c rowData = [Select Id, Name, Log__c, ErrorLog__c, Log2__c, Log3__c, Log4__c, Log5__c, Log6__c, Log7__c, Log8__c, Log9__c, Log10__c, Log11__c, Log12__c, MessageGroupNumber__c, retry_cnt__c from BatchIF_Log__c where RowDataFlg__c = true and Id =: rowData_Id];

        String logstr = 'start\n';
        BatchIF_Log__c iflog = new BatchIF_Log__c();
        iflog.Type__c = LOG_TYPE;
        iflog.MessageGroupNumber__c = rowData.MessageGroupNumber__c;
        iflog.Log__c = logstr;
        iflog.ErrorLog__c = '';
        insert iflog;

        String rowDataStr = NFMUtil.getRowDataStr(rowData);

        List < GeData > itemMasterList = (List < GeData > ) JSON.deserialize(rowDataStr, List < GeData > .class);
        logstr += '数据总数为：' + itemMasterList.size() + '\n';
        if (itemMasterList == null || itemMasterList.size() == 0) {
            return;
        }
        Savepoint sp = Database.setSavepoint();

        try {
            List < String > cicstaffList = new List < String > (); //存放cic所属人
            List < String > inquireList = new List < String > (); //存放询问产品
            List < String > mngCdList = new List < String > ();

            Map < String, GeData > geDataMap = new Map < String, GeData > ();
            //遍历给oldcicIdList存放id，给map赋值
            for (GeData ged: itemMasterList) {
                String dataComplete = verify(ged);
                if (!String.isBlank(dataComplete)) {
                    logstr += dataComplete;
                    continue;
                }
                geDataMap.put(ged.complaintID, ged); //key是接口拿到的id，value是GeData一整条数据
                cicstaffList.add(ged.CICstaff);
                inquireList.add(ged.InquireProduct);
                if (String.isNotBlank(ged.mngCd)) {
                    mngCdList.add(ged.mngCd);
                }

            }

            if (geDataMap.size() > 0) {
                // 获取CIC
                Map < String, Case > caseMap = getCaseMap(geDataMap);
                // 获取 启用的用户
                Map < String, Id > cicstaffmap = getCaseOwnerMap(cicstaffList);
                // 获取产品
                Map < String, Id > inquireMap = getProductMap(inquireList);
                // 获取联系人以及联系人对应的客户
                Map < String, Contact > accountIdMap = getContactMap(mngCdList);



                List < Case > upsertList = new List < Case > ();
                Map < String, List < String >> answerMap = new Map < String, List < String >> ();

                Boolean attachmentDownloadFlg = false;
                String complaintIDStr = '业务单号  [ \n';
                for (String complaintID: geDataMap.keySet()) {

                    GeData ged = geDataMap.get(complaintID);
                    if (!cicstaffmap.containsKey(ged.CICstaff)) {
                        logstr += ged.CICstaff + '员工编码不存在或对应用户无效,此条数据跳过';
                        continue;
                    }

                    Case cas = caseMap.containsKey(complaintID) ? caseMap.get(complaintID) : new Case(); //new Case();

                    //询问产品
                    if (inquireMap.containsKey(ged.InquireProduct)) {
                        cas.prod__c = inquireMap.get(ged.InquireProduct);
                    } else {
                        cas.Other_company_product__c = ged.InquireProduct;
                    }
                    if (accountIdMap.containsKey(ged.mngCd)) {
                        Contact con = accountIdMap.get(ged.mngCd);
                        cas.ContactId = con.Id;
                        cas.Account__c = getAccountId(con);
                    }

                    cas.Ownerid = cicstaffmap.get(ged.CICstaff); //CIC所属人
                    cas.inquiry_detail__c =ged.InquireContent; //询问内容 //'内容太长，详情请见 CIC问答内容 相关内容'; //ged.InquireContent; //询问内容
                    cas.complaintID__c = ged.complaintID; //业务单号
                    cas.Origin = '客户端'; //(个案来源)(20220106修改)
                    cas.Received_call_day__c = NFMUtil.parseStr2Date(ged.InquirerDate); //询问日期(收到电话日)
                    cas.Contact_staff__c = ged.InquirerType; //询问方
                    cas.answer_detail_content__c = ged.answerContent; //回答内容 '内容太长，详情请见 CIC问答内容 相关内容'; //
                    cas.answer_day__c = NFMUtil.parseStr2Date(ged.answerDate); //回答日期
                    cas.Process_method__c = ged.dealMethod; //对应方法
                    cas.solutuion__c = ged.faultJudgment; //故障判断
                    cas.Question_Area_new__c = ged.field; //所属领域
                    cas.Province__c = ged.province; //管辖部门
                    cas.inquiry_type__c = ged.questionType; //问题类别
                    cas.Text_attachement__c = ged.remarks; //备注
                    cas.Status = ged.status; //状态
                    cas.Follow_category__c = ged.trackType; //跟踪
                    cas.RecordTypeId = '01210000000QsYpAAK';
                    cas.AttachmentLink__c = ged.attachmentfile;
                    String attachmentName = ged.attachmentName;
                    cas.AttachmentName__c = attachmentName;
                    if (String.isNotBlank(ged.attachmentfile)) {
                        cas.AttachmentDownload__c = true;
                        attachmentDownloadFlg = true;
                        if (String.isBlank(attachmentName) || (String.isNotBlank(attachmentName) && !attachmentName.contains('.zip'))){
                            cas.AttachmentName__c = '附件.zip';
                        }  
                    }

                    
                    
                    upsertList.add(cas);
                    if ('投诉'.equals(ged.questionType)) { //问答时 AnswerList放全部， 投诉时 需合并 QuestionList
                        ged.AnswerList.addAll(ged.QuestionList);
                    }



                    complaintIDStr += complaintID + '\n';
                    answerMap.put(complaintID, ged.AnswerList);
                }



                if (upsertList.size() > 0) {
                    upsert upsertList;

                    logstr += complaintIDStr + ' ]\n保存成功\n';
                    if (attachmentDownloadFlg) {
                        NFM609Schedule.assignOneMinute('Case');
                    }
                    
                    
                }
            }
            logstr += 'END'; 
            rowData.retry_cnt__c = 0;
        } catch (Exception ex) {

            //发生错误时
            Database.rollback(sp);
            logstr += '\n' + ex.getMessage();
            iflog.ErrorLog__c = ex.getMessage() + '\n' + ex.getStackTraceString() + '\n' + iflog.ErrorLog__c;
            
            rowData = NFMUtil.LogAutoSend(rowData, ex, null);
        } finally {
            update rowData;
            iflog.Log__c = logstr;
            update iflog;
        }
    }

    private static String verify(GeData ged) {
        String result = '';
        String complaintID = '';
        if (ged == null) {
            result += 'DataError: is null!\n';
        } else {
            if (String.isBlank(ged.complaintID)) {
                result += 'DataError: 业务单号 [ complaintID ] is null!\n';
            } else {
                complaintID = '业务单号 [ ' + ged.complaintID + ' ]\n';
            }
            if (String.isBlank(ged.CICstaff)) {
                result += 'DataError: CIC所属人 [ CICstaff ] is null!\n';
            }

            if (String.isBlank(ged.questionType)) {
                result += 'DataError: 问题类别 [ questionType ] is null!\n';
            }

            if (String.isBlank(ged.InquireProduct)) {
                result += 'DataError: 询问产品 [ InquireProduct ] is null!\n';
            }
            if (ged.AnswerList == null) {
                result += 'DataError: 回答内容 [ AnswerList ] is null!\n';
            }

            if (String.isNotBlank(complaintID) && String.isNotBlank(result)) {
                result += complaintID + result;
            }

        }

        return result;
    }
    // 查找 CIC(个案) 
    private static Map < String, Case > getCaseMap(Map < String, GeData > geDataMap) {
        List < Case > caseList = [SELECT Id, complaintID__c FROM Case WHERE complaintID__c IN: geDataMap.keySet()];
        Map < String, Case > caseMap = new Map < String, Case > ();
        for (Case cas: caseList) {
            caseMap.put(cas.complaintID__c, cas);
        }
        return caseMap;
    }
    // 查找 启用的用户
    private static Map < String, Id > getCaseOwnerMap(List < String > cicstaffList) {
        List < User > userList = [SELECT id, Employee_No__c FROM User WHERE Employee_No__c IN: cicstaffList and IsActive = true];
        Map < String, Id > cicstaffmap = new Map < String, Id > ();
        for (User u: userList) {
            cicstaffmap.put(u.Employee_No__c, u.Id);
        }
        return cicstaffmap;
    }

    // 获取客户Id
    private static String getAccountId(Contact con) {
        String result = null;
        // 医院/经销商
        if (String.isBlank(con.Account.ParentId)) {
            result = con.AccountId;
        } else if (String.isNotBlank(con.Account.Parent.ParentId)) { //科室
            result = con.Account.Parent.ParentId;
        } else { //战略科室
            result = con.Account.ParentId;
        }
        return result;
    }

    // 查找 联系人
    public static Map < String, Contact > getContactMap(List < String > mngCdList) {
        Map < String, Contact > accountIdMap = new Map < String, Contact > ();
        if (mngCdList.size() > 0) {
            String contactId = null;
            List < Contact > contactList = [
                SELECT Id, AccountId, Account.Name, Account.ParentId, Account.Parent.ParentId, CManageCode__c, Employee_No_manual__c
                FROM Contact
                WHERE CManageCode__c IN: mngCdList OR Employee_No_manual__c IN: mngCdList
            ];
            for (Contact con: contactList) {
                if (String.isNotBlank(con.Employee_No_manual__c)) {
                    accountIdMap.put(con.Employee_No_manual__c, con);
                }
                accountIdMap.put(con.CManageCode__c, con);
            }
        }

        return accountIdMap;
    }
    // 根据产品型号 查找最晚创建的产品
    private static Map < String, Id > getProductMap(List < String > inquireList) {
        List < Product2 > productList = [SELECT Id, Asset_Model_No__c, createdDate FROM product2 WHERE Asset_Model_No__c IN: inquireList ORDER BY Asset_Model_No__c, createdDate];
        Map < String, Id > inquireMap = new Map < String, Id > ();
        for (Product2 pro: productList) {
            inquireMap.put(pro.Asset_Model_No__c, pro.Id);
        }

        return inquireMap;
    }

    
}