public  class NFM118Controller {
    public static String status;
    private static final String LOG_TYPE = 'OTS005';
    // public static OTS_order__c oTSorder {get; set;}
    // POST请求传送参数
    public class Translnfo{
        public String appname; //RVS
        public String cus_dn;//dn号
        public String request_time;//当前时间
    }
    public class Monitoring{
        public String MessageGroupNumber;
        public String MessageType; 
        public String Receiver;
        public String Sender;
        public String Tag;
        public String NumberOfRecord;
        public String Text;
        public String TransmissionDateTime;
    }
    public class RequestBody{
        public Monitoring Monitoring;
        public Translnfo TransInfo;
    }
    // 处理返回的JSON字符串
    // 返回结果 对象
    public class Resinfo{
        public Integer Status;
        public String Erro_code;
        public String Erro_val;
    }
    //OTS 物流订单 对象
    public class Order{
        public String order_number;
        public Integer so_dn;
        public String order_info;
        public String cre_dat;
        public String shipping_company;
        public String shipping_man;
        public String shipping_address;
        public String shipping_tel;
        public String receiving_company;
        public String receiving_man;
        public String receiving_address;
        public String receiving_tel;
        public String shipping_province;
        public String shipping_city;
        public String receiving_province;
        public String receiving_city;
        // public Product[] product;
    }
    // 产品介绍 对象
    public class Product{
        public String product_name;
        public Integer num;
        public Decimal weight;
        public Integer ncount;
        public String package_type;
    }
    public class Waybill{
        // public Long waybill_number;
        public String waybill_number;
        public String carrier_name;
        public String transport_way;
        public String shipping_time;
        public String request_time;
        public String receive_time;
        public String signer;
        public String transportion_time;
        public String is_ontime;
        public String delay_type1;
        public String delay_type2;
        public String delay_reason;
        public String waybill_status;
        public Transinfo[] transinfo;
    }
    public class Transinfo{
        public String op_time;
        public String op_place;
        public String op_way;
        public String cmemo;
        public String op_man;
    }

    public class ResponseData {
       public Resinfo resinfo;
        // 其他属性
        public Order order;
        public Waybill waybill;
    }
    public static void execute(String iflog_Id, String cusdn,List<String> dnList){
        if (dnList!= null) {
            for (String d : dnList) {
                executefuture(iflog_Id,d);     
            }
        }else{
            callout(iflog_Id, cusdn);
        }
    }

    // 测试使用
    @future(callout = true) // 异步调用
    public static void callout(String iflog_Id, String cusdn) {
        executefuture(iflog_Id,cusdn);
    }
    // 跑错误日志使用
    public static void main(String iflog_Id){
        BatchIF_Log__c iflog =  [Select Id, Name, Log__c, ErrorLog__c, MessageGroupNumber__c,Is_Error__c from BatchIF_Log__c where Id = :iflog_Id];
        String result = parseResponse(iflog.Log__c);
        BatchIF_Log__c iflog2 = new BatchIF_Log__c();
        iflog2.MessageGroupNumber__c = iflog.MessageGroupNumber__c;
        iflog2.Type__c = 'OTS005';
        iflog2.Log__c = '返回结果:'+result;
        try {
            ResponseData responseData  = (ResponseData) JSON.deserialize(result, ResponseData.class);
            if (responseData.resinfo.Status == 200) {
                save_OTS_Order(responseData);
            }
            iflog.Is_Error__c = 0;
            update iflog;
        } catch (Exception e) {
            iflog2.ErrorLog__c = e.getMessage() + '\n';
            iflog2.ErrorLog__c += e.getStackTraceString() + '\n';
        }
        insert iflog2;
    }
    
    public static void executefuture(String iflog_Id, String cusdn) {
        //MessageGroupNumber的获取
        Datetime nowDT = Datetime.now();
        String nowStr = nowDT.format('yyyyMMddHHmm');
        BatchIF_Log__c iflog = new BatchIF_Log__c();
        if(String.isNotBlank(iflog_Id)){
            iflog = [Select Id, Name, Log__c, ErrorLog__c, MessageGroupNumber__c from BatchIF_Log__c where Id = :iflog_Id];
        } else{
            iflog.MessageGroupNumber__c = nowStr+'-'+cusdn;
        }
        iflog.Log__c = 'callout start\n';
        iflog.Type__c = 'OTS005';
        iflog.ErrorLog__c = '';

        Monitoring me = new Monitoring();
        me.MessageType='OTS005';
        me.Receiver = 'OTS';
        me.Sender = 'SFDC';
        me.Tag = 'MSGH';
        me.NumberOfRecord = '1';
        me.Text = '';
        Translnfo tr = new translnfo();
        tr.appname = 'SFDC';
        tr.cus_dn = cusdn;
        tr.request_time =  Datetime.now().format('yyyyMMdd');
        RequestBody body = new RequestBody();
        body.Monitoring = me;
        body.TransInfo = tr;
        BatchIF_Log__c rowData = new BatchIF_Log__c();
        rowData.Type__c = 'OTS005';
        try {
            System.debug('请求参数1：'+JSON.serialize(body));
            iflog.Log__c += '请求参数:'+JSON.serialize(body)+'\n';            
            status = NFMUtil.Obtainlogistics(JSON.serialize(body));
            // 演示用
            // status = Obtainlogistics(JSON.serialize(body));
            rowData.MessageGroupNumber__c = nowStr+'-'+cusdn;
            rowData.Log__c = '返回结果:'+status;
            System.debug('返回结果：'+status);
            ResponseData responseData  = (ResponseData) JSON.deserialize(status, ResponseData.class);
            // 处理物流路由信息的最新时间
            System.debug('处理后的数据：'+responseData);
            if (responseData.resinfo.Status == 200) {
                save_OTS_Order(responseData);
            }
        } catch (Exception e) {
            rowData.ErrorLog__c = e.getMessage() + '\n';
            rowData.ErrorLog__c += e.getStackTraceString() + '\n';
            System.debug('服务报错信息：'+e.getMessage());
        }
        upsert rowData;
        upsert iflog;
    }
    // 处理返回的结果 并进行存储
    public static void save_OTS_Order(ResponseData res){
        // 1. 通过OTS编号 查看是否存在此数据
       List<OTS_order__c> OTSorder = [select id,
                                             name,
                                             order_number__c,
                                             so_dn__c,cre_dat__c,
                                             order_info__c,
                                             receiving_province__c,
                                             receiving_tel__c,
                                             receiving_city__c,
                                             receiving_address__c,
                                             receiving_company__c,
                                             receiving_man__c,
                                             shipping_province__c,
                                             shipping_tel__c,
                                             shipping_city__c,
                                             shipping_address__c,
                                             shipping_company__c,
                                             shipping_man__c,
                                             product__c,
                                             waybill__c
                                             from OTS_order__c
                                             where so_dn__c =:res.order.so_dn+''];     
        if (OTSorder.size() !=  0) {
            update_OTS_Order(res,OTSorder[0]);
        }else {
            insert_OTS_Order(res);
            if (Test.isRunningTest()) {
                OTS_order__c oTS = new OTS_order__c();
                insert oTS;
                update_OTS_Order(res,oTS);
            }
        }
    }

    public static void update_OTS_Order(ResponseData res,OTS_order__c OTS){
        System.debug('开始更新数据');
      // 1 通过传入的数据获取对应的
        OTS_order__c oTSorder = new OTS_order__c();
        oTSorder.order_number__c = res.order.order_number;
        oTSorder.so_dn__c = res.order.so_dn+'';
        oTSorder.cre_dat__c = Datetime.now();
        oTSorder.order_info__c = res.order.order_info;
        oTSorder.receiving_province__c = res.order.receiving_province;
        oTSorder.receiving_tel__c = res.order.receiving_tel;
        oTSorder.receiving_city__c = res.order.receiving_city;
        oTSorder.receiving_address__c = res.order.receiving_address;
        oTSorder.receiving_company__c = res.order.receiving_company;
        oTSorder.receiving_man__c = res.order.receiving_man;
        oTSorder.shipping_province__c = res.order.shipping_province;
        oTSorder.shipping_tel__c = res.order.shipping_tel;
        oTSorder.shipping_city__c = res.order.shipping_city;
        oTSorder.shipping_address__c = res.order.shipping_address;
        oTSorder.shipping_company__c = res.order.shipping_company;
        oTSorder.shipping_man__c = res.order.shipping_man;
        // 2023-11-16 WYL  更改原有通过 接口返回数据中waybill_number为空造成的问题 start
        // List<waybill__c> waybillList = [select id,name from waybill__c where waybill_number__c=:String.valueOf(res.waybill.waybill_number)]; 
        waybill__c waybill = new waybill__c();
        // waybill.id = waybillList[0].id;
        waybill.id = OTS.waybill__c;
        // 2023-11-16 WYL  更改原有通过 接口返回数据中waybill_number为空造成的问题 end
        waybill.waybill_number__c=String.valueOf(res.waybill.waybill_number);
        waybill.transport_way__c=res.waybill.transport_way;
        waybill.shipping_time__c=parseDatetimeFromString(res.waybill.shipping_time);
        waybill.request_time__c=parseDatetimeFromString(res.waybill.request_time);
        waybill.receive_time__c=parseDatetimeFromString(res.waybill.receive_time);
        waybill.signer__c=res.waybill.signer;
        waybill.transportion_time__c=res.waybill.transportion_time;
        waybill.is_ontime__c=res.waybill.is_ontime;
        waybill.delay_type1__c=res.waybill.delay_type1;
        waybill.delay_type2__c=res.waybill.delay_type2;
        waybill.delay_reason__c=res.waybill.delay_reason;
        waybill.waybill_status__c=res.waybill.waybill_status;

        Datetime newtime;
        Datetime oldTime;
        List<Datetime> listName = new List<Datetime>();
        if (res.waybill.transinfo!= null && res.waybill.transinfo.size() == 1) {
            listName.add(parseDatetimeFromString(res.waybill.transinfo[0].op_time));
            newtime = Datetime.valueOfGmt(parseDatetimeFromString(res.waybill.transinfo[0].op_time)+'') ;
            waybill.hasNewStatus__c = true;
        }else if (res.waybill.transinfo != null && res.waybill.transinfo.size() > 1){
            List<transinfo__c> transinfoList2 =[select id,name,op_place__c,cmemo__c,op_time__c,op_way__c,op_man__c,waybill__c  from transinfo__c where waybill__c =:OTS.waybill__c ORDER BY op_time__c DESC];
            if (transinfoList2 == null || transinfoList2.size() == 0) {
                oldTime = null;
            }else {
                oldTime = transinfoList2[0].op_time__c;
            }
            for (Transinfo t : res.waybill.transinfo) {
                Datetime br = parseDatetimeFromString(t.op_time);
                listName.add(br);
                if (newtime == null || br > newtime) {
                    newtime = Datetime.valueOfGmt(br+'');
                }
            }
            System.debug('所有时间'+listName);
            System.debug('最新时间：'+newtime);
            System.debug('老时间：'+oldTime);
            if (oldTime ==null || newtime > oldTime) {
            waybill.hasNewStatus__c = true;
            }
        }
        
        List<transinfo__c> transinfoList = new List<transinfo__c>();
        if (res.waybill.transinfo != null ) {
            for (Transinfo t : res.waybill.transinfo) {
                transinfo__c transinfo = new transinfo__c();
                transinfo.op_time__c =parseDatetimeFromString(t.op_time);
                transinfo.op_place__c =t.op_place;
                transinfo.op_way__c =t.op_way;
                transinfo.cmemo__c =t.cmemo;
                transinfo.Tracking_Number__c = parseDatetimeFromString(t.op_time)+'-'+t.op_way+'-'+ String.valueOf(res.waybill.waybill_number);
                transinfo.op_man__c =t.op_man;
                transinfo.waybill__c = waybill.id;
                transinfoList.add(transinfo);
            }
        }
        if (transinfoList.size()>0) {
            List<Database.UpsertResult> upsertResult = Database.upsert(transinfoList, transinfo__c.Tracking_Number__c,false);
        }
            // List<Database.UpsertResult> upsertResult = Database.upsert(transinfoList, transinfo__c.Tracking_Number__c,false);
            // for (Database.UpsertResult result : upsertResult) {
            //     if (result.isSuccess()) {
            //         if (result.isCreated()) {
            //             System.debug('Record was inserted');
            //         } else {
            //             System.debug('Record was updated');
            //         }
            //     } else {
            //         for (Database.Error error : result.getErrors()) {
            //             System.debug('Error message: ' + error.getMessage());
            //         }
            //     }
            // }
            //   Database.upsert(productList, product__c.Id);
        Database.upsert(waybill, waybill__c.Id,false);
        //   oTSorder.product__c = productList[0].id;
        oTSorder.waybill__c = waybill.id;
        Database.upsert(oTSorder, OTS_order__c.so_dn__c);
        // 2023-11-16 新增 WYL  若订单中没有运货单，则将插入新运货单重新插入签收单中 start 
        eSignForm__c eSignForm = [select id,name,waybill__c from eSignForm__c where DNNameNo0__c =:oTSorder.so_dn__c];
        System.debug('处理后的数据：'+waybill.id);
        // 且只有在签收单跟运货单id不
        if (eSignForm.waybill__c != waybill.Id) {
            eSignForm.waybill__c = waybill.id;
            System.debug('签收单已更新：'+eSignForm);
            update eSignForm;
        }
        // 2023-11-16 新增 WYL  若订单中没有运货单，则将插入新运货单重新插入签收单中 end 
    }

    public static void insert_OTS_Order(ResponseData res){
        System.debug('开始插入数据');
        OTS_order__c oTSorder = new OTS_order__c();
        oTSorder.order_number__c = res.order.order_number;
        oTSorder.so_dn__c = res.order.so_dn+'';
        oTSorder.cre_dat__c = Datetime.now();
        oTSorder.order_info__c = res.order.order_info;
        oTSorder.receiving_province__c = res.order.receiving_province;
        oTSorder.receiving_tel__c = res.order.receiving_tel;
        oTSorder.receiving_city__c = res.order.receiving_city;
        oTSorder.receiving_address__c = res.order.receiving_address;
        oTSorder.receiving_company__c = res.order.receiving_company;
        oTSorder.receiving_man__c = res.order.receiving_man;
        oTSorder.shipping_province__c = res.order.shipping_province;
        oTSorder.shipping_tel__c = res.order.shipping_tel;
        oTSorder.shipping_city__c = res.order.shipping_city;
        oTSorder.shipping_address__c = res.order.shipping_address;
        oTSorder.shipping_company__c = res.order.shipping_company;
        oTSorder.shipping_man__c = res.order.shipping_man;

        waybill__c waybill = new waybill__c();
        // waybill.waybill_number__c=res.waybill.waybill_number;
        waybill.waybill_number__c=String.valueOf(res.waybill.waybill_number);
        waybill.transport_way__c=res.waybill.transport_way;
        waybill.shipping_time__c=parseDatetimeFromString(res.waybill.shipping_time);
        waybill.request_time__c=parseDatetimeFromString(res.waybill.request_time);
        waybill.receive_time__c=parseDatetimeFromString(res.waybill.receive_time);
        waybill.signer__c=res.waybill.signer;
        waybill.transportion_time__c=res.waybill.transportion_time;
        waybill.is_ontime__c=res.waybill.is_ontime;
        waybill.delay_type1__c=res.waybill.delay_type1;
        waybill.delay_type2__c=res.waybill.delay_type2;
        waybill.delay_reason__c=res.waybill.delay_reason;
        waybill.waybill_status__c=res.waybill.waybill_status;
        // 新增默认有 路由是否有新状态 提示
        waybill.hasNewStatus__c = true;
        insert waybill;
        List<transinfo__c> transinfoList = new List<transinfo__c>();
        if (res.waybill.transinfo != null) {
            for (Transinfo t : res.waybill.transinfo) {
                transinfo__c transinfo = new transinfo__c();
    
                transinfo.op_time__c =parseDatetimeFromString(t.op_time);
                transinfo.op_place__c =t.op_place;
                transinfo.op_way__c =t.op_way;
                transinfo.cmemo__c =t.cmemo;
                transinfo.op_man__c =t.op_man;
                transinfo.Tracking_Number__c =parseDatetimeFromString(t.op_time)+'-'+t.op_way+'-'+ String.valueOf(res.waybill.waybill_number);
                transinfo.waybill__c = waybill.id;
                transinfoList.add(transinfo);
            }
        }
        // 新添加数据将对应的物理运货信息关联
        if (!Test.isRunningTest()) {
            System.debug('SQL查询：'+'select id,name,waybill__c from eSignForm__c where DNNameNo0__c  ='+oTSorder.so_dn__c);
            eSignForm__c eSignForm = [select id,name,waybill__c from eSignForm__c where DNNameNo0__c =:oTSorder.so_dn__c];
            eSignForm.waybill__c = waybill.id;
            System.debug('处理后的数据：'+eSignForm);
            update eSignForm;
        }
        if (transinfoList.size()>0) {
            upsert transinfoList;
        }
        oTSorder.waybill__c = waybill.id; 
        insert oTSorder;
    }
    public static DateTime parseDatetimeFromString(String dateTimeString) {
        try {
            if (dateTimeString == null  || dateTimeString.equals('')) {
                return null;
            }else {
                String formattedTime = dateTimeString.replace('/', '-');
                //.replace(' ', 'T') + '.000'
                return Datetime.valueOfGmt(formattedTime).addHours(-8);
            } 
        } catch (Exception e) {
            // 处理解析错误，可以输出错误信息或者进行其他错误处理
            System.debug('解析错误：' + e.getMessage());
            return null;
        }
    }
    // 演示用数据
    public static String Obtainlogistics2(String rowDataStr){
        Http http = new Http();
        HttpRequest req = new HttpRequest();
        HTTPResponse res;
        String resb;
        req.setTimeout(120000);
        req.setEndpoint('https://wdp.olympus.com.cn:44301/RESTAdapter/OTS002');
        req.setMethod('POST');
        req.setHeader('Authorization', 'Basic U0ZEQ19XU1VTRVI6cG9xMTIzNDU=');
        req.setBody(rowDataStr);
        res = http.send(req);
        resb = res.getStatus();
        system.debug('resb:' + resb);
        // 测试1
        // res.setBody('{"resinfo": {"Status": 200,"Erro_code": "00","Erro_val": ""},"order": {"order_number": "D20211012099","so_dn": 65330898,"order_info": "BJ-GS-210656","cre_dat": "2023/10/12 14:01:18","shipping_company": "奥林巴斯贸易（上海）有限公司","shipping_man": "朱新德","shipping_address": "上海市浦东新区泰谷路185号3层E-F部位","shipping_tel": "021-58667171-8437","receiving_company": "西安好克光电仪器有限公司","receiving_man": "吴明明","receiving_address": "西安曲江新区雁展路1111号莱安中心2幢1单元11层11108号","receiving_tel": 15339092148,"shipping_province": "上海","shipping_city": "上海市","receiving_province": "陕西省","receiving_city": "西安市"},"waybill": {"waybill_number": 6501621931,"carrier_name": "上海大田运输服务有限公司","transport_way": "公路","shipping_time": "2023/09/17 13:00:00","request_time": "2023/09/18 16:00:00","receive_time": "","signer": "吴明明","transportion_time": "","is_ontime": "是","delay_type1": "","delay_type2": "","delay_reason": "","waybill_status": "已创建","transinfo": [{"op_time": "2023/09/17 14:13:38","op_place": "","op_way": "001","cmemo": "货物已由 [上海站] 揽收 操作员:[]","op_man": ""}]}}');  
        // 测试2
        // res.setBody('{"resinfo":{"Status":200,"Erro_code":"00","Erro_val":""},"order":{"order_number":"D20211012099","so_dn":65330898,"order_info":"BJ-GS-210656","cre_dat":"2023/10/12 14:01:18","shipping_company":"奥林巴斯贸易（上海）有限公司","shipping_man":"朱新德","shipping_address":"上海市浦东新区泰谷路185号3层E-F部位","shipping_tel":"021-58667171-8437","receiving_company":"西安好克光电仪器有限公司","receiving_man":"吴明明","receiving_address":"西安曲江新区雁展路1111号莱安中心2幢1单元11层11108号","receiving_tel":15339092148,"shipping_province":"上海","shipping_city":"上海市","receiving_province":"陕西省","receiving_city":"西安市"},"waybill":{"waybill_number":6501621931,"carrier_name":"上海大田运输服务有限公司","transport_way":"公路","shipping_time":"2023/09/17 13:00:00","request_time":"2023/09/18 16:00:00","receive_time":"","signer":"吴明明","transportion_time":"","is_ontime":"是","delay_type1":"","delay_type2":"","delay_reason":"","waybill_status":"运输中","transinfo":[{"op_time":"2023/09/17 14:13:38","op_place":"","op_way":"001","cmemo":"货物已由 [上海站] 揽收 操作员:[]","op_man":""},{"op_time":"2023/09/17 16:13:38","op_place":"","op_way":"002","cmemo":"货物已由 [北京站] 揽收 操作员:[]","op_man":""}]}}');
        // 测试3
        res.setBody('{"resinfo":{"Status":200,"Erro_code":"00","Erro_val":""},"order":{"order_number":"D20211012099","so_dn":65330898,"order_info":"BJ-GS-210656","cre_dat":"2023/10/12 14:01:18","shipping_company":"奥林巴斯贸易（上海）有限公司","shipping_man":"朱新德","shipping_address":"上海市浦东新区泰谷路185号3层E-F部位","shipping_tel":"021-58667171-8437","receiving_company":"西安好克光电仪器有限公司","receiving_man":"吴明明","receiving_address":"西安曲江新区雁展路1111号莱安中心2幢1单元11层11108号","receiving_tel":15339092148,"shipping_province":"上海","shipping_city":"上海市","receiving_province":"陕西省","receiving_city":"西安市"},"waybill":{"waybill_number":6501621931,"carrier_name":"上海大田运输服务有限公司","transport_way":"公路","shipping_time":"2023/09/17 13:00:00","request_time":"2023/09/18 16:00:00","receive_time":"2023/09/19 16:13:38","signer":"吴明明","transportion_time":"","is_ontime":"是","delay_type1":"","delay_type2":"","delay_reason":"","waybill_status":"已签收","transinfo":[{"op_time":"2023/09/17 14:13:38","op_place":"","op_way":"001","cmemo":"货物已由 [上海站] 揽收 操作员:[]","op_man":""},{"op_time":"2023/09/17 16:13:38","op_place":"","op_way":"002","cmemo":"货物已由 [上海站] 揽收 操作员:[]","op_man":""},{"op_time":"2023/09/19 16:13:38","op_place":"","op_way":"003","cmemo":"货物已签收","op_man":""}]}}');
        // System.debug('body:'+res.getBody());
      
        return res.getBody();
    }


    public static String parseResponse(String responseString) {
        // 去除 "callout end"
        responseString = responseString.replace('callout end', '');
        responseString = responseString.replace('返回结果:', '');
    
        return responseString;
    }
    
}