public with sharing class ReceivingNoteStockInRequestController {

    public static final String NONE = system.label.StartTrading_None;
    private List<String> assetFieldApiList;
    private List<String> receivingNoteFieldApiList;

    public List<LabelValue> outputFieldList {get; set;}
    public List<LabelValue> inputFieldList {get; set;}

    public String parId {get; set;}
    public PageBean pageB {get; set;}
    public String showCount {get;set;}
    public Integer nowPage {get;set;}
    public Integer maxPage {get;set;}
    public Boolean canBefore {get;set;}
    public Boolean canNext {get;set;}

    public ReceivingNoteStockInRequestController() {
        parId = System.currentPageReference().getParameters().get('parId');
        nowPage = 1;
    }

    public void init() {
        try {
            Set<String> assetFieldApiSet = new Set<String>();
            Set<String> receivingNoteFieldApiSet = new Set<String>();
            outputFieldList = setFIeldSet('ReceivingNoteDetail__c', 'ReceivingNoteStockInRequest_L', receivingNoteFieldApiSet);
            inputFieldList = setFIeldSet('ReceivingNoteDetail__c', 'ReceivingNoteStockInRequest_R', receivingNoteFieldApiSet);
            addField(receivingNoteFieldApiSet, assetFieldApiSet);
            assetFieldApiList = new List<String>();
            receivingNoteFieldApiList = new List<String>();
            assetFieldApiList.addAll(assetFieldApiSet);
            receivingNoteFieldApiList.addAll(receivingNoteFieldApiSet);
            if (String.isBlank(parId)) {
                throw new ControllerUtil.myException('请传入正确的参数');
            }
            List<ReceivingNote__c> rnList = [SELECT Id
                        , Internal_asset_location__c
                        , Sales_order_number__c
                        , OrderCode__c
                        , ApprovalNumber__c
                        , DateOfDelivery__c
                        //20210312 you WLIG-BV8CHF start
                        //, ReceivingNoteNo__c
                        , ReceivingNoteNo_New__c
                        //20210312 you WLIG-BV8CHF end
                        //, Status__c
                        , RN_Status__c
                        , Asset_loaner_category__c
                     FROM ReceivingNote__c
                    WHERE Id = :parId];
            if (rnList.size() == 0) {
                throw new ControllerUtil.myException('收货清单Id不存在');
            }
            pageB = new PageBean(rnList[0], assetFieldApiList, receivingNoteFieldApiList);
            String level = ApexPages.currentPage().getParameters().get('level');
            String message = ApexPages.currentPage().getParameters().get('message');
            if(String.isNotBlank(level) && String.isNotBlank(message)){
                if(level == 'info'){
                    ApexPages.Message vfApplyMsg = new ApexPages.Message(ApexPages.severity.INFO, message);
                    ApexPages.addMessage(vfApplyMsg);
                }
                else if(level == 'warning'){
                    ApexPages.Message vfApplyMsg = new ApexPages.Message(ApexPages.severity.WARNING, message);
                    ApexPages.addMessage(vfApplyMsg);
                }
                else if(level == 'error'){
                    ApexPages.Message vfApplyMsg = new ApexPages.Message(ApexPages.severity.ERROR, message);
                    ApexPages.addMessage(vfApplyMsg);
                }
            }
            String fixMode = System.currentPageReference().getParameters().get('fixMode');
            if(fixMode == 'true'){
                pageB.fixMode = true;
            }
            else{
                pageB.fixMode = false;
            }
            pageB.rn.Asset_loaner_category__c = null;
            getShowCountOps();
            changePage();
        }
        catch (Exception e) {
            ApexPages.addMessages(e);
        }
    }

    public List<SelectOption> getShowCountOps() {
        String countStr = System.Label.ReceivingNoteWaitingReceipt_Show_Count;
        List<String> countStrList = countStr.split(':');
        if (String.isBlank(showCount)) {
            showCount = countStrList[1];
        }
        List<SelectOption> opList = new List<SelectOption>();
        for (String str : countStrList[0].split(',')) {
            Integer iStr = Integer.valueOf(str);
            opList.add(new SelectOption(str, str));
        }
        return opList;
    }

    public void nextPage() {
        if (nowPage < maxPage) {
            nowPage ++;
            changePage();
        }
    }

    public void beforePage() {
        if (nowPage > 0) {
            nowPage --;
            changePage();
        }
    }

    private void changePage() {
        maxPage = Integer.valueOf((pageB.rowBList.size() / Integer.valueOf(showCount)));
        maxPage += Math.mod(pageB.rowBList.size(), Integer.valueOf(showCount)) > 0 ? 1 : 0;
        Integer showC = Integer.valueOf(showCount);
        Integer i = (nowPage - 1) * showC;
        Integer k = (pageB.rowBList.size() - i) > showC ? showC : (pageB.rowBList.size() - i);
        pageB.showBList = new List<RowBean>();
        System.debug(k);
        for (Integer j = i; j < i + k; j ++) {
            pageB.showBList.add(pageB.rowBList[j]);
        }
        pageB.currentPageRecordCnt = pageB.showBList.size();
        System.debug(nowPage);
        System.debug(maxPage);
        canNext = nowPage < maxPage;
        canBefore = nowPage > 1;
    }


    public List<SelectOption> getStatusOps() {
        List<FixtureUtil.RNDStatus> rndList = new List<FixtureUtil.RNDStatus>();
        rndList.add(FixtureUtil.RNDStatus.Dai_Shu_Ju_Que_Ren);
        rndList.add(FixtureUtil.RNDStatus.Yi_Shu_Ju_Que_Ren);
        rndList.add(FixtureUtil.RNDStatus.Yi_Shou_Huo_Que_Ren);
        rndList.add(FixtureUtil.RNDStatus.Yi_Qing_Dian);
        rndList.add(FixtureUtil.RNDStatus.Qing_Dian_NG);
        rndList.add(FixtureUtil.RNDStatus.Yi_Yan_Shou);
        rndList.add(FixtureUtil.RNDStatus.Yan_Shou_NG);
        rndList.add(FixtureUtil.RNDStatus.Dai_Ru_Ku_Zhi_Shi);
        rndList.add(FixtureUtil.RNDStatus.Yi_Ru_Ku_Zhi_Shi);
        rndList.add(FixtureUtil.RNDStatus.Yi_Ru_Ku);
        List<SelectOption> opList = new List<SelectOption>();
        opList.add(new SelectOption('', '--无--'));
        for (FixtureUtil.RNDStatus sNum : rndList) {
            String value = FixtureUtil.RNDStatusMap.get(sNum.ordinal());
            opList.add(new SelectOption(value, value));
        }
        return opList;
        //return getPlickList('ReceivingNote__c', 'Status__c');
    }

    public List<SelectOption> getcategoryOps() {
        return getPlickList('ReceivingNote__c', 'Asset_loaner_category__c');
    }

    public void search() {
        nowPage = 1;
        System.debug(assetFieldApiList);
        String wher = '';
        if (String.isNotBlank(pageB.status)) {
            wher += ' AND RND_Status__c = \'' + String.escapeSingleQuotes(pageB.status) + '\'';
        }

        if (String.isNotBlank(pageB.rn.Asset_loaner_category__c)) {
            wher += ' AND Asset_loaner_category_F__c = \'' + String.escapeSingleQuotes(pageB.rn.Asset_loaner_category__c) + '\'';
        }
        if (String.isNotBlank(pageB.fixture_Model_No)) {
            wher += ' AND Fixture_Model_No_F__c = \'' + String.escapeSingleQuotes(pageB.fixture_Model_No) + '\'';
        }
        pageB.search(wher, assetFieldApiList, receivingNoteFieldApiList);
        changePage();
    }

    public void changeFixModel() {
        pageB.fixMode = true;
    }

    private void addField(Set<String> receivingNoteFieldApiSet, Set<String> assetFieldApiSet) {
        receivingNoteFieldApiSet.add('Id');
        receivingNoteFieldApiSet.add('RNDAssert__c');
        receivingNoteFieldApiSet.add('ReceivingNoteSummary__c');
        receivingNoteFieldApiSet.add('Loaner_accsessary__c');
        receivingNoteFieldApiSet.add('DataConfirmation__c');
        receivingNoteFieldApiSet.add('unknow_serial_NO_product__c');
        receivingNoteFieldApiSet.add('ReceivingNoteSummary__r.ReceivingNote__c');
        receivingNoteFieldApiSet.add('ReceivingNoteSummary__r.Select_Fixture_Set_Key__c');
        receivingNoteFieldApiSet.add('Inspection_result_after__c');
        receivingNoteFieldApiSet.add('ReceivingNoteSummary__r.Wei_Arrival_wh_Request_Cnt__c');
        receivingNoteFieldApiSet.add('Arrival_wh_Request_time__c');
        receivingNoteFieldApiSet.add('DataConfirmationAgainStaff__c');
        receivingNoteFieldApiSet.add('DataConfirmationAgainTime__c');

    }

    private List<SelectOption> getPlickList(String objApi, String fieldApi) {
        Schema.DescribeFieldResult fieldResult = Schema.getGlobalDescribe().get(objApi).getDescribe().fields.getMap().get(fieldApi).getDescribe();
        List<SelectOption> pickListValuesList= new List<SelectOption>();
        List<Schema.PicklistEntry> ple = fieldResult.getPicklistValues();
        pickListValuesList.add(new SelectOption('', NONE));
        for( Schema.PicklistEntry pickListVal : ple){
            pickListValuesList.add(new SelectOption(pickListVal.getValue(), pickListVal.getLabel()));
        }
        return pickListValuesList;
    }

    private List<LabelValue> setFIeldSet(String objApi, String fieldSetApi, Set<String> fieldApiSet) {
        List<LabelValue> lvList = new List<LabelValue>();
        Map<String, Schema.FieldSet> fsMap = Schema.getGlobalDescribe().get(objApi).getDescribe().fieldSets.getMap();
        Schema.FieldSet fs = fsMap.get(fieldSetApi);
        List<FieldSetMember> fsmList = fs.getFields();

        for (FieldSetMember fsm : fsmList) {
            if (objApi == 'Asset') {
                fieldApiSet.add('RNDAssert__r.' + fsm.getFieldPath());
            }
            else {
                fieldApiSet.add(fsm.getFieldPath());
            }
            lvList.add(new LabelValue(fsm.getLabel(), fsm.getFieldPath()));
        }
        return lvList;
    }

    // 适用区域信息提示
    public void showApplyMsg() {
        String applyMsg = ApexPages.currentPage().getParameters().get('applyMsg');
        String applyMsgType = ApexPages.currentPage().getParameters().get('applyMsgType');
        String applyErrorLabel = ApexPages.currentPage().getParameters().get('applyErrorLabel');
        if(applyMsgType == 'Fail') {
            ApexPages.Message vfApplyMsg = new ApexPages.Message(ApexPages.severity.ERROR, applyMsg);
            ApexPages.addMessage(vfApplyMsg);
            System.debug('applyMsg===' + applyMsg);
            System.debug('applyMsgType===' + applyMsgType);
            System.debug('applyErrorLabel===' + applyErrorLabel);
            if(applyErrorLabel != null) {
                System.debug('applyErrorLabel===' + applyErrorLabel);
            }
        } else {
            ApexPages.Message vfApplyMsg = new ApexPages.Message(ApexPages.severity.INFO, applyMsg);
            ApexPages.addMessage(vfApplyMsg);
        }
    }

    // 保存画面上的数据
    public PageReference saveRecord() {
        PageReference pageRef = Page.ReceivingNoteStockInRequest;
        pageRef.getParameters().put('parId',parId);
        pageRef.setRedirect(true);
        try {
            List<ReceivingNoteDetail__c> rndList = new List<ReceivingNoteDetail__c>();
            Boolean allDataConfirmAgain = true;
            Datetime now = System.Now();
            String userId = Userinfo.getUserId();
            Map<Id, ReceivingNoteDetail__c> originRndMap = new Map<Id, ReceivingNoteDetail__c>([
                    SELECT Id
                         , Inspection_result_after__c
                         , Arrival_wh_Request_time__c
                      FROM ReceivingNoteDetail__c
                     WHERE ReceivingNote__c =:pageB.rn.Id
                    ]);
            for (RowBean rowB : pageB.showBList) {
                if (rowB.checked) {
                    if(!originRndMap.containsKey(rowB.rnd.Id)){
                        throw new ControllerUtil.myException('【'+ rowB.rnd.ReceivingNoteDetailNo__c +'】已被删除，请重试。');
                    }
                    else if(originRndMap.get(rowB.rnd.Id).Inspection_result_after__c != 'OK') {
                        throw new ControllerUtil.myException('【'+ rowB.rnd.ReceivingNoteDetailNo__c +'】未验收成功，请重试。');
                    }
                    else if(originRndMap.get(rowB.rnd.Id).Arrival_wh_Request_time__c != null) {
                        throw new ControllerUtil.myException('【'+ rowB.rnd.ReceivingNoteDetailNo__c +'】已做入库指示，请重试。');
                    }
                    if(!rowB.rnd.DataConfirmationAgain__c){
                        allDataConfirmAgain = false;
                    }
                    if(rowB.rnd.DataConfirmationAgain__c){
                        rowB.rnd.DataConfirmationAgainTime__c = now;
                        rowB.rnd.DataConfirmationAgainStaff__c = userId;
                    }
                    else{
                        rowB.rnd.DataConfirmationAgainTime__c = null;
                        rowB.rnd.DataConfirmationAgainStaff__c = null;
                    }
                    rndList.add(rowB.rnd);
                }
            }
            if (rndList.size() > 0) {
                update rndList;
                pageB.fixMode = false;
                if (allDataConfirmAgain){
                    pageRef.getParameters().put('message','再数据确认完了');
                }
                else{
                    pageRef.getParameters().put('message','保存完成');
                }
                pageRef.getParameters().put('level','info');
            }
            else {
                pageRef.getParameters().put('level','warning');
                pageRef.getParameters().put('message','未勾选明细');
            }
        }
        catch (Exception e) {
            pageRef.getParameters().put('level','error');
            pageRef.getParameters().put('message',e.getMessage());
        }
        pageRef.getParameters().put('fixMode','' + pageB.fixMode);
        return pageRef;
    }



    // 取消按钮Action，已弃用
    //public PageReference cancelRecord() {
    //    try {
    //        List<ReceivingNoteDetail__c> rndList = new List<ReceivingNoteDetail__c>();
    //        for (RowBean rowB : pageB.rowBList) {
    //            if (rowB.checked) {
    //                rowB.rnd.Delete_Flag__c = true;
    //                rndList.add(rowB.rnd);
    //            }
    //        }
    //        if (rndList.size() > 0) {
    //            update rndList;
    //        }
    //        else {
    //            ApexPages.Message vfApplyMsg = new ApexPages.Message(ApexPages.severity.WARNING, '没有需要取消的收货清单配套一览');
    //            ApexPages.addMessage(vfApplyMsg);
    //        }
    //        search();
    //        // pageB.search(null, assetFieldApiList, receivingNoteFieldApiList);
    //    }
    //    catch (Exception e) {
    //        ApexPages.addMessages(e);
    //    }
    //    pageB.fixMode = false;
    //    return null;
    //}

    public PageReference reject() {
        PageReference pageRef = Page.ReceivingNoteStockInRequest;
        pageRef.getParameters().put('parId',parId);
        pageRef.setRedirect(true);
        try {
            List<ReceivingNoteDetail__c> rndList = new List<ReceivingNoteDetail__c>();
            Datetime now = Datetime.now();
            Boolean hasCheckedBox = false;
            String userId = Userinfo.getUserId();
            Map<Id, ReceivingNoteDetail__c> originRndMap = new Map<Id, ReceivingNoteDetail__c>([
                    SELECT Id
                         , Inspection_result_after__c
                         , DataConfirmationAgain__c
                      FROM ReceivingNoteDetail__c
                     WHERE ReceivingNote__c =:pageB.rn.Id
                    ]);
            for (RowBean rowB : pageB.showBList) {
                if (rowB.checked) {
                    if(!originRndMap.containsKey(rowB.rnd.Id)){
                        throw new ControllerUtil.myException('【'+ rowB.rnd.ReceivingNoteDetailNo__c +'】已被删除，无法驳回，请重试。');
                    }
                    else if(originRndMap.get(rowB.rnd.Id).DataConfirmationAgain__c) {
                        throw new ControllerUtil.myException('【'+ rowB.rnd.ReceivingNoteDetailNo__c +'】已再数据确认，无法驳回，请重试。');
                    }
                    else if(originRndMap.get(rowB.rnd.Id).Inspection_result_after__c != 'OK') {
                        throw new ControllerUtil.myException('【'+ rowB.rnd.ReceivingNoteDetailNo__c +'】未验收成功，无法驳回，请重试。');
                    }
                    if (rowB.rnd.DataConfirmationAgain__c) {
                        throw new ControllerUtil.myException('请先取消再确认数据,然后再驳回');
                    }
                    hasCheckedBox = true;
                    if (String.isBlank(rowB.rnd.Reject_Reason__c)) {
                         throw new ControllerUtil.myException('驳回必须填写驳回理由');
                    }
                    rowB.rnd.Reject_Time__c = now;
                    rowB.rnd.RejectStaff__c = userId;
                    rowB.rnd.After_Inspection_time__c = null;
                    rowB.rnd.Inspection_staff_After__c = null;
                    rowB.rnd.Inspection_Comment__c = null;
                    rowB.rnd.Inspection_result_after__c = null;
                    rowB.rnd.Received_Quantity__c = 0;
                    rowB.rnd.Inspection_Cnt__c = 0;
                    rndList.add(rowB.rnd);
                }
            }
            if(!hasCheckedBox){
                pageRef.getParameters().put('message','未勾选明细');
                pageRef.getParameters().put('level','warning');
            }
            else if (rndList.size() > 0) {
                update rndList;
                pageRef.getParameters().put('message','已驳回');
                pageRef.getParameters().put('level','info');
            }
        }
        catch (Exception e) {
            pageRef.getParameters().put('level','error');
            pageRef.getParameters().put('message',e.getMessage());
        }
        pageRef.getParameters().put('fixMode', '' + pageB.fixMode);
        return pageRef;
    }

    public PageReference inStockRequest() {
        PageReference pageRef = Page.ReceivingNoteStockInRequest;
        pageRef.getParameters().put('parId',parId);
        pageRef.setRedirect(true);
        try {
            if (pageB.fixMode) {
                throw new ControllerUtil.myException('请先保存再做入库指示');
            }
            List<ReceivingNoteDetail__c> rndList = new List<ReceivingNoteDetail__c>();
            Datetime now = Datetime.now();
            Map<Id, ReceivingNoteDetail__c> originRndMap = new Map<Id, ReceivingNoteDetail__c>([
                    SELECT Id
                         , DataConfirmationAgain__c
                         , Arrival_in_wh__c
                      FROM ReceivingNoteDetail__c
                     WHERE ReceivingNote__c =:pageB.rn.Id
                    ]);
            for (RowBean rowB : pageB.showBList) {
                if (rowB.checked) {
                    if(!originRndMap.containsKey(rowB.rnd.Id)){
                        throw new ControllerUtil.myException('【'+ rowB.rnd.ReceivingNoteDetailNo__c +'】已被删除，请重试。');
                    }
                    else if(!originRndMap.get(rowB.rnd.Id).DataConfirmationAgain__c) {
                        throw new ControllerUtil.myException('【'+ rowB.rnd.ReceivingNoteDetailNo__c +'】未再数据确认，请重试。');
                    }
                    else if(originRndMap.get(rowB.rnd.Id).Arrival_in_wh__c) {
                        throw new ControllerUtil.myException('【'+ rowB.rnd.ReceivingNoteDetailNo__c +'】已入库，请重试。');
                    }
                    rowB.rnd.Arrival_wh_Request_time__c = now;
                    rndList.add(rowB.rnd);
                }
            }
            if (rndList.size() > 0) {
                update rndList;
                pageRef.getParameters().put('message','入库指示完了');
                pageRef.getParameters().put('level','info');
            }
            else {
                pageRef.getParameters().put('message','未勾选明细');
                pageRef.getParameters().put('level','waring');
            }
        }
        catch (Exception e) {
            pageRef.getParameters().put('level','error');
            pageRef.getParameters().put('message',e.getMessage());
        }
        pageRef.getParameters().put('fixMode','' + pageB.fixMode);
        return pageRef;
    }


    public class PageBean {
        /* ------------ 复数编辑用 ------------ */
        public ReceivingNoteDetail__c assetInput {get{
            if (assetInput == null) {
                assetInput = [SELECT Id
                         FROM ReceivingNoteDetail__c
                        LIMIT 1];
                assetInput = new ReceivingNoteDetail__c(Id = assetInput.Id);
            }
            return assetInput;
        } set;}

        /* ------------ 检索用 ------------ */
        public ReceivingNote__c rn {get; set;}
        public String fixture_Model_No {get; set;}
        public String status {get; set;}

        /* ------------  显示用 ------------ */
        public String dateOfDelivery {get; set;}

        /* ------------ 明细一覧 ------------ */
        public List<RowBean> rowBList {get; set;}
        public List<RowBean> showBList {get; set;}

        /* ------------ 记录用 ------------ */
        public Boolean fixMode {get; set;}
        public Integer currentPageRecordCnt {get; set;}

        public PageBean() {
            rn = new ReceivingNote__c();
            rowBList = new List<RowBean>();
            showBList = new List<RowBean>();
            fixMode = false;
            currentPageRecordCnt = 0;
        }

        public PageBean(ReceivingNote__c rnObj, List<String> assetFieldApiList, List<String> receivingNoteFieldApiList) {
            rn = rnObj;
            dateOfDelivery = rnObj.DateOfDelivery__c == null ? '' : rnObj.DateOfDelivery__c.format();
            rowBList = new List<RowBean>();
            showBList = new List<RowBean>();
            fixMode = false;
            search(null, assetFieldApiList, receivingNoteFieldApiList);
        }

        public void search(String wher, List<String> assetFieldApiList, List<String> receivingNoteFieldApiList) {
            wher = String.isBlank(wher) ? '' : wher;
            System.debug(assetFieldApiList);
            String soql = 'SELECT '
                    + String.join(assetFieldApiList, ',')
                    + (assetFieldApiList.size() > 0 ? ',' : '')
                    + String.join(receivingNoteFieldApiList, ',')
                 + ' FROM ReceivingNoteDetail__c '
                + ' WHERE ReceivingNoteSummary__r.ReceivingNote__c = \'' + rn.Id + '\'' + wher
                  + ' AND Delete_Flag__c = false '
                + ' ORDER BY ReceivingNoteSummary__c, ReceivingNoteDetailNo__c, RNDAssert__c nulls last';
            rowBList = new List<RowBean>();
            showBList = new List<RowBean>();
            System.debug(soql);
            List<ReceivingNoteDetail__c> rndList = Database.query(soql);
            Integer i = 0;
            for (ReceivingNoteDetail__c rnd : rndList) {
                rowBList.add(new RowBean(rnd, i));
                i ++;
            }
            currentPageRecordCnt = showBList.size();
        }
    }

    public class RowBean {
        public Boolean checked {get; set;}
        public Boolean canChange {get; set;}
        public Boolean dataConfirmation {get; set;}
        public String canChangeField {get; set;}
        public String canNotChangeField {get;set;}
        public Integer lineNo {get; set;}
        public Boolean haveAsset {get; set;}
        public ReceivingNoteDetail__c rnd {get; set;}
        // public Asset asse {get; set;}

        public RowBean() {
            checked = false;
            rnd = new ReceivingNoteDetail__c();
            // asse = new Asset();
            canChange = true;
            dataConfirmation = false;
            canChangeField = '';
        }

        public RowBean(ReceivingNoteDetail__c rnd1, Integer lineNo1) {
            rnd = rnd1;
            // asse = rnd1.RNDAssert__r;
            checked = false;
            canChange = false;
            lineNo = lineNo1;
            canNotChangeField = 'null';
            canChangeField = 'Reject_Reason__c, DataConfirmationAgain__c';
            haveAsset = String.isNotBlank(rnd1.RNDAssert__c);
            // 验收OK 未入库指示 才可编辑
            if(rnd.Inspection_result_after__c == 'OK'
                && rnd.Arrival_wh_Request_time__c == null) {
                canChange = true;
            }
        }
    }

    public class LabelValue {
        public String label {get; set;}
        public String value {get; set;}

        public LabelValue() {
            label = '';
            value = '';
        }

        public LabelValue(String l, String v) {
            label = l;
            value = v;
        }
    }

}