// todo 可用 report api实现
// <runtest>FixtureRemindControllerTest</runtest>
// <runtest>FixtureRemindBatchTest</runtest>
public without sharing class FixtureRemindUtil {
    public Map<String, Integer> eastMap {set;get;} // 华东
    public Map<String, Integer> eastConsumMap {set;get;} // 华东耗材
    public Map<String, Integer> southMap {set;get;} // 南方
    public Map<String, Integer> northMap {set;get;} // 北方
    public Map<String, Integer> totalMap {set;get;} // 合计
    public final static List<String> STATUS_LIST {set;get;}
    public final static List<String> CONSUM_STATUS_LIST {set;get;}
    private static Map<String, String> RENTAL_DETAIL_WHERE_MAP;
    private static Map<String, String> CONSUM_DETAIL_WHERE_MAP;
    private static Map<String, String> RENTAL_APPLY_WHERE_MAP;
    private static Map<String, String> CONSUM_APPLY_WHERE_MAP;
    private static Map<String, String> STATUS_NAME_MAP;
    private static Map<String, String> CONSUM_STATUS_NAME_MAP;
    private static Map<String, String> LABEL_API_MAP;
    private OlympusCalendar__c today;
    private String nowTimeOption; 
    public FixtureRemindUtil(){
        northMap = new Map<String, Integer>();
        southMap = new Map<String, Integer>();
        eastMap = new Map<String, Integer>();
        eastConsumMap = new Map<String, Integer>();
        totalMap = new Map<String, Integer>();
        try{
            today = [SELECT Before_1_WorkDay__c FROM OlympusCalendar__c WHERE Date__c=:System.today()];
        }
        catch(Exception e){
            today = new OlympusCalendar__c(Date__c=System.today(), Before_1_WorkDay__c = System.today().addDays(-1));
        }
        nowTimeOption = nowTimeToOption();
    }
    public void init() {

        resetAllMaps();
        List<Rental_Apply_Equipment_Set_Detail__c> raesdList = [
            SELECT RAESD_Status_Text__c
                 , Rental_Apply__r.Loaner_centre_mail_address__c
                 , Lost_item_check_time_Final__c
                 , Repair_Status_F__c
                 , Return_DeliverySlip__c
                 , EquipmentSet_Detail_Status_Status__c
              FROM Rental_Apply_Equipment_Set_Detail__c
             WHERE ((Is_Body_F__c = true 
                       AND (RAESD_Status_Text__c IN:STATUS_NAME_MAP.keySet()
                            // or 待欠品确认件数
                            OR (RAESD_Status_Text__c = '欠品中' AND Return_DeliverySlip__c != null)
                            // or 待回收后检测件数
                            OR (RAESD_Status_Text__c = '修理中' AND Repair_Status_F__c = '修理完毕')
                        )
                    )
                // or 欠品中件数
                //OR (RAESD_Status_Text__c = '欠品中' AND Lost_item_check_time_Final__c >= :today.Before_1_WorkDay__c)
                //update lxy 2021/10/13 去掉欠品确认时间（最终）≥上一个工作日条件
                //update by rentx 2021-10-18 start 
                 OR (RAESD_Status_Text__c = '欠品中')
                // or 待修理
                OR (RAESD_Status_Text__c = '待修理' AND Is_Body_F__c = false))
                //SFDC-BZT44W add by rentx 2021-04-07 start 
                AND Rental_Apply__r.RecordType.DeveloperName != 'AgencyRequest'
                //SFDC-BZT44W add by rentx 2021-04-07 end
        ];

        for(Rental_Apply_Equipment_Set_Detail__c  raesd : raesdList) {
            String show_status = '';
            if(STATUS_NAME_MAP.containsKey(raesd.RAESD_Status_Text__c)) {
                show_status = STATUS_NAME_MAP.get(raesd.RAESD_Status_Text__c);
            }
            else if (raesd.RAESD_Status_Text__c == '欠品中' && raesd.Return_DeliverySlip__c != null) {
                show_status = '待欠品确认件数';
            }
            //else if(raesd.RAESD_Status_Text__c == '欠品中' && raesd.Lost_item_check_time_Final__c >= today.Before_1_WorkDay__c){
            //update lxy 2021/10/13 去掉欠品确认时间（最终）≥上一个工作日条件
            // else if(raesd.RAESD_Status_Text__c == '欠品中'){
            //     show_status = '欠品中件数';
            // }
            //update by rentx 欠品未回寄并且是主体或者是附属品的  状态不是 确认遗失 start
            else if(raesd.RAESD_Status_Text__c == '欠品中' && raesd.EquipmentSet_Detail_Status_Status__c != '确认遗失' ){
                show_status = '欠品中件数';
            }
            //update by rentx 欠品未回寄并且是主体或者是附属品的  状态不是 确认遗失 end
            else if(raesd.RAESD_Status_Text__c == '修理中' && raesd.Repair_Status_F__c == '修理完毕'){
                show_status = '待回收后检测件数';
            }
            else {
                continue;
            }
            if(String.isNotBlank(raesd.Rental_Apply__r.Loaner_centre_mail_address__c)){
                switch on raesd.Rental_Apply__r.Loaner_centre_mail_address__c.toLowerCase() {
                    when 'ocm_asset@olympus.com.cn'{
                        northMap.put(show_status, northMap.get(show_status) + 1);
                    }
                    when 'ocm_assetgz@olympus.com.cn'{
                        southMap.put(show_status, southMap.get(show_status) + 1);
                    }
                    when 'ocm_assetsh@olympus.com.cn'{
                        eastMap.put(show_status, eastMap.get(show_status) + 1);
                    }
                }
            }
        }
        // 待确认签收数
        List<Rental_Apply__c> raList = [
                SELECT Id
                     , Loaner_centre_mail_address__c
                FROM Rental_Apply__c
                WHERE Bollow_Date__c != null
                AND HP_received_sign_day__c != null
                AND AssetManageConfirm__c = false
                AND HP_received_sign_NG__c = false
                AND RA_Status__c != '完了'
                // SFDC-BZT44W add by rentx 2021-04-07 start
                AND RecordType.DeveloperName != 'AgencyRequest'
                //SFDC-BZT44W add by rentx 2021-04-07 end
        ];
        for(Rental_Apply__c ra:raList){
            if(String.isNotBlank(ra.Loaner_centre_mail_address__c)){
                switch on ra.Loaner_centre_mail_address__c.toLowerCase() {
                    when 'ocm_asset@olympus.com.cn'{
                        northMap.put('待确认签收单数', northMap.get('待确认签收单数') + 1);
                    }
                    when 'ocm_assetgz@olympus.com.cn'{
                        southMap.put('待确认签收单数', southMap.get('待确认签收单数') + 1);
                    }
                    when 'ocm_assetsh@olympus.com.cn'{
                        eastMap.put('待确认签收单数', eastMap.get('待确认签收单数') + 1);
                    }
                }
            }
        }
        for(String show_status:totalMap.keySet()){
            totalMap.put(show_status, eastMap.get(show_status) + southMap.get(show_status) + northMap.get(show_status));
        }
        // 耗材部分
        List<Consum_Apply_Equipment_Set_Detail__c > caesdList = [
                SELECT RAESD_Status__c
                     , Asset_Center_Confirm_Time__c
                     , Consum_Apply__r.AssetManageConfirm__c
                  FROM Consum_Apply_Equipment_Set_Detail__c
                 WHERE RAESD_Status__c IN:CONSUM_STATUS_NAME_MAP.keySet()
                    OR (RAESD_Status__c='申请者收货NG' AND Asset_Center_Confirm_Time__c = null)
                    OR (RAESD_Status__c='已回寄' AND Consum_Apply__r.AssetManageConfirm__c = true)
        ];
        Set<Id> caIdSet = new Set<Id>();
        for(Consum_Apply_Equipment_Set_Detail__c   caesd : caesdList){
            String show_status = '';
            if(CONSUM_STATUS_NAME_MAP.containsKey(caesd.RAESD_Status__c)) {
                show_status = CONSUM_STATUS_NAME_MAP.get(caesd.RAESD_Status__c);
            }
            else if (caesd.RAESD_Status__c == '申请者收货NG'
                && caesd.Asset_Center_Confirm_Time__c == null){
                show_status = '到货NG待确认数量';
            }
            else if(caesd.RAESD_Status__c == '已回寄'
                && caesd.Consum_Apply__r.AssetManageConfirm__c){
                show_status = '待收货件数';
            }
            else {
                continue;
            }
            eastConsumMap.put(show_status, eastConsumMap.get(show_status) + 1);
        }
        List<Consum_Apply__c> caList = [
                SELECT Id
                FROM Consum_Apply__c
                WHERE Bollow_Date__c != null
                  AND Consum_Trial_Update_Time__c != null
                  AND AssetManageConfirm__c = false
                  AND HP_received_sign_NG__c = false
                  AND RA_Status__c != '完了'
                  AND RA_Status__c != '取消'
        ];
        eastConsumMap.put('待确认试用表数量', caList.size());
    }
    // 按给定状态列表初始化map
    private void initStatusMap(Map<String, Integer> tempMap, List<String> show_status_list) {
        for(String show_status : show_status_list){
            tempMap.put(show_status, 0);
        }
    }
    public void resetAllMaps() {
        initStatusMap(northMap, STATUS_LIST);
        initStatusMap(southMap, STATUS_LIST);
        initStatusMap(eastMap, STATUS_LIST);
        initStatusMap(totalMap, STATUS_LIST);
        initStatusMap(eastConsumMap, CONSUM_STATUS_LIST);
    }
    static {
        STATUS_LIST = new List<String> {
            '待分配件数',
            '暂定分配件数',
            '排队中件数',
            '待出库指示件数',
            '待下架件数',
            '待出库前检测件数',
            '待发货件数',
            '待确认签收单数',
            '待欠品确认件数',
            '待CDS件数',
            '待回收后检测件数',
            '待上架件数',
            '欠品中件数',
            '待报修件数'
        };
        CONSUM_STATUS_LIST = new List<String> {
            '待分配件数',
            '待出库指示件数',
            '待发货件数',
            '到货NG待确认数量',
            '待确认试用表数量',
            '待收货件数'
        };
        // 借出明细状态名 => 显示状态名
        STATUS_NAME_MAP = new Map<String, String> {
            FixtureUtil.raesdStatusMap.get(FixtureUtil.HistoryStatus.Dai_Fen_Pei.ordinal())       => '待分配件数',
            FixtureUtil.raesdStatusMap.get(FixtureUtil.HistoryStatus.Zan_Ding_Fen_Pei.ordinal())  => '暂定分配件数',
            FixtureUtil.raesdStatusMap.get(FixtureUtil.HistoryStatus.Pai_Dui_Zhong.ordinal())          => '排队中件数',
            FixtureUtil.raesdStatusMap.get(FixtureUtil.HistoryStatus.Yi_Fen_Pei.ordinal())       => '待出库指示件数',
            FixtureUtil.raesdStatusMap.get(FixtureUtil.HistoryStatus.Yi_Chu_Ku_Zhi_Shi.ordinal())       => '待下架件数',
            FixtureUtil.raesdStatusMap.get(FixtureUtil.HistoryStatus.Yi_Xia_Jia.ordinal())          => '待出库前检测件数',
            FixtureUtil.raesdStatusMap.get(FixtureUtil.HistoryStatus.Chu_Ku_Qian_Yi_Jian_Ce.ordinal())     => '待发货件数',
            FixtureUtil.raesdStatusMap.get(FixtureUtil.HistoryStatus.Yi_Hui_Ji.ordinal())     => '待欠品确认件数',
            FixtureUtil.raesdStatusMap.get(FixtureUtil.HistoryStatus.Yi_Hui_Shou.ordinal())             => '待CDS件数',
            FixtureUtil.raesdStatusMap.get(FixtureUtil.HistoryStatus.Hui_Shou_Hou_Yi_CDS.ordinal()) => '待回收后检测件数',
            FixtureUtil.raesdStatusMap.get(FixtureUtil.HistoryStatus.Dai_Shang_Jia.ordinal()) => '待上架件数',
            FixtureUtil.raesdStatusMap.get(FixtureUtil.HistoryStatus.Yi_Zhi_Bao_Fei_Qu.ordinal()) => '待上架件数',
            FixtureUtil.raesdStatusMap.get(FixtureUtil.HistoryStatus.Dai_Xiu_Li.ordinal()) => '待报修件数'
        };
        // 耗材明细状态名 => 显示状态名
        CONSUM_STATUS_NAME_MAP = new Map<String, String> {
            '待分配'      => '待分配件数',
            '暂定分配'    => '待分配件数',
            '已分配'      => '待出库指示件数',
            '已出库指示'  => '待发货件数'
        };
        //
        LABEL_API_MAP = createLabelApiMap();
    }
    // 创建快照记录
    public FixtureRemindSnapshot__c createSnapshotRecord(String region) {
        FixtureRemindSnapshot__c frs = new FixtureRemindSnapshot__c();
        Map<String, Integer> snapMap = null;
        switch on region {
            when '华东'{
                for(String label : this.eastConsumMap.keySet()){
                    String objlabel = label + '(耗材)';
                    String api = LABEL_API_MAP.get(objlabel);
                    frs.put(api, this.eastConsumMap.get(label));
                }
                snapMap = this.eastMap;
            }
            when '北方'{
                snapMap = this.northMap;
            }
            when '南方'{
                snapMap = this.southMap;
            }
        }
        for(String label : snapMap.keySet()){
            String api = LABEL_API_MAP.get(label);
            frs.put(api, snapMap.get(label));
        }

        frs.Date__c = System.today();
        frs.Time__c = nowTimeOption;
        frs.Region__c = region;
        return frs;
    }
    // 时间=> 字段列表中选项
    @TestVisible private String nowTimeToOption() {
        DateTime now = System.now();

        if(now.time() < Time.newInstance(11,30,0,0)) {
            return '09:00';
        } 
        else if(now.time() < Time.newInstance(13,0,0,0)) {
            return '11:30';
        }
        else if(now.time() < Time.newInstance(14,0,0,0)){
            return '13:00';
        }
        else if(now.time() < Time.newInstance(15,0,0,0)){
            return '14:00';
        }
        else if(now.time() < Time.newInstance(17,30,0,0)){
            return '15:00';
        }
        else{
            return '17:30';
        }
    }
    // label=>api
    @TestVisible private static Map<String, String> createLabelApiMap(){
        Map<String,String> apiMap = new Map<String,String>();
        SObjectType sotype = Schema.getGlobalDescribe().get('FixtureRemindSnapshot__c');
        Map<String,Schema.SObjectField> mfields = sotype.getDescribe().fields.getMap();
        for(String strField:mfields.keySet()) {
            SObjectField fl = mfields.get(strField);
            apiMap.put(fl.getDescribe().getlabel(), strField);
        }
        return apiMap;
    }

}