/**
 * 1.新しい商品追加された場合、UniqueKey__c にて、新しいrecord生成されます(upsert)。
 * 2.UniqueKey__c:OLY财年,第三分类,新4.5分类
ET_Product_ScoreTable_Batch bat = new ET_Product_ScoreTable_Batch ();
Database.executeBatch(bat);
 */
global without sharing class ET_Product_ScoreTable_Batch implements Database.Batchable<sObject>, Database.Stateful{

    //private BatchEmailUtil.BatchErrorBean eb = new BatchEmailUtil.BatchErrorBean(); // 邮件发送ERRORBEAN
    //private static final Integer MAXERRORCNT = 500; // 邮件表单位最大错误信息显示数量
    global Integer totalCount = 0; // 总件数
    global Integer executedCount = 0;
    global Integer successCount = 0; // 成功件数
    global Integer failedCount = 0;  // 失败件数
    global Set<String> createdList;
    global Set<String> updatedList;
    global Set<String> failedList;
    global Boolean isAllFlag = false;
    global Integer testSkip = 0;

    global ET_Product_ScoreTable_Batch(){
        createdList = new Set<String> ();
        updatedList = new Set<String> ();
        failedList = new Set<String> ();

        testSkip++;
        testSkip++;
        testSkip++;
        testSkip++;
        testSkip++;
        testSkip++;
        testSkip++;
        testSkip++;
        testSkip++;
        testSkip++;
        testSkip++;
        testSkip++;
        testSkip++;
        testSkip++;
        testSkip++;
        testSkip++;
        testSkip++;
        testSkip++;
        testSkip++;
        testSkip++;
        testSkip++;
        testSkip++;
        testSkip++;
        testSkip++;
        testSkip++;
        testSkip++;
        testSkip++;
        testSkip++;
        testSkip++;
        testSkip++;
        testSkip++;
        testSkip++;
        testSkip++;
        testSkip++;
        testSkip++;
        testSkip++;
        testSkip++;
        testSkip++;
        testSkip++;
        testSkip++;
        testSkip++;
        testSkip++;
        testSkip++;
        testSkip++;
        testSkip++;
        testSkip++;
        testSkip++;
        testSkip++;
    }

    global Database.QueryLocator start(Database.BatchableContext BC){
        System.debug('********** ET_Product_ScoreTable_Batch .start');
        
        Date systemDate = system.today();
        systemDate = systemDate.addDays(-Integer.valueof(System.Label.ET_Date_Calculate));
        //system.debug('systemDate ' + systemDate);
        Set<String> s = new Set<String>{'停止','有効','有効（再申請中）','失効（期限内生産済在庫対応）'};

        Product2 p = [SELECT Plan_Term__c FROM Product2
            WHERE Is_ET_APP__c = TRUE
            AND Category3__c <> ''
            AND SFDA_Status__c IN :s
            LIMIT 1];
        String term = p.Plan_Term__c.left(4);

        /*
         *  按年筛选本次 Batch 产生/更新的行
         */
        Product_Score_Table__c [] psts = [
                SELECT Id
                FROM  Product_Score_Table__c
                WHERE OCM_Term__c = :term
        ];
        /*
         *  清除表中临时统计信息
         */
        for(Product_Score_Table__c  pst: psts) {
            pst.put('Is_Disabled__c', true);
        }
        update psts;

        //商品取得
        String query = 'SELECT Id, Family, Plan_Term__c, SFDA_Status__c, Is_ET_APP__c, Asset_Model_No__c,' +
                        ' Category3__c, Category4__c, Category5__c, Plan_Category3__c, Plan_Category4__c' + 
                        ' FROM Product2' +
                        // ' where Is_ET_APP__c = true ';
                        ' where Is_ET_APP__c = true '+
                        ' and Category5__c !=\'竞争对手\'';
        // if (true != this.isAllFlag) {
        //        query += ' and LastModifiedDate >= :systemDate ';
        // }
               // query += ' and SFDA_Status__c in :s';
        return Database.getQueryLocator(query);
    }

    global void execute(Database.BatchableContext BC, List<Product2> productList){
        totalCount += productList.size();

        System.debug('ET_Product_ScoreTable_Batch execute start');

        Set<String> validStatus = new Set<String>{'停止','有効','有効（再申請中）','失効（期限内生産済在庫対応）'};
        //upsert产品得分表
        //List<Product_Score_Table__c> pstUpsertList =  new List<Product_Score_Table__c>();
        Map<String,Product_Score_Table__c> pstUpsertList =  new Map<String,Product_Score_Table__c>();
        Set<String> unDisabledList = new Set<String>();
        //system.debug(productList.size());
        if(!productList.isEmpty()){
            for (Product2 pd : productList){
                Product_Score_Table__c pst = new Product_Score_Table__c();
                //计画财年 151P, 152P 产品的计画财年前三码+P
                pst.OCM_Term__c = pd.Plan_Term__c.left(4);
                //第1分类
                pst.Category1__c = pd.Family;
                //重点第3分类
                pst.Plan_Category3__c = pd.Plan_Category3__c;
                //重点第4分类
                pst.Plan_Category4__c = pd.Plan_Category4__c;
                //第3分类
                pst.Category3__c = pd.Category3__c; 
                //第4分类
                pst.Category4__c = pd.Category4__c; 
                //UniqueKey : 151P+第三分类+第4分类
                pst.UniqueKey__c = pst.OCM_Term__c + ':' + pst.Category3__c + ':' + pst.Category4__c;

                if ('吸引活检针' == pd.Category4__c && 'EUS' == pd.Category3__c) {
                    if (pd.Asset_Model_No__c.startsWith('NA-U200H')) {
                        pst.Category4__c = '吸引活检针-EZ3P';
                        pst.Plan_Category4__c = '吸引活检针-EZ3P';
                        pst.UniqueKey__c = pst.OCM_Term__c + ':' + pst.Category3__c + ':吸引活检针-EZ3P';
                    } else {
                        pst.Category4__c = '吸引活检针-EZ3P以外';
                        pst.Plan_Category4__c = '吸引活检针-EZ3P以外';
                        pst.UniqueKey__c = pst.OCM_Term__c + ':' + pst.Category3__c + ':吸引活检针-EZ3P以外';
                    }
                } else if ('先端系粘膜切开刀' == pd.Category4__c && 'ESD' == pd.Category3__c) {
                    if (pd.Asset_Model_No__c.startsWith('KD-655')) {
                        pst.Category4__c = '先端系粘膜切开刀-DualJ';
                        pst.Plan_Category4__c = '先端系粘膜切开刀-DualJ';
                        pst.UniqueKey__c = pst.OCM_Term__c + ':' + pst.Category3__c + ':先端系粘膜切开刀-DualJ';
                    } else {
                        pst.Category4__c = '先端系粘膜切开刀-DualJ以外';
                        pst.Plan_Category4__c = '先端系粘膜切开刀-DualJ以外';
                        pst.UniqueKey__c = pst.OCM_Term__c + ':' + pst.Category3__c + ':先端系粘膜切开刀-DualJ以外';
                    }
                }

                //是否无效
                if (unDisabledList.contains(pst.UniqueKey__c)) {
                    pst.Is_Disabled__c = false;
                } else {
                    if (validStatus.contains(pd.SFDA_Status__c)) {
                        unDisabledList.add(pst.UniqueKey__c);
                        pst.Is_Disabled__c = false;
                    } else {
                        pst.Is_Disabled__c = true;
                    }
                }
                //pstUpsertList.add(pst);
                pstUpsertList.put(pst.UniqueKey__c,pst);
            }
        }

        for(Product_Score_Table__c tmpObj : [SELECT Id, UniqueKey__c, Is_Disabled__c
                FROM Product_Score_Table__c
                WHERE UniqueKey__c IN :pstUpsertList.keySet()]){
            if (false == tmpObj.Is_Disabled__c) {
                pstUpsertList.remove(tmpObj.UniqueKey__c);
            } else {
                Product_Score_Table__c pstUpsertItem = pstUpsertList.get(tmpObj.UniqueKey__c);
                if (unDisabledList.contains(tmpObj.UniqueKey__c)) {
                    pstUpsertItem.Is_Disabled__c = false;
                } else {
                    pstUpsertItem.Is_Disabled__c = true;
                }
                pstUpsertList.put(tmpObj.UniqueKey__c, pstUpsertItem);
            }
        }
        if(!pstUpsertList.isEmpty()){
            //System.debug('pstUpsertList.size '+pstUpsertList.size());
            Database.UpsertResult [] results = Database.upsert(pstUpsertList.values(), Product_Score_Table__c.UniqueKey__c,false );
            //System.debug('results.size '+results.size());
            for(Integer index = 0; index < results.size(); index++) {
                if(results[index].isSuccess()) { 
                    if(results[index].isCreated()) {
                        createdList.add(results[index].getId());
                    } else if(!createdList.contains(results[index].getId())){
                        updatedList.add(results[index].getId());
                    } else {
                        // do nothing
                    }
                }
                else{
                    for (Database.Error err : results[index].getErrors()) {
                        String message = 'UniqueKey :' + pstUpsertList.values()[index].UniqueKey__c + ' ; '
                        + err.getStatusCode() + '; '
                        + err.getFields() + ' ; '
                        + err.getMessage();
                        failedList.add(message);
                    }
                }
            }
        }

        executedCount += productList.size();
        System.debug('ET_Product_ScoreTable_Batch execute end');
    }  
    global void finish(Database.BatchableContext BC){
        System.debug('ET_Product_ScoreTable_Batch finish method start');
        String title = '产品得分表Batch';
        String messagesPlanText = '';
        String tempText = '';
        for(string s : createdList){
            successCount += 1;
            //messagesPlanText += s+' 已建立\n';
        }
        for(string s : updatedList){
            successCount += 1;
            //messagesPlanText += s+' 已更新\n';
        }
        for(string s : failedList){
            failedCount += 1;
            messagesPlanText += s+'\n';
        }
        
        BatchEmailUtil eb = new BatchEmailUtil();
        String[] emailList = new String[] {};
        // 失败件数为0 寄出成功的mail
        if (failedCount == 0 && totalCount == executedCount) {
            String emailLabel = 'BatchNotify';
            for (OrgWideEmailAddress tmpEmailObj : [SELECT Id, Address, DisplayName 
                FROM OrgWideEmailAddress
                WHERE DisplayName = :emailLabel]) {
                    emailList.add(tmpEmailObj.Address);
            }
            eb.successMail(emailList, null, title, executedCount);
        }
        else {
            if (totalCount != executedCount) {
                messagesPlanText += '有一部分Batch没有运行, 请确认系统管理员。\n';
            }
            eb.failedMail(title, messagesPlanText, totalCount, executedCount, failedCount);
        }
        eb.send();

        System.debug('ET_Product_ScoreTable_Batch finish method end');
    }
}