/**
     * [FrameNumUploadController 进口单证上传]
     * @Author   lijinhuan
     * @DateTime 2022-11-04T18:31:03+0800
     * 测试类：FrameNumUploadControllerTest
*/
public with sharing class FrameNumUploadController {
    public Integer detailCountLimit{get;private set;}
    // 数据集
    public List<DataBean> dataBeans {get; set;}
    public Boolean haveErr{get; set;}
    public FrameNumUploadController() {
        detailCountLimit = 10000;
        dataBeans = new List<DataBean>();
        haveErr = false;
    }
    public void importCSVFile() {
        dataBeans = new List<DataBean>();
        haveErr = false;
        String csvData = ApexPages.currentPage().getParameters().get('csvData');
        if(String.isBlank(csvData)){
            ApexPages.addMessage(new ApexPages.Message(ApexPages.severity.WARNING,'csv文件不可为空' ));
            return;
        }
        csvData = csvData.trim();
        List<List<String>> tempCsvBody = CSVReader.readIETFRFC4180CSVFile(Blob.valueof(csvData));  // 全部CSV数据
        List<String> importLabelList = tempCsvBody[0];  // CSV读入的标题行
        // List<FrameNumManage__c> fnmList = new List<FrameNumManage__c>();
        Map<String,FrameNumManage__c> fnmMap = new Map<String,FrameNumManage__c>();
        Integer importLine = 0;
        List<String> warningList = new List<String>(); 
        Map<String, String> labelToApiMap = createLabelApiMap();
        Map<String, SObjectField> queryFrameNumFieldMap = FrameNumManage__c.getSObjectType().getDescribe().fields.getMap();
        
        for (Integer i = 1; i < tempCsvBody.size(); i++) {
            FrameNumManage__c tempFnm = new FrameNumManage__c();
            Boolean flag = false;
            for (Integer j = 0; j < importLabelList.size(); j++) {
                String api = labelToApiMap.get(importLabelList[j]);
                if (queryFrameNumFieldMap.containsKey(api) == false) {
                    throw new ControllerUtil.myException('字段:【' + importLabelList[j] + '】在' + FrameNumManage__c.getSObjectType().getDescribe().getLabel() + '里不存在, 请确认。');
                }
                DescribeFieldResult queryAssetFieldResult = queryFrameNumFieldMap.get(api).getDescribe();
                if (String.isNotBlank(tempCsvBody[i][j])){
                    flag = true;
                    String value = String.valueOf(tempCsvBody[i][j]).trim();
                    if (queryAssetFieldResult.getType() == Schema.DisplayType.Date) {
                        value = value.replace('/', '-');
                        tempFnm.put(api, Date.valueOf(value));
                    } else if (queryAssetFieldResult.getType() == Schema.DisplayType.Boolean) {
                        tempFnm.put(api, Boolean.valueOf(value));
                    } else if (queryAssetFieldResult.getType() == Schema.DisplayType.Double) {
                        tempFnm.put(api, Decimal.valueOf(value));
                    } else {
                        tempFnm.put(api, value);
                    }
                }
            }
            if(flag){
                String managementCode = tempFnm.ManagementCode__c;
                String key = tempFnm.SerialNumber__c+'('+tempFnm.ManagementCode__c+')';
                tempFnm.SerialNumberS__c = key;
                tempFnm.name = tempFnm.ManagementCode__c;
                tempFnm.UploadDate__c = Date.today();
                tempFnm.Handleer__c = UserInfo.getUserId();
                if(String.isBlank(managementCode)){
                    throw new ControllerUtil.myException('【' + queryFrameNumFieldMap.get('ManagementCode__c').getDescribe().getLabel() + '】不可为空' + tempFnm);
                }else if(fnmMap.containsKey(key)){
                    throw new ControllerUtil.myException('【' + queryFrameNumFieldMap.get('ManagementCode__c').getDescribe().getLabel() + '】存在多条数据' + tempFnm);
                } else{
                    fnmMap.put(key,tempFnm);
                }
            }
            
        }
        // System.debug('zheli1:'+fnmMap.size());
        // 执行更新
        if(fnmMap.size() > 0){
            Database.UpsertResult[] urList = Database.upsert(fnmMap.values(),FrameNumManage__c.ManagementCode__c,false);
            //只更新 start
            // Map<String,String> codeMap = new Map<String,String>();
            // List<FrameNumManage__c> upList = new List<FrameNumManage__c>();
            // List<FrameNumManage__c> tempList = [SELECT Id,SerialNumberS__c FROM FrameNumManage__c WHERE SerialNumberS__c IN :fnmMap.keySet()];
            // for(FrameNumManage__c temp:tempList){
            //     codeMap.put(temp.SerialNumberS__c,temp.Id);
            // }
            // for(String s:fnmMap.keySet()){
            //     if(!codeMap.containsKey(s)){
            //         String errStr = '本条数据管理编码或者机身号有误，请确认';
            //         warningList.add(errStr);
            //         DataBean dataBean = new DataBean(fnmMap.get(s),errStr);
            //         dataBeans.add(dataBean);
            //         fnmMap.remove(s);
            //     }else{
            //         FrameNumManage__c fn = fnmMap.get(s);
            //         fn.Id = codeMap.get(s);
            //         upList.add(fn);
            //     }
            // }
            // 只更新 end
            // if(upList.size() > 0){
                // System.debug('zheli2:'+fnmMap.size());
                // Database.SaveResult[] urList = Database.update(upList,false);// 只更新
                for (Integer tIdx = 0; tIdx < urList.size(); tIdx++) {
                    Database.UpsertResult sr = urList[tIdx];
                    // Database.SaveResult sr = urList[tIdx]; // 只更新
                    if (!sr.isSuccess()) {
                        String errStr = '';
                        Database.Error emsg = sr.getErrors()[0];
                        errStr = emsg.getMessage();
                        warningList.add(errStr);
                        DataBean dataBean = new DataBean(fnmMap.values()[tIdx],errStr);
                        // DataBean dataBean = new DataBean(upList[tIdx],errStr);// 只更新
                        dataBeans.add(dataBean);
                    }else{
                        importLine++;
                    }
                }
            // }
            
            // 生成错误文件
            if (warningList.size() > 0) {
                haveErr = true;
                ApexPages.addMessage(new ApexPages.Message(ApexPages.severity.WARNING, warningList.size() + '条记录插入/更新失败，点击下面查看按钮下载查看'));
            }
            if(importLine == 0) {
                ApexPages.addMessage(new ApexPages.Message(ApexPages.severity.WARNING, '未导入成功任何数据，请检查CSV文件'));
            }
            else {
                String importSuccessfulMsg = '导入CSV文件完成，成功导入' + importLine + '条数据。';
                ApexPages.addMessage(new ApexPages.Message(ApexPages.severity.INFO, importSuccessfulMsg));
                // 调用batch
                Database.executeBatch(new SetFrameNumManageBatch(), 100);
            }
        }else{
            ApexPages.addMessage(new ApexPages.Message(ApexPages.severity.WARNING, '未导入任何数据，请检查CSV文件'));
        }
    }
    public Pagereference exportBycsv() {
        return page.FrameNumUploadErrcsv;                 
    }
    private Map<String, String> createLabelApiMap(){
        Map<String,String> apiMap = new Map<String,String>();
        Map<String,Schema.SObjectField> mfields = FrameNumManage__c.sObjectType.getDescribe().fields.getMap();
        for(String strField:mfields.keySet()) {
            SObjectField fl = mfields.get(strField);
            apiMap.put(fl.getDescribe().getlabel(), strField);
        }
        return apiMap;
    }
     // 数据类
    class DataBean {
        // 机身管理
        public FrameNumManage__c  FNumManage { get; set; }
        // 导入信息
        public String message { get; set; }

        public String ScanDate { get; set; }
        public String StartDate { get; set; }
        public String EndDate { get; set; }
        // 构造方法
        DataBean(FrameNumManage__c fnm, String m){
            FNumManage  = fnm;
            message = m;
            ScanDate = fnm.ScanDate__c != null?fnm.ScanDate__c.format():'';
            StartDate = fnm.StartDate__c != null?fnm.StartDate__c.format():'';
            EndDate = fnm.EndDate__c != null?fnm.EndDate__c.format():'';
        }
    }
}