public with sharing class SetProvinceTargetEngController {
    // 当前期
    public String currentPeriod { get; private set; }
    // 上年度按钮制御
    public boolean previousRendered { get; private set; }
    // 下年度按钮制御
    public boolean nextRendered { get; private set; }
    // 数据集
    public List<DataBean> dataBeans { get; set; }
    // 金额分类
    public List<String> opportunity_category { get; private set; }
    // 是否是过去年度
    public Boolean isPast { get; private set; }
    // 年度変化時セーブかどうか
    public Boolean saveFlg { get; set; }
    // 本部の選択値
    public String salesDpt { get; set; }
    
    public SetProvinceTargetEngController() {
        //Apexpages.currentPage().getHeaders().put('X-UA-Compatible', 'IE=8');
    }

    // 本部プルダウン
    public List<SelectOption> getSalesDptOpts() {
        List<SelectOption> salesDpt = new List<SelectOption>();
        salesDpt.add(new SelectOption('0.无','--无--'));
        salesDpt.add(new SelectOption('1.华北','1.华北'));
        salesDpt.add(new SelectOption('2.东北','2.东北'));
        salesDpt.add(new SelectOption('3.西北','3.西北'));
        salesDpt.add(new SelectOption('4.华东','4.华东'));
        salesDpt.add(new SelectOption('5.华南','5.华南'));
        salesDpt.add(new SelectOption('6.西南','6.西南'));
        return salesDpt;
    }
    
    //  现在年度
    private Integer currentYear;
    //  当前年度
    private Integer iYear;

    private String target_category;  // 省目标
    public User loginUser { get; set; }          // 登陆用户
    private RecordType rt;           // 目标的数据类型
    private Map<String, List<Double>> proportion;    // 比重
    
    private Map<String,List<String>> salesDptMap;  //本部-省对应关系
    private Map<String,String> provinceMap;        //省-本部对应关系
    
    // 既存目标数据
    private Map<String, Opportunity> oppsMap;
    // 金额分类
    //private static String[] amountCategory = new String[] {'GI','ET','BF','GS','URO','GYN','ENT','OTH'};
    private static String[] amountCategory = new String[] {'ENG'};
    
    // 画面初始化
    public Pagereference init() {
        // 现在时间
        Date dateNow = Date.today();
        Integer year = dateNow.year();
        Integer month = dateNow.month();
        if (month < 4) {
            year -= 1;
        }
        // 初始化
        currentYear = year;
        iYear = year;
        isPast = false;
        if (month == 3) isPast = true;
        currentPeriod = String.valueOf(iYear - 1867 + 'P');
        previousRendered = true;
        nextRendered = true;
        saveFlg = false;
        // 金额分类
        opportunity_category = amountCategory;
        // 每月比重
        if (proportion == null) {
            proportion = new Map<String, List<Double>>();
            String strObjectiveProportionGI = System.Label.ObjectiveProportionGI;
            List<String> objectiveProportionGI = strObjectiveProportionGI.split(',');
            List<Double> doubleGI = new List<Double>();
            for (String strGI : objectiveProportionGI) {
                doubleGI.add(Double.valueOf(strGI));
            }
            proportion.put('GI', doubleGI);

            String strObjectiveProportionET = System.Label.ObjectiveProportionET;
            List<String> objectiveProportionET = strObjectiveProportionET.split(',');
            List<Double> doubleET = new List<Double>();
            for (String strET : objectiveProportionET) {
                doubleET.add(Double.valueOf(strET));
            }
            proportion.put('ET', doubleET);

            String strObjectiveProportionBF = System.Label.ObjectiveProportionBF;
            List<String> objectiveProportionBF = strObjectiveProportionBF.split(',');
            List<Double> doubleBF = new List<Double>();
            for (String strBF : objectiveProportionBF) {
                doubleBF.add(Double.valueOf(strBF));
            }
            proportion.put('BF', doubleBF);

            String strObjectiveProportionGS = System.Label.ObjectiveProportionGS;
            List<String> objectiveProportionGS = strObjectiveProportionGS.split(',');
            List<Double> doubleGS = new List<Double>();
            for (String strGS : objectiveProportionGS) {
                doubleGS.add(Double.valueOf(strGS));
            }
            proportion.put('GS', doubleGS);

            String strObjectiveProportionURO = System.Label.ObjectiveProportionURO;
            List<String> objectiveProportionURO = strObjectiveProportionURO.split(',');
            List<Double> doubleURO = new List<Double>();
            for (String strURO : objectiveProportionURO) {
                doubleURO.add(Double.valueOf(strURO));
            }
            proportion.put('URO', doubleURO);

            String strObjectiveProportionGYN = System.Label.ObjectiveProportionGYN;
            List<String> objectiveProportionGYN = strObjectiveProportionGYN.split(',');
            List<Double> doubleGYN = new List<Double>();
            for (String strGYN : objectiveProportionGYN) {
                doubleGYN.add(Double.valueOf(strGYN));
            }
            proportion.put('GYN', doubleGYN);

            String strObjectiveProportionENT = System.Label.ObjectiveProportionENT;
            List<String> objectiveProportionENT = strObjectiveProportionENT.split(',');
            List<Double> doubleENT = new List<Double>();
            for (String strENT : objectiveProportionENT) {
                doubleENT.add(Double.valueOf(strENT));
            }
            proportion.put('ENT', doubleENT);

            String strObjectiveProportionOTH = System.Label.ObjectiveProportionOTH;
            List<String> objectiveProportionOTH = strObjectiveProportionOTH.split(',');
            List<Double> doubleOTH = new List<Double>();
            for (String strOTH : objectiveProportionOTH) {
                doubleOTH.add(Double.valueOf(strOTH));
            }
            proportion.put('OTH', doubleOTH);

            // CHAN-BBLCYP 2019/4/28 LHJ Start
            //String strObjectiveProportionENG = System.Label.ObjectiveProportionENG;
            String strObjectiveProportionENG = System.Label.ObjectiveProportionENGENG;
            // CHAN-BBLCYP 2019/4/28 LHJ End

            List<String> objectiveProportionENG = strObjectiveProportionENG.split(',');
            List<Double> doubleENG = new List<Double>();
            for (String strENG : objectiveProportionENG) {
                doubleENG.add(Double.valueOf(strENG));
            }
            proportion.put('ENG', doubleENG);
        }
        // 当前用户信息
        if (loginUser == null) {
            loginUser = [Select Id, Salesdepartment__c, ProfileId From User where Id = :Userinfo.getUserId()];
        }
        
        getsalesDptMap();
        salesDpt = '0.无';
        
        // 所有本年度属于省目标的目标
        if (target_category == null) {
            target_category = '省目标';
        }
        // 目标的数据类型
        if (rt == null) {
            rt = [select Id from RecordType where SobjectType = 'Opportunity' and IsActive = true and DeveloperName = 'Target'];
        }
        // 数据赋值
        setBean(iYear);

        return null;
    }
    //SWAG-BB48QB 判断当前时间是否是4月15日之后 start
    private boolean checkCurrentDate(){
        boolean dateResult = true;
        Date today = Date.today();
        Date date415 = Date.newInstance(today.year(), 4, 
            Integer.valueOf(System.Label.SetPersonalTarget_buffer_day));

        if(iYear >= currentYear - 1  && today <= date415 )
            dateResult = false;
        return dateResult;
    }
    //SWAG-BB48QB 判断当前时间是否是4月15日之后 end
    //
    // 点击上年度
    public void previous() {
        if (saveFlg) {
            this.saveLogic();
        }
        
        iYear -= 1;
        currentPeriod = String.valueOf(iYear - 1867 + 'P');
        // 是否是过去数据
        isPast = false;
         //SWAG-BB48QB 判断当前时间是否是4月15日之后 start
        if (iYear < currentYear && checkCurrentDate()) {
            isPast = true;
        } 
        //else if (iYear == currentYear) {
        //    if (Date.today().month() == 3) {
        //        isPast = true;
        //    }
        //}
         //SWAG-BB48QB 判断当前时间是否是4月15日之后 end
        previousRendered = true;
        nextRendered = true;
        // 数据赋值
        setBean(iYear);
    }
    
    // 点击下年度
    public void next() {
        if (saveFlg) {
            this.saveLogic();
        }
        
        iYear += 1;
        currentPeriod = String.valueOf(iYear - 1867 + 'P');
        // 是否是过去数据
        isPast = false;
        //SWAG-BB48QB 判断当前时间是否是4月15日之后 start
        if (iYear < currentYear && checkCurrentDate()) {
            isPast = true;
        } 
        //else if (iYear == currentYear) {
        //    if (Date.today().month() == 3) {
        //        isPast = true;
        //    }
        //}
         //SWAG-BB48QB 判断当前时间是否是4月15日之后 end
        previousRendered = true;
        nextRendered = true;
        // 只显示到现在时间的下一年数据
        if (iYear > currentYear) {
            nextRendered = false;
        }
        // 数据赋值
        setBean(iYear);
    }
    
    // 本部プルダウン変更時の処理
    public void searchByDpt() {
        if (saveFlg) {
            this.saveLogic();
        }
        
        setBean(iYear);
    }
    
    // 点击保存按钮
    public Pagereference saveBtn() {
        this.saveLogic();
        setBean(iYear);
        
        ApexPages.Message msg = new ApexPages.Message(ApexPages.Severity.INFO, '保存成功。');
        ApexPages.addMessage(msg);
        return null;
    }
    
    // 点击返回按钮
    public Pagereference backBtn() {
        // HOMEに戻る
        PageReference ref = new Pagereference('/home/home.jsp');
        ref.setRedirect(true);
        return ref;
    }
    
    // 数据赋值
    private void setBean(Integer year) {
        // 取得当前年度目标数据
        Opportunity[] opportunitys = [select
                        Id, OwnerId, Opportunity_Category__c, Proportion__c, CloseDate,
                        Amount, Objective__c, Target_category__c,
                        SAP_Province__c, RecordTypeId, OCM_Target_period__c, Owner_System__c,Owner_System__r.Name
                 from Opportunity
                where Target_category__c = :target_category
                  //and Opportunity_Category__c = :amountCategory
                  and RecordTypeId = :rt.Id
                  and Target_Source__c = 'SetProvinceTargetEng'
                  and OCM_Target_period__c = :currentPeriod];
        // 当前年度没有数据时，显示信息
        if (opportunitys.size() <= 0 && isPast && iYear < currentYear) {
            ApexPages.Message msg = new ApexPages.Message(ApexPages.Severity.INFO, '没有上年度的数据。');
            ApexPages.addMessage(msg);
            previousRendered = false;
            iYear += 1;
            currentPeriod = String.valueOf(iYear - 1867 + 'P');
            isPast = false;
            if (iYear < currentYear) {
                isPast = true;
            } else if (iYear == currentYear) {
                if (Date.today().month() == 3) {
                    isPast = true;
                }
            }
            // 今表示しているデータを再取得
            setBean(iYear);
            return;
        }
        oppsMap = new Map<String, Opportunity>();
        for (Opportunity opp : opportunitys) {
            if (opp.OwnerId != null && opp.Opportunity_Category__c != null && opp.CloseDate !=null){
                //  目标 key : Province + _ + Opportunity_Category__c + _ + CloseDate(yyyy-mm-dd)
                String key = opp.SAP_Province__c + '_' + opp.Opportunity_Category__c + '_' + String.valueOf(opp.CloseDate);
                oppsMap.put(key, opp);
            }
        }
        dataBeans = new List<DataBean>();
        List<String> provinces = salesDptMap.get(salesDpt);
        for (String pro : provinces) {
            DataBean dataBean = new DataBean(provinceMap.get(pro), pro, oppsMap, iYear);
            dataBeans.add(dataBean);
        }
    }
    
    //获取本部-省对应关系
    private void getsalesDptMap() {
        salesDptMap = new Map<String,List<String>>();
        
        List<String> provinceList = new List<String>();
        provinceList.add('北京市');
        provinceList.add('天津市');
        provinceList.add('河南省');
        provinceList.add('河北省');
        provinceList.add('山西省');
        provinceList.add('内蒙古');
        provinceList.add('山东省');
        provinceList.add('陕西省');
        provinceList.add('青海省');
        provinceList.add('宁夏自治区');
        provinceList.add('甘肃省');
        provinceList.add('新疆自治区');
        provinceList.add('辽宁省');
        provinceList.add('黑龙江省');
        provinceList.add('吉林省');
        provinceList.add('上海市');
        provinceList.add('江苏省');
        provinceList.add('浙江省');
        provinceList.add('福建省');
        provinceList.add('安徽省');
        provinceList.add('江西省');
        provinceList.add('广东省');
        provinceList.add('广西自治区');
        provinceList.add('海南省');
        provinceList.add('四川省');
        provinceList.add('重庆市');
        provinceList.add('云南省');
        provinceList.add('贵州省');
        provinceList.add('西藏自治区');
        provinceList.add('湖北省');
        provinceList.add('湖南省');
        provinceList.add('深圳市');
        provinceList.add('大连市');
        provinceList.add('青岛市');
        salesDptMap.put('0.无',provinceList);
        
        provinceList = new List<String>();
        provinceList.add('北京市');
        provinceList.add('天津市');
        provinceList.add('河北省');
        provinceList.add('内蒙古');
        provinceList.add('山东省');
        provinceList.add('青岛市');
        salesDptMap.put('1.华北',provinceList);
        
        provinceList = new List<String>();
        provinceList.add('辽宁省');
        provinceList.add('黑龙江省');
        provinceList.add('吉林省');
        provinceList.add('大连市');
        salesDptMap.put('2.东北',provinceList);
        
        provinceList = new List<String>();
        provinceList.add('河南省');
        provinceList.add('山西省');
        provinceList.add('陕西省');
        provinceList.add('青海省');
        provinceList.add('宁夏自治区');
        provinceList.add('甘肃省');
        provinceList.add('新疆自治区');
        salesDptMap.put('3.西北',provinceList);
        
        provinceList = new List<String>();
        provinceList.add('上海市');
        provinceList.add('江苏省');
        provinceList.add('浙江省');
        provinceList.add('福建省');
        provinceList.add('安徽省');
        provinceList.add('江西省');
        salesDptMap.put('4.华东',provinceList);
        
        provinceList = new List<String>();
        provinceList.add('广东省');
        provinceList.add('广西自治区');
        provinceList.add('海南省');
        provinceList.add('湖北省');
        provinceList.add('湖南省');
        provinceList.add('深圳市');
        salesDptMap.put('5.华南',provinceList);
        
        provinceList = new List<String>();
        provinceList.add('四川省');
        provinceList.add('重庆市');
        provinceList.add('云南省');
        provinceList.add('贵州省');
        provinceList.add('西藏自治区');
        salesDptMap.put('6.西南',provinceList);
        
        provinceMap = new Map<string,string>();
        
        provinceMap.put('北京市','1.华北');
        provinceMap.put('天津市','1.华北');
        provinceMap.put('河北省','1.华北');
        provinceMap.put('内蒙古','1.华北');
        provinceMap.put('山东省','1.华北');
        provinceMap.put('青岛市','1.华北');
        
        provinceMap.put('辽宁省','2.东北');
        provinceMap.put('黑龙江省','2.东北');
        provinceMap.put('吉林省','2.东北');
        provinceMap.put('大连市','2.东北');
        
        provinceMap.put('河南省','3.西北');
        provinceMap.put('山西省','3.西北');
        provinceMap.put('陕西省','3.西北');
        provinceMap.put('青海省','3.西北');
        provinceMap.put('宁夏自治区','3.西北');
        provinceMap.put('甘肃省','3.西北');
        provinceMap.put('新疆自治区','3.西北');
        
        provinceMap.put('上海市','4.华东');
        provinceMap.put('江苏省','4.华东');
        provinceMap.put('浙江省','4.华东');
        provinceMap.put('福建省','4.华东');
        provinceMap.put('安徽省','4.华东');
        provinceMap.put('江西省','4.华东');
        
        provinceMap.put('广东省','5.华南');
        provinceMap.put('广西自治区','5.华南');
        provinceMap.put('海南省','5.华南');
        provinceMap.put('湖北省','5.华南');
        provinceMap.put('湖南省','5.华南');
        provinceMap.put('深圳市','5.华南');
        
        provinceMap.put('四川省','6.西南');
        provinceMap.put('重庆市','6.西南');
        provinceMap.put('云南省','6.西南');
        provinceMap.put('贵州省','6.西南');
        provinceMap.put('西藏自治区','6.西南');
    }
    
    // 是否删除整行数据
    private boolean isDelete(DataBean db) {
        if (db.opportunity.Owner_System__c == null) {
            for (Integer i = 0; i < 12; i++) {
                Integer y = iYear;
                Integer m = 4 + i;
                if (m > 12) {
                    y += 1;
                    m -= 12;
                }
                String syear = String.valueOf(y);
                String smonth = String.valueOf(m);
                if (m < 10) {
                    smonth = '0' + smonth;
                }
                String sTargetDay = syear + '-' + smonth + '-01';
                Date targetDay = Date.valueOf(sTargetDay);
                // 按金额分类顺序处理
                for (Integer j = 0; j < amountCategory.size(); j++) {
                    String amountC = amountCategory[j];
                    // 数据检索Key
                    String key = db.opportunity.SAP_Province__c + '_' + amountC + '_' + sTargetDay;
                    if (oppsMap.containskey(key)) {
                        return true;
                    }
                }
            }
        }
        return false;
    }
    
    // 実際の保存ロジック
    private void saveLogic() {
        List<Opportunity> saveList = new List<Opportunity>();
        List<Opportunity> deleteList = new List<Opportunity>();
        
        for (Integer d = 0; d < dataBeans.size(); d++) {
            DataBean db = dataBeans[d];
            
            // 寄存数据比例值是否变化
            Boolean proportionChanged = false;
            for (Integer i = 0; i < 12; i++) {
                Integer y = iYear;
                Integer m = 4 + i;
                if (m > 12) {
                    y += 1;
                    m -= 12;
                }
                String syear = String.valueOf(y);
                String smonth = String.valueOf(m);
                if (m < 10) {
                    smonth = '0' + smonth;
                }
                String sTargetDay = syear + '-' + smonth + '-01';
                // 按金额分类顺序处理
                for (Integer j = 0; j < amountCategory.size(); j++) {
                    String amountC = amountCategory[j];
                    // 数据检索Key
                    String key = db.opportunity.SAP_Province__c + '_' + amountC + '_' + sTargetDay;
                    // 每月数据赋值
                    Opportunity opp = new Opportunity();
                    if (oppsMap.containskey(key)) {
                        opp = oppsMap.get(key);
                        if (opp.Proportion__c != proportion.get(amountC)[i]) {
                            proportionChanged = true;
                            break;
                        }
                    }
                }
                if (proportionChanged) {
                    break;
                }
            }
            if (db.isChanged == '0' && !proportionChanged) {
                continue;
            }
            User u = new User();
/*************************Update 20160413 Start*************************/
            if (db.opportunity.Owner_System__c == null) {
                if (isDelete(db) == false) {
                    continue;
                }
            }
/*************************Update 20160413 End***************************/
            // 一年分成12条数据
            for (Integer i = 0; i < 12; i++) {
                Integer y = iYear;
                Integer m = 4 + i;
                if (m > 12) {
                    y += 1;
                    m -= 12;
                }
                String syear = String.valueOf(y);
                String smonth = String.valueOf(m);
                if (m < 10) {
                    smonth = '0' + smonth;
                }
                String sTargetDay = syear + '-' + smonth + '-01';
                Date targetDay = Date.valueOf(sTargetDay);
                // 按金额分类顺序处理
                for (Integer j = 0; j < amountCategory.size(); j++) {
                    String amountC = amountCategory[j];
                    // 数据检索Key
                    String key = db.opportunity.SAP_Province__c + '_' + amountC + '_' + sTargetDay;
                    // 每月数据赋值
                    Opportunity opp = new Opportunity();
                    if (oppsMap.containskey(key)) {
                        opp = oppsMap.get(key);
                        //if (db.opportunity.Owner_System__c == null || db.amount[j].Amount == null || db.amount[j].Amount == 0) {
                        if (db.amount[j].Amount == null || db.amount[j].Amount == 0) {
                            deleteList.add(opp);
                            continue;
                        }
/*************************Update 20160531 Start*************************/
                        opp.OwnerId = db.opportunity.Owner_System__c;
                        opp.Owner_System__c = db.opportunity.Owner_System__c;
/*************************Update 20160531 End***************************/
                        opp.Proportion__c = proportion.get(amountC)[i];
                        opp.Amount = db.amount[j].Amount;
                    } else {
                        if (db.amount[j].Amount == null || db.amount[j].Amount == 0) {
                            continue;
                        }
                        opp.Name = db.opportunity.SAP_Province__c + ' 省目标';
                        opp.StageName = '目標';
/*************************Update 20160531 Start*************************/
                        opp.OwnerId = db.opportunity.Owner_System__c;
                        //トリガをスルーのため、ここでやります
                        opp.Owner_System__c = db.opportunity.Owner_System__c;
/*************************Update 20160531 End***************************/
                        opp.Opportunity_Category__c = amountC;
                        opp.Proportion__c = proportion.get(amountC)[i];
                        opp.CloseDate = targetDay;
                        opp.Amount = db.amount[j].Amount;
                        opp.Target_category__c = target_category;
                        opp.SAP_Province__c = db.opportunity.SAP_Province__c;
                        opp.RecordTypeId = rt.Id;
                        opp.Target_Source__c = 'SetProvinceTargetEng';
                        opp.OCM_Target_period__c = currentPeriod;
                    }
                    // 加入保存列表
                    saveList.add(opp);
                }
            }
            // 数据库限制小于10000条
            if (saveList.size() + deleteList.size() >= 4000) {
                ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.INFO, '操作数据量过大，截止至' + db.opportunity.SAP_Province__c + '的数据操作完成，之后的数据请再次输入并保存。'));
                break;
            }
        }
        // トリガをスルー
        StaticParameter.EscapeOpportunityBefUpdTrigger = true;
        StaticParameter.EscapeOpportunityHpDeptUpdTrigger = true;
        StaticParameter.EscapeNFM007Trigger = true;

        // 更新数据库
        if (saveList.size() > 0) upsert saveList;
        if (deleteList.size() > 0) delete deleteList;
    }
    
    // 数据类
    class DataBean {
        // 担当者信息
        public Opportunity opportunity { get; set; }
        // 总金额，画面用
        public Opportunity[] amount { get; set; }
        // 本部表示用
        public String department { get; private set; }
        // 是否变化 0：无 1：有
        public String isChanged { get; set; }
        
        // 构造方法
        DataBean(String salesDpt, String province, Map<String, Opportunity> oppMap, Integer iYear) {
            this.opportunity = new Opportunity();
            this.amount = new List<Opportunity>();
            this.opportunity.SAP_Province__c = province;
            this.department = salesDpt;
            this.isChanged = '0';

            // 按金额分类，查找数据，并设值
            for (Integer i = 0; i < amountCategory.size(); i++) {
                String amountC = amountCategory[i];
                Opportunity a = new Opportunity();
                a.Opportunity_Category__c = amountC;
                Decimal amountSum = 0.0;
                for (Integer j = 0; j < 12; j++) {
                    Integer y = iYear;
                    Integer m = 4 + j;
                    if (m > 12) {
                        y += 1;
                        m -= 12;
                    }
                    String strY = String.valueOf(y);
                    String strM = String.valueOf(m);
                    if (strM.length() < 2) {
                        strM = '0' + strM;
                    }
                    String key = this.opportunity.SAP_Province__c + '_' + amountC + '_' + strY + '-' + strM + '-01';
                    if (oppMap.containskey(key)) {
/*************************Update 20160531 Start*************************/
                        if (oppMap.get(key).Owner_System__c != null) {
                            this.opportunity.Owner_System__c = oppMap.get(key).Owner_System__c;
                        }
                        a.Amount = oppMap.get(key).Amount;
/*************************Update 20160531 End***************************/
                        amountSum += oppMap.get(key).Objective__c == null ? 0 : oppMap.get(key).Objective__c;
                    }
                }
                if (amountSum > 0) {
                    amountSum = amountSum.setScale(2);
                    a.Amount = amountSum;
                }
                this.amount.add(a);
            }
        }
    }
}