// 六个Apex方法，初始化，保存，取消，提交审批，追加品牌，追加型号
public with sharing class PCLLostReportByTcmController {
    public string oppId { get; set; }
    public string lostReportId { get; set; }
    // 当前页面状态 Create,View and Edit, MarketEdit
    public string pageStatus { get; set; }
    // 失单，部分失单
    public string lostType {get;set;}
    public Set<ID> deleteBrandIDSet = new Set<ID>();
    public string submitFlag {get;set;}
    public LostReport LostReport {get;set;}
    public integer brandNo {get;set;}
    public integer RemoveBrandNo {get;set;}
    public integer setBrandNo {get;set;}
    public integer brandCount {get;set;}
    // 竞争对手对照关系表，key是品牌名字，value是ID
    public map<string,id> CompetitionMap ;
    public PCLLostReportByTcmController(ApexPages.StandardController controller) {
        this();
    }
    public PCLLostReportByTcmController(){
        oppId =
            ApexPages.currentPage().getParameters().get('oppId') == null ? ''
            : ApexPages.currentPage().getParameters().get('oppId');
        lostReportId =
            ApexPages.currentPage().getParameters().get('Id') == null ? ''
            : ApexPages.currentPage().getParameters().get('Id');
        pageStatus =
            ApexPages.currentPage().getParameters().get('pageStatus') == null ? ''
            : ApexPages.currentPage().getParameters().get('pageStatus');
        lostType =
            ApexPages.currentPage().getParameters().get('lostType') == null ? ''
            : ApexPages.currentPage().getParameters().get('lostType');
        submitFlag = ApexPages.currentPage().getParameters().get('submitFlag') == null ? ''
            : ApexPages.currentPage().getParameters().get('submitFlag');

    }
    // 初始化
    public void init(){
        system.debug('lostReportId:'+lostReportId);
        if(string.isblank(pageStatus)){
            ApexPages.addmessage(new ApexPages.message(ApexPages.severity.Error, '页面出错，请刷新后重试！'));
            // 这里需要报错没有传参数
            return;
        }
        else if(pageStatus.equals('Create')){
            if(string.isBlank(oppId)){
                // 这里报错创建时候必须有询价
                ApexPages.addmessage(new ApexPages.message(ApexPages.severity.Error, '创建失单报告时，请重询价页面创建'));
                return;
            }
            list<opportunity> opplist =
                [select id,Name,
                 Sales_assistant_ID__c,
                 Sales_manager_departmentID__c,Sales_owner_buchangID__c
                 from opportunity
                 where id =: oppId
                 limit 1];
            if( opplist.size() == 0){
                ApexPages.addmessage(new ApexPages.message(ApexPages.severity.Error, '您没有询价的查看权限，无法创建失单报告！'));
                pageStatus = null;
                return;
            }
            Schema.DescribeSObjectResult s = Lost_cancel_report__c.sObjectType.getDescribe();
            if( !s.isCreateable()){
                ApexPages.addmessage(new ApexPages.message(ApexPages.severity.Error, '您不能创建失单/部分失单报告！'));
                return;
            }
            Lost_cancel_report__c tempLostReport =
                new Lost_cancel_report__c(LostType__c= lostType,
                                          Opportunity__c = oppId,
                                          Sales_assistant__c = opplist[0].Sales_assistant_ID__c,
                                          Manager_sales__c = opplist[0].Sales_manager_departmentID__c,
                                          Buchang_sales__c = opplist[0].Sales_owner_buchangID__c,
                                          Submit_Day__c = date.today(),
                                          Report_Status__c = '草案');
            LostReport = new LostReport(tempLostReport);
            brandCount = 1;
        }
        else if(pageStatus.equals('View') ||  pageStatus.equals('Edit')){
            system.debug('edit1');
            if(string.isBlank(lostReportId)){
                ApexPages.addmessage(new ApexPages.message(ApexPages.severity.Error, '您没有查看这个失单/部分失单报告的权限！'));
                pageStatus = null;
                return;
            }
            system.debug('edit2');
            list<Lost_cancel_report__c> lostReportList =
                [select id ,of_lost_system_processor__c,
                Lost_reason_main__c,
                 Lost_Reason_Sub__c,Lost_By_Company__c,
                 LostTotalAmount__c,LostType__c,
                 Report_Status__c,Sales_assistant__c,
                 Opportunity__c, Opportunity__r.Sales_assistant_ID__c,
                 Opportunity__r.Sales_manager_departmentID__c,
                 Manager_sales__c,recordtypeid,recordtype.DeveloperName
                 from Lost_cancel_report__c
                 where id =: lostReportId limit 1];

            if(lostReportList.size() == 0){
                ApexPages.addmessage(new ApexPages.message(ApexPages.severity.Error, '您没有查看这个失单/部分失单报告的权限！'));
                pageStatus = null;
                return;
            }
            lostReportList[0].Sales_assistant__c =
            lostReportList[0].Opportunity__r.Sales_assistant_ID__c;
            lostReportList[0].Manager_sales__c =
            lostReportList[0].Opportunity__r.Sales_manager_departmentID__c;
            if(lostReportList[0].recordtype.DeveloperName.equals('PCL_Lost_report')){
                lostReportList[0].LostType__c ='失单';
                
            }else if(lostReportList[0].recordtype.DeveloperName.equals('PCL_PartLost_report')){
                lostReportList[0].LostType__c ='部分失单';
            }
            // 权限，如果当前状态不是草案中，那么需要跳转到只读页面
            if(!'草案'.equals(lostReportList[0].Report_Status__c)){
                pageStatus = 'View';
            }
            oppId = lostReportList[0].Opportunity__c;
            system.debug('edit3');
            list<PCLLostBrand__c> selectlostBrandList =
                [
                    select id, LostPrice__c, Lost_By_Company__c,
                    Lost_reason_main__c,Lost_Reason_Sub__c,Name,Agency__c, AgencyMannual__c ,
                    // ProductCategory__c,ProductClass__c,
                    Lost_cancel_report__c  ,Lost_By_Company_Mannual__c,
                    ( select id ,PCLLostBrand__c,LostProduct__c,
                        LostProductMannual__c,      //SWAG-C6P9PX lt 20210913 add
                        Quantity__c,Name, LostBrandName__c 
                     from PCLLostBrand__c.PCLLostBrandProduct__r)
                    from PCLLostBrand__c
                    where Lost_cancel_report__c =: lostReportId
                ];
            if(selectlostBrandList.size() == 0 ){
                LostReport = new LostReport(lostReportList[0]);
                brandCount = 1;
            }else{
                system.debug('edit4:'+selectlostBrandList[0]);
                brandCount = 0;
                list<LostBrand> LostBrandList = new list<LostBrand>();
                for(PCLLostBrand__c templostBrand : selectlostBrandList){
                    list<PCLLostProduct__c> tempProductList = new list<PCLLostProduct__c>();
                    integer productCount = 0;
                    for( PCLLostProduct__c tempProduct: templostBrand.PCLLostBrandProduct__r){
                        tempProductList.add(tempProduct);
                        productCount++;
                    }
                    LostBrandList.add( new LostBrand(brandCount,tempProductList, templostBrand));
                    brandCount++;
                }

                LostReport = new LostReport(lostReportList[0],LostBrandList);
                system.debug('LostReport.LostBrands:'+LostReport.LostBrands);
            }
        }
        brandNo = 0;
        // 读取竞争对手品牌
        BrandmapSet();
        if(string.isNotEmpty(submitFlag)){
            ApexPages.addmessage(new ApexPages.message(ApexPages.severity.CONFIRM,
                                                       '提交成功！'));

        }
    }
    // 编辑 只有系统管理员或者草案中可以编辑
    public PageReference edit2(){
        if( userinfo.getProfileId() == (ID) '00e10000000Y3o5AAC' ||
           '草案'.equals(LostReport.LostReport.Report_Status__c)
          ){
              pageStatus = 'Edit';
          }
        else{
            ApexPages.addmessage(new ApexPages.message(ApexPages.severity.Error, '只有在草案中才能进行编辑！'));
        }
        return null;
    }
    // 设置品牌
    public void setBrand(){
        list<LostBrand> LostBrandlist =  LostReport.LostBrands;
        LostBrand tempBrand = LostBrandlist.get(setBrandNo);
        string brandName = tempBrand.lostBrand?.Lost_By_Company__c;
        ID compID = CompetitionMap.get(brandName);
        // for(PCLLostProduct__c tempLostProduct : tempBrand.LostProducts ){
        //     tempLostProduct.Competitor__c = compID;
        // }
    }
    // 保存
    public PageReference save(){
        if(!DataCheck()){
            return null;
        }
        if(!dataEntry()){
            return null;
        }
        brandCount = LostReport.LostBrands.size();
        pageStatus = 'View';
        ApexPages.addmessage(new ApexPages.message(ApexPages.severity.CONFIRM, '保存成功！'));

        return null;
    }
    //读取并构建竞争对手品牌
    public void BrandmapSet(){
        CompetitionMap = new map<string, id>();
        list <Competition_Company__c> competitionList
            =  [select id ,name from Competition_Company__c];
        for(Competition_Company__c tempComp : competitionList ){
            CompetitionMap.put(tempComp.name, tempComp.id);
        }

    }
    // 数据检查
    public boolean DataCheck(){
        boolean dataCheck = true;
        if(string.isBlank(LostReport.LostReport.LostType__c))
        {
            LostReport.LostReport.LostType__c.addError('必须填写失单类型！');
            dataCheck = false;
        }

        for(LostBrand tempLostBrand : LostReport.LostBrands ){
            if(string.isblank(tempLostBrand.lostBrand.Lost_By_Company__c)){
                tempLostBrand.lostBrand.Lost_By_Company__c.addError('请填写失单品牌！');
                dataCheck = false;
            }

            if(tempLostBrand.lostBrand.LostPrice__c == null) {
                tempLostBrand.lostBrand.LostPrice__c.addError('失单金额必填！');
                dataCheck = false;
            }
            if(string.isblank(tempLostBrand.lostBrand.Lost_reason_main__c )) {
                tempLostBrand.lostBrand.Lost_reason_main__c.addError('失单理由(主)必填！');
                dataCheck = false;
            }
            if(string.isblank(tempLostBrand.lostBrand.Agency__c )) {
                tempLostBrand.lostBrand.Agency__c.addError('中标经销商必填！');
                dataCheck = false;
            }
            // 检查是否有超过1个有数的产品
            integer productCount = 0;
            for( PCLLostProduct__c temlostProduct : tempLostBrand.LostProducts){
                if(temlostProduct.Quantity__c!=null && temlostProduct.Quantity__c >0 ){
                    productCount++;
                }
            }
            if(productCount == 0){
                tempLostBrand.LostProducts[0].Quantity__c.addError('请填写一个失单型号！');
                dataCheck = false;
            }

        }

        return dataCheck;
    }
    public list<LostBrand> brandcopy(){
        list<LostBrand> tempbrands = new list<LostBrand>();
        for(LostBrand tempbrand: LostReport.LostBrands){
            LostBrand LostBrand =
                new LostBrand(tempbrand.lineNo,tempbrand.LostProducts );
            LostBrand.lostBrand = tempbrand.lostBrand.clone();
            LostBrand.lostBrand.id = tempbrand.lostBrand.id;
            tempbrands.add(LostBrand);
        }
        return tempbrands;
    }
    // 数据录入
    public boolean dataEntry(){
        system.debug('save---start:');
        Savepoint sp = Database.setSavepoint();
        Lost_cancel_report__c templostReport = LostReport.lostReport.clone();
        templostReport.id = LostReport.lostReport.id;
        list<LostBrand> tempBrands = brandcopy();
        try{
            // 待完成，这里需要把第一个品牌的信息赋值到这个失单报告上去，还有需要把各个品牌金额汇总加起来；
            //system.debug('LostReport.LostBrands:'+LostReport.LostBrands);
            // 设置记录类型
            LostReport.lostReport.recordTypeID  =  LostReport.lostReport.LostType__c== '失单'?Schema.SObjectType.Lost_cancel_report__c.getRecordTypeInfosByDeveloperName().get('PCL_Lost_report').getRecordTypeId() : Schema.SObjectType.Lost_cancel_report__c.getRecordTypeInfosByDeveloperName().get('PCL_PartLost_report').getRecordTypeId();
            LostReport.lostReport.LostTotalAmount__c    = 0;
            LostReport.lostReport.of_lost_system_processor__c   = 0;
            LostReport.lostReport.Lost_reason_main__c = null;
            LostReport.lostReport.Lost_Reason_Sub__c  = null;
            LostReport.lostReport.Lost_By_Company__c = null;
            for(LostBrand tempLostBrand : LostReport.LostBrands){
                if(string.isNotBlank(tempLostBrand.lostBrand.Lost_By_Company__c)){
                    LostReport.lostReport.LostTotalAmount__c += tempLostBrand.lostBrand.LostPrice__c;
                    LostReport.lostReport.Lost_reason_main__c =
                        LostReport.lostReport.Lost_reason_main__c == null
                        ? tempLostBrand.lostBrand.Lost_reason_main__c
                        : LostReport.lostReport.Lost_reason_main__c;
                    LostReport.lostReport.Lost_Reason_Sub__c  =
                        LostReport.lostReport.Lost_Reason_Sub__c == null
                        ? tempLostBrand.lostBrand.Lost_Reason_Sub__c
                        : LostReport.lostReport.Lost_Reason_Sub__c;
                    LostReport.lostReport.Lost_By_Company__c =
                        LostReport.lostReport.Lost_By_Company__c == null
                        ? tempLostBrand.lostBrand.Lost_By_Company__c
                        : LostReport.lostReport.Lost_By_Company__c;

                    for( PCLLostProduct__c tempLostProduct : tempLostBrand.LostProducts){
                        if(tempLostProduct.Quantity__c !=null && tempLostProduct.Quantity__c >0){
                            LostReport.lostReport.of_lost_system_processor__c   += tempLostProduct.Quantity__c;
                        }

                    }
                }

            }
            upsert LostReport.lostReport;
            // 需要插入更新的失单品牌
            map<integer,PCLLostBrand__c> upsertLostBrandMap = new map<integer,PCLLostBrand__c>();
            // 需要删掉的失单品牌
            map<integer,PCLLostBrand__c> deleteLostBrandMap = new map<integer,PCLLostBrand__c>();
            // 需要插入更新的失单型号，key是品牌编号+型号编号，value是需要更新的失单型号
            map<string,PCLLostProduct__c> upsertLostProductMap = new map<string,PCLLostProduct__c>();
            // 需要删掉的失单品牌
            list<PCLLostProduct__c> deleteLostProductList = new list<PCLLostProduct__c>();
            for(LostBrand tempLostBrand : LostReport.LostBrands ){
                // 如果有失单品牌，那么就要插入更新；
                system.debug('tempLostBrand.lostBrand.Lost_By_Company__c:'+tempLostBrand.lostBrand.Lost_By_Company__c);
                if(string.isNotBlank(tempLostBrand.lostBrand.Lost_By_Company__c)){
                    upsertLostBrandMap.put(tempLostBrand.lineNo,tempLostBrand.lostBrand);
                    tempLostBrand.lostBrand.Lost_cancel_report__c = LostReport.lostReport.id;
                    tempLostBrand.lostBrand.Name = tempLostBrand.lostBrand.Lost_By_Company__c;
                    integer tempNo = 0;
                    for( PCLLostProduct__c tempLostProduct : tempLostBrand.LostProducts){
                        system.debug('Name:'+ tempLostProduct.Name );
                        if(tempLostProduct.Quantity__c !=null && tempLostProduct.Quantity__c >0){
                            tempLostProduct.Name = tempLostBrand.lostBrand.Name + tempLostProduct.Quantity__c;
                            upsertLostProductMap.put(tempLostBrand.lineNo +':'+ tempNo,tempLostProduct);
                        }else if(string.isNotBlank(tempLostProduct.id)){
                            deleteLostProductList.add(tempLostProduct);
                        }
                        tempNo++;
                    }
                }
                // 如果没有品牌，但是有id， 这样数据需要删除
                else if(string.isNotBlank(tempLostBrand.lostBrand.id)){
                    deleteLostBrandMap.put(tempLostBrand.lineNo,tempLostBrand.lostBrand);
                    // 这里可能需要也判断一下失单型号有没有需要删掉
                }
            }
            if(upsertLostBrandMap.size()>0){
                upsert upsertLostBrandMap.values();
            }
            for( string productNo :upsertLostProductMap.keyset()){
                PCLLostProduct__c tempLostProduct = upsertLostProductMap.get(productNo);
                integer brandNo = integer.valueof(productNo.split(':')[0]);
                tempLostProduct.PCLLostBrand__c = upsertLostBrandMap.get(brandNo).id;
            }
            if(upsertLostProductMap.size()>0){
                upsert upsertLostProductMap.values();
            }
            if(deleteLostBrandMap.size()>0){
                delete deleteLostBrandMap.values();
                for(PCLLostBrand__c pcl: deleteLostBrandMap.values()){
                    pcl.id = null;
                }
            }
            if(deleteLostProductList.size()>0){
                delete deleteLostProductList;
                for(PCLLostProduct__c pclp: deleteLostProductList){
                    pclp.id = null;
                }
            }
            if(deleteBrandIDSet.size() > 0){
                list<id> tempdeleteIDlist = new list<id>();
                tempdeleteIDlist.addall(deleteBrandIDSet);
                database.delete(tempdeleteIDlist);

            }

            for(integer brandNumber =0;brandNumber< LostReport.LostBrands.size();brandNumber++){

                LostBrand tempLostBrand = LostReport.LostBrands.get(brandNumber);
                if(tempLostBrand.lostBrand.Id == null){
                    LostReport.LostBrands.remove(brandNumber);
                    brandNumber--;
                    continue;
                }
                for(integer productNumber = 0;productNumber< tempLostBrand.LostProducts.size();productNumber++){
                    PCLLostProduct__c tempLostProduct = tempLostBrand.LostProducts.get(productNumber);
                    if(tempLostProduct.Id == null){
                        tempLostBrand.LostProducts.remove(productNumber);
                        productNumber--;
                        continue;
                    }
                }
            }
            lostReportId = LostReport.lostReport.id;
            system.debug('save---end:');
        }catch (Exception ex) {
            Database.rollback(sp);
            LostReport.lostReport = templostReport;
            LostReport.LostBrands = tempBrands;
            // 这里需要写一些报错信息
            ApexPages.addmessage(new ApexPages.message(ApexPages.severity.Error,ex.getMessage()));
            return false;
        }
        return true;
    }

    // 取消
    public PageReference cancel(){
        PageReference page = new PageReference('/'+oppId);
        page.setRedirect(true);
        return page;
    }
    // 提交
    public PageReference submit(){
        if(! '草案'.equals(LostReport.LostReport.Report_Status__c) ){
            ApexPages.addmessage(new ApexPages.message(ApexPages.severity.Error, '只有在草案中才能提交申请！'));
            return null;
        }

        Savepoint sp = Database.setSavepoint();
        try{
            LostReport.lostReport.Report_Status__c = '提交';
            update LostReport.lostReport;
            Approval.ProcessSubmitRequest psr = new Approval.ProcessSubmitRequest();
            psr.setObjectId(lostReportId);
            Approval.ProcessResult submitResult = Approval.process(psr);
            PageReference page = new PageReference('/apex/PCLLostReportPage');
            page.getParameters().put('Id', lostReportId);
            page.getParameters().put('pageStatus', 'View');
            page.getParameters().put('submitFlag', '1');

            page.setRedirect(true);
            return page;
        }catch(exception ex){
             Database.rollback(sp);
            ApexPages.addmessage(new ApexPages.message(ApexPages.severity.Error,ex.getMessage()));
            return  null;
        }

    }
    // 添加品牌
    public PageReference addBrand(){
        LostReport.LostBrands.add(new LostBrand(LostReport.LostBrands.size()));
        brandCount = LostReport.LostBrands.size();
        return null;
    }
    // 删除品牌 这个有参数brandNo，才知道是删除那个品牌
    public PageReference Remove(){
        system.debug('RemoveBrandNo:'+RemoveBrandNo);
        list<LostBrand> tempLostBrands = new List<lostBrand>();
        Integer i = 0;
        for(integer j = 0;j< LostReport.LostBrands.size() ;j++ ){
            LostBrand templostBrand  = LostReport.LostBrands.get(j);
            if(j != RemoveBrandNo){
                templostBrand.lineNo = i;
                tempLostBrands.add(templostBrand);
                i++;
            }else if(!string.isBlank(templostBrand.lostBrand.id)){
                deleteBrandIDSet.add(templostBrand.lostBrand.id);
            }
        }

        LostReport.LostBrands =  tempLostBrands;

        brandCount = LostReport.LostBrands.size();
        return null;
    }
    // 添加型号， 这个有参数brandNo，才知道是添加到那个品牌
    public PageReference addProduct(){
        system.debug('brandNo:'+brandNo);
        LostBrand tempLostBrand = LostReport.LostBrands.get(brandNo);
        tempLostBrand.LostProducts.add(new PCLLostProduct__c());
        tempLostBrand.ProductSize = tempLostBrand.LostProducts.size();
        return null;
    }

    // 页面的数据结构
    public class LostReport {
        public Lost_cancel_report__c lostReport { get; set; }
        public list<LostBrand> LostBrands{ get; set; }
        public LostReport(){
            lostReport = new Lost_cancel_report__c();
            LostBrands = new list<LostBrand>{new LostBrand(0)};
                }
        public LostReport(Lost_cancel_report__c lostReport){
            this.lostReport = lostReport;
            LostBrands = new list<LostBrand>{new LostBrand(0)};
                }
        public LostReport(Lost_cancel_report__c lostReport,  list<LostBrand> LostBrands){
            this.lostReport = lostReport;
            this.LostBrands = LostBrands;
        }
    }
    public class LostBrand{
        public PCLLostBrand__c lostBrand { get; set; }
        public Integer lineNo { get; set; }
        public list<PCLLostProduct__c> LostProducts { get; set; }
        public Integer ProductSize {get;set;}
        public LostBrand( integer lineNo ){
            lostBrand = new PCLLostBrand__c();
            this.lineNo = lineNo;
            LostProducts = new list<PCLLostProduct__c>{new PCLLostProduct__c()};
                ProductSize = 1;
            lostBrand = new PCLLostBrand__c();
        }
        public LostBrand( integer lineNo, list<PCLLostProduct__c> LostProducts ){
            lostBrand = new PCLLostBrand__c();
            this.lineNo = lineNo;
            this.LostProducts = LostProducts;
            ProductSize = LostProducts.size();

        }
        public LostBrand( integer lineNo, list<PCLLostProduct__c> LostProducts ,  PCLLostBrand__c lostBrand){
            this.lostBrand = lostBrand;
            this.lineNo = lineNo;
            this.LostProducts = LostProducts;
            ProductSize = LostProducts.size();
        }
    }

}