public without sharing class TransferShippmentReceived3Controller {
    public FixtureDeliverySlip__c slip { get; set; }
    public TransferApplySummary__c es { get; set; }
    public List<EsdInfo> esdList { get; set; }
    public Boolean saveBtnDisabled { get; private set; }
    public boolean ReturnRefuse {get;private set;}
    public String ErrorMessage {get; set;}
    public String CDSFinished {get;set;}
    public boolean LostFlg {get;set;}
    public String Step_status { get; private set; }
    public Boolean needCDS { get; private set; }
    public Boolean done_flg { get; set; }
    public String Raid {get;set;}
    public String ApplyId {get;set;}
    public String CheckedId {get;set;}
    public String UnCheckedId {get;set;}
    private String Id;

    public Integer getEsdListSize() {
        return esdList.size();
    }

    public TransferShippmentReceived3Controller() {
        Id = ApexPages.currentPage().getParameters().get('id');
        if (Step_status == null) {
            Step_status = ApexPages.currentPage().getParameters().get('step');
        }
        ApplyId = Id;
    }

    public PageReference searchSlip() {
        Map<String,boolean> esdIdMap = new Map<String,boolean>();
        for (EsdInfo esd : esdList) {
            if (!esd.hasSended)
            esdIdMap.put(esd.rec.Id, esd.isChecked);
        }

        String qryString = 'select Combine_Pack__c, Name, Id, DeliveryCompany_SlipNo__c,DeliveryType__c,Distributor_method__c,DeliveryCompany__c,Wh_Staff__c '
                + 'from FixtureDeliverySlip__c '
                + 'where Name =\''+ slip.Name +'\' and DeliveryType__c = \'发货\'';
        if (String.isNotBlank(slip.Distributor_method__c)) {
            qryString += ' and Distributor_method__c = \''+ slip.Distributor_method__c +'\'';
        }
        if (String.isNotBlank(slip.DeliveryCompany__c)) {
            qryString += ' and DeliveryCompany__c = \''+ slip.DeliveryCompany__c +'\'';
        }
        List<FixtureDeliverySlip__c> slipList = Database.query(qryString);

        if (slipList.size() > 0) {
            if (slipList.size() > 1) {
                ApexPages.addmessage(new ApexPages.message(ApexPages.severity.Error, '当前条件检索到复数条运输单，请追加检索条件!'));
                return null;
            }
            slip = slipList[0];

            List<TransferApplyDetail__c> eList = [select TransferApply__c, TransferApply__r.Shippment_ng_num__c, TransferApply__r.Pre_inspection_ng_num__c, SerialNumber_F__c, TransferApplySummary__r.Inspection_not_finish__c, Fixture_Name_F__c, TransferApplySummary__r.Fixture_Set__r.Name, TransferApplySummary__r.TransferApply__r.Name, TransferApplySummary__r.Name, Pre_inspection_time__c, StockDown__c, StockDown_time__c, Id, Name, Asset__c, Asset__r.Name, Asset__r.SerialNumber, Asset__r.Product_Serial_No__c,
                           TransferApply__r.Name, Asset__r.Remark__c, Asset__r.ImageAsset__c, Asset__r.ImageSerial__c, Asset__r.ImageAssetUploadedTime__c, Asset__r.ImageSerialUploadedTime__c,
                           Loaner_CDS_Info__c, Inspection_result__c, Check_lost_Item__c, Pre_disinfection__c, Water_leacage_check__c, Inspection_result_after__c, Arrival_in_wh__c,
                           Asset__r.Pre_Reserve_TAES_Detail__c, Asset__r.Pre_Reserve_TAES_Detail__r.After_Inspection_time__c,
                           Inspection_result_after_ng__c, Inspection_result_ng__c, Lost_item_giveup__c, CDS_complete__c, Loaner_accsessary__c
                      from TransferApplyDetail__c
                     where (DeliverySlip__c = :slip.Id or Id in :esdIdMap.keySet())
                       and Cancel_Select__c = False and Return_DeliverySlip__c = null
                     order by TransferApplySummary__r.Name, TransferApplySummary__c, Name ];

            esdList.clear();
            for (TransferApplyDetail__c esd : eList) {
                EsdInfo esdinfo;
                if (esdIdMap.containsKey(esd.Id)) {
                    esdinfo = new EsdInfo(esd, esdIdMap.get(esd.Id));
                } else {
                    esdinfo = new EsdInfo(esd, true);
                    esdInfo.hasSended = true;
                }
                esdList.add(esdInfo);
            }
        }
        return null;
    }

    public PageReference filljsQRAction() {
        List<String> ids = ApplyId.split(',');
        Set<String> checkedIds = new Set<String>(CheckedId.split(':'));
        CheckedId = null;
        List<TransferApplySummary__c> esList = [
            SELECT TransferApply__r.Name
                 , First_TAD_Model_No_F__c
                 , First_TAD__r.SerialNumber_F__c
                 , First_TAD__r.Loaner_asset_no__c
                 , TransferApply__c, Id
                 , TAS_Status__c, Name, Shippment_loaner_time2__c
              FROM TransferApplySummary__c
             WHERE (TransferApply__r.Name in :ids or Id in :ids)
               AND Cancel_Select__c = False
          ORDER BY TransferApply__r.Name, Id
        ];
        Set<Id> esIds = new Set<Id>();
        Set<Id> esdIds = new Set<Id>();
        Set<Id> applySet = new Set<Id>();
        for (TransferApplySummary__c raes : esList) {
            esIds.add(raes.Id);
            applySet.add(raes.TransferApply__c);
        }
        Raid = String.join(new List<Id>(applySet), ':');
        for (EsdInfo raesd : esdList) {
            esdIds.add(raesd.rec.Id);
        }
        List<TransferApplyDetail__c> eList = [
                SELECT TransferApply__c, TransferApply__r.Shippment_ng_num__c, TransferApply__r.Pre_inspection_ng_num__c, SerialNumber_F__c, TransferApplySummary__r.Inspection_not_finish__c, Fixture_Name_F__c, TransferApplySummary__r.Fixture_Set__r.Name, TransferApplySummary__r.TransferApply__r.Name, TransferApplySummary__r.Name, Pre_inspection_time__c, StockDown__c, StockDown_time__c, Id, Name, Asset__c, Asset__r.Name, Asset__r.SerialNumber, Asset__r.Product_Serial_No__c,
                       TransferApply__r.Name, Asset__r.Remark__c, Asset__r.ImageAsset__c, Asset__r.ImageSerial__c, Asset__r.ImageAssetUploadedTime__c, Asset__r.ImageSerialUploadedTime__c,
                       Loaner_CDS_Info__c, Inspection_result__c, Check_lost_Item__c, Pre_disinfection__c, Water_leacage_check__c, Inspection_result_after__c, Arrival_in_wh__c,
                       Asset__r.Pre_Reserve_TAES_Detail__c, Asset__r.Pre_Reserve_TAES_Detail__r.After_Inspection_time__c,
                       Inspection_result_after_ng__c, Inspection_result_ng__c, Lost_item_giveup__c, CDS_complete__c, Loaner_accsessary__c
                  FROM TransferApplyDetail__c
                 WHERE TransferApplySummary__c IN :esIds
                   AND DeliverySlip__c = null
                   AND Return_DeliverySlip__c = null
                   AND Cancel_Select__c = False
              ORDER BY TransferApplySummary__r.TransferApply__r.Name, TransferApplySummary__r.Name, TransferApplySummary__c, Name
        ];
        for (TransferApplyDetail__c esd : eList) {
            if (!esdIds.contains(esd.Id)) {
                esdList.add(new EsdInfo(esd, false));
            }
        }

        for (EsdInfo raesd : esdList) {
            if (checkedIds.contains(raesd.rec.TransferApplySummary__c)) {
                raesd.isChecked = true;
            }
        }
        return null;
    }

    // 画面初始化
    public PageReference init() {
        done_flg = false;
        es = new TransferApplySummary__c();
        slip = new FixtureDeliverySlip__c();
        esdList = new List<EsdInfo>();
        Set<Id> esIds = new Set<Id>();
        saveBtnDisabled = false;
        ReturnRefuse = true;
        ErrorMessage = '';
        if (Id != null) {
            // 当前User
            String userid = Userinfo.getUserId();
            User user = [SELECT Id, Name FROM User WHERE Id = :userid];
            List<TransferApplySummary__c> esList;
            List<String> ids = Id.split(',');
            esList = [
                SELECT TransferApply__r.Name
                     , First_TAD_Model_No_F__c
                     , First_TAD__r.SerialNumber_F__c
                     , First_TAD__r.Loaner_asset_no__c
                     , TransferApply__c
                     , Id
                     , TAS_Status__c
                     , Name
                     , Shippment_loaner_time2__c
                  FROM TransferApplySummary__c
                 WHERE (TransferApply__r.Name IN :ids OR Id IN:ids)
                   AND Cancel_Select__c = False
              ORDER BY TransferApply__r.Name, Id];
            slip.Wh_Staff__c = userid;
            slip.DeliveryType__c = '发货';
            slip.IsForTransfer__c = true;

            if (esList.size() > 0) {
                for (TransferApplySummary__c raes : esList) {
                    esIds.add(raes.Id);
                    Raid = raes.TransferApply__c;
                }
            } else {
                ApexPages.addmessage(new ApexPages.message(ApexPages.severity.Error, '备品不存在'));
                saveBtnDisabled = true;
                return null;
            }
        }

        // 备品set明细
        List<TransferApplyDetail__c> eList = [
                select TransferApply__c, TransferApply__r.Shippment_ng_num__c, TransferApply__r.Pre_inspection_ng_num__c, SerialNumber_F__c, TransferApplySummary__r.Inspection_not_finish__c, Fixture_Name_F__c, TransferApplySummary__r.TAS_Status__c, TransferApplySummary__r.Fixture_Set__r.Name, TransferApplySummary__r.TransferApply__r.Name, TransferApplySummary__r.Name, Pre_inspection_time__c, StockDown__c, StockDown_time__c, Id, Name, Asset__c, Asset__r.Name, Asset__r.SerialNumber, Asset__r.Product_Serial_No__c,
                       TransferApply__r.Name, Asset__r.Remark__c, Asset__r.ImageAsset__c, Asset__r.ImageSerial__c, Asset__r.ImageAssetUploadedTime__c, Asset__r.ImageSerialUploadedTime__c,
                       Loaner_CDS_Info__c, Inspection_result__c, Check_lost_Item__c, Pre_disinfection__c, Water_leacage_check__c, Inspection_result_after__c, Arrival_in_wh__c,
                       Asset__r.Pre_Reserve_TAES_Detail__c, Asset__r.Pre_Reserve_TAES_Detail__r.After_Inspection_time__c,
                       Inspection_result_after_ng__c, Inspection_result_ng__c, Lost_item_giveup__c, CDS_complete__c, Loaner_accsessary__c
                  from TransferApplyDetail__c
                 where TransferApplySummary__c in :esIds and DeliverySlip__c = null and Return_DeliverySlip__c = null//and Shipment_request_time__c <> null
                   and Cancel_Select__c = False
                 order by TransferApplySummary__r.TransferApply__r.Name, TransferApplySummary__r.Name, TransferApplySummary__c, Name
        ];


        needCDS = false;
        for (TransferApplyDetail__c esd : eList) {
            esdList.add(new EsdInfo(esd));
        }

        if (String.isBlank(Step_status)) {
            Step_status = '追加';
        }

        if (esdList.size() <= 0) {
            ApexPages.addmessage(new ApexPages.message(ApexPages.severity.Error, '没有备品set明细'));
            saveBtnDisabled = true;
            return null;
        }

        return null;
    }

    // Step 切り替えボタン、发货前-检测
    public PageReference ShippmentDetail() {
        Step_status = '明细';

        if (!String.isBlank(CheckedId)) {
            Map<String, Set<String>> shipcount = new Map<String, Set<String>>();
            Map<String, Integer> allcount = new Map<String, Integer>();
            Set<String> checkedIds = new Set<String>(CheckedId.split(':'));
            for (EsdInfo esd : esdList) {
                boolean checked = checkedIds.contains(esd.rec.TransferApplySummary__c);
                esd.isChecked = checked;
                if (checked) {
                    Set<String> count = new Set<String>();
                    if (shipcount.containsKey(esd.rec.TransferApply__c)) {
                        count = shipcount.get(esd.rec.TransferApply__c);
                    }
                    count.add(esd.rec.TransferApplySummary__c);
                    shipcount.put(esd.rec.TransferApply__c, count);
                    allcount.put(esd.rec.TransferApply__c, Integer.valueOf(esd.rec.TransferApply__r.Shippment_ng_num__c));
                }
            }

            for (String raid : allcount.keySet()) {
                if (allcount.get(raid) > shipcount.get(raid).size()) {
                    Step_status = '追加';
                    //ApexPages.addmessage(new ApexPages.message(ApexPages.severity.Error, '申请单内存在未勾选的配套，请勾选全部配套或分割申请单!'));
                    ApexPages.addmessage(new ApexPages.message(ApexPages.severity.Error, '必须整单发货!'));
                }
            }
        }
        CheckedId = null;

        return null;
    }

    // Step 切り替えボタン、发货-发货运输单号 等
    public PageReference ShippmentAdd() {
        Step_status = '追加';
        return null;
    }

    public PageReference deleteDetail() {
        List<TransferApplyDetail__c> updDetails = new List<TransferApplyDetail__c>();
        for (EsdInfo esd : esdList) {
            if (esd.rec.TransferApplySummary__c == UnCheckedId) {
                if (esd.hasSended) {
                    esd.rec.DeliverySlip__c = null;
                    updDetails.add(esd.rec);
                } else {
                    esd.isChecked = false;
                }
            }
        }
        UnCheckedId = null;
        if (updDetails.size() > 0) {
            update updDetails;
            searchSlip();
        }

        return null;
    }

    // 保存按钮
    public PageReference save() {

        List<String> raids = Raid.split(':');
        //检查是否可以继续
        List<TransferApply__c> RaTarList = [select Campaign__c,Repair__c,
                                                Campaign__r.Status,repair__r.Return_Without_Repair_Date__c,Repair__r.Repair_Final_Inspection_Date__c,Repair__r.Repair_Shipped_Date__c
                                            from TransferApply__c
                                            where id in :raids];
        for (TransferApply__c RaTar : RaTarList) {
            if( RaTar.Campaign__r.Status == '取消'){

                ApexPages.addmessage(new ApexPages.message(ApexPages.severity.Error, '学会已取消，不能继续操作了'));
                return null;
            }else if(RaTar.Repair__r.Repair_Final_Inspection_Date__c!=null){

                ApexPages.addmessage(new ApexPages.message(ApexPages.severity.Error, '存在修理最终检测日，不能继续了'));
                return null;
            }else if(RaTar.repair__r.Return_Without_Repair_Date__c!=null&&RaTar.repair__c!=null ){

                ApexPages.addmessage(new ApexPages.message(ApexPages.severity.Error, '未修理归还日不为空，不能出库'));
                return null;
            }else if(RaTar.Repair__r.Repair_Shipped_Date__c!=null){

                ApexPages.addmessage(new ApexPages.message(ApexPages.severity.Error, '存在RC修理返送日，不能继续了'));
                return null;
            }
        }

        //检查是否可以继续
        String userid = Userinfo.getUserId();
        Set<Id> eSet = new Set<Id>();
        List<TransferApplyDetail__c> eList = new List<TransferApplyDetail__c>();
        //申请书set
        Set<String> raSet = new Set<String>();
        for (EsdInfo esdInfo : esdList) {
            if (esdInfo.isChecked && !esdInfo.hasSended) {
                TransferApplyDetail__c esd = esdInfo.rec;
                eSet.add(esd.Id);
                raSet.add(esd.TransferApply__c);
            }
            else if(!esdInfo.isChecked && !esdInfo.hasSended) {
                ApexPages.addmessage(new ApexPages.message(ApexPages.severity.Error, '必须整单发货'));
                return null;
            }
        }
        if (eSet.size() == 0) {
            ApexPages.addmessage(new ApexPages.message(ApexPages.severity.Error, '未选择备品set，不能创建发货单'));
            return null;
        }
        eList = [select TransferApply__c, TransferApply__r.Shippment_ng_num__c, TransferApply__r.Pre_inspection_ng_num__c, TransferApplySummary__r.Inspection_not_finish__c, Fixture_Name_F__c, TransferApplySummary__r.Fixture_Set__r.Name, TransferApplySummary__r.TransferApply__r.Name, TransferApplySummary__r.Name, Pre_inspection_time__c, StockDown__c, StockDown_time__c, Id, Name, Asset__c, Asset__r.Name, Asset__r.SerialNumber, Asset__r.Product_Serial_No__c,
                           TransferApply__r.Name, Asset__r.Remark__c, Asset__r.ImageAsset__c, Asset__r.ImageSerial__c, Asset__r.ImageAssetUploadedTime__c, Asset__r.ImageSerialUploadedTime__c,
                           Loaner_CDS_Info__c, Inspection_result__c, Check_lost_Item__c, Pre_disinfection__c, Water_leacage_check__c, Inspection_result_after__c, Arrival_in_wh__c,
                           Asset__r.Pre_Reserve_TAES_Detail__c, Asset__r.Pre_Reserve_TAES_Detail__r.After_Inspection_time__c,
                           Inspection_result_after_ng__c, Inspection_result_ng__c, Lost_item_giveup__c, CDS_complete__c, Loaner_accsessary__c
                    from TransferApplyDetail__c where Id in :eSet for update];
        Boolean needSaveSet = false;
        Boolean needSaveDetail = false;
        Boolean needDeliverySlip = false;

        Set<Id> astForLock = new Set<Id>();
        for (TransferApplyDetail__c esd : eList) {
            if (esd.Inspection_result__c <> null && esd.StockDown__c == false) {
                ApexPages.addmessage(new ApexPages.message(ApexPages.severity.Error, '备品set未下架，不能填写发货前检查结果'));
                return null;
            }
            astForLock.add(esd.Asset__c);
        }
        List<Asset> astLock = [select Id
                 from Asset
                where id in :astForLock
                  for update];

        if (Step_status == '明细') {
            needDeliverySlip = true;

            if (slip.Id != null) {
                slip = [select Combine_Pack__c, Name, Id, DeliveryCompany_SlipNo__c,DeliveryType__c,Distributor_method__c,DeliveryCompany__c,Wh_Staff__c
                        from FixtureDeliverySlip__c
                        where Id =:slip.Id for update];
            }
            slip.Shippment_loaner_time__c = Datetime.now();
            needSaveDetail = true;
        }
        List<TransferApply__c> raList = [SELECT Id, DeliverySlip__c FROM TransferApply__c WHERE Id IN :raSet];
        Savepoint sp = Database.setSavepoint();
        try {
            // 调拨发货优化追加 20230706 lc Start
            TransferApplyDetailHandler.skipUpdateAgain = true;
            // 调拨发货优化追加 20230706 lc End

            if (needDeliverySlip) {
                // 20230928 ljh Start
                if(String.isBlank(slip.Name)
                    || String.isBlank(slip.DeliveryCompany__c)
                    || String.isBlank(slip.Distributor_method__c)
                    || String.isBlank(slip.Wh_Staff__c)) {
                    ApexPages.addmessage(new ApexPages.message(ApexPages.severity.Error, '发货物流信息必填！'));
                    return null;
                }
                // 20230928 ljh Start
                FixtureUtil.withoutUpsertObjects(new List<FixtureDeliverySlip__c>{ slip });
                for (TransferApplyDetail__c esd : eList) {
                    esd.DeliverySlip__c = slip.Id;
                }

                for (TransferApply__c ra : raList) {
                    ra.DeliverySlip__c = slip.Id;
                }
            }
            if (needSaveDetail) {
                FixtureUtil.withoutUpsertObjects(eList);
                FixtureUtil.withoutUpsertObjects(raList);
            }

            done_flg = true;
            return null;
        } catch (Exception ex) {
            String msg = ex.getMessage();
            if (msg != null && msg.contains('DUPLICATE_VALUE') && msg.contains('DeliveryCompany_SlipNo__c')) {
                ApexPages.addmessage(new ApexPages.message(ApexPages.severity.Error, '系统已存在相同的运输单。如果继续使用该运输单发货，请输入运输单号检索，检索后再勾选配套发货。'));
            } else {
                ApexPages.addmessage(new ApexPages.message(ApexPages.severity.Error, msg));
            }
            Database.rollback(sp);
            done_flg = false;
            return null;
        }

        return null;
    }

    public class EsdInfo {
        public TransferApplyDetail__c rec { get; set; }
        public String imageAssetUploadedTime { get; set; }
        public String imageSerialUploadedTime { get; set; }
        // 回库はSet単位で、明細一つ一つのquickCheck要らない
        public boolean quickCheck { get; set; }
        public boolean isChecked { get; set; }
        public boolean hasSended { get; set; }
        public Boolean inspectionFinished {get;set;}
        public String fsName {get;set;}

        public EsdInfo(TransferApplyDetail__c rec, boolean checked) {
            this.rec = rec;
            this.isChecked = checked;
            this.hasSended = false;
            this.inspectionFinished = rec.TransferApplySummary__r.Inspection_not_finish__c == 0;
            this.fsName = rec.TransferApplySummary__r.Name;
            if(String.isNotBlank(rec.TransferApplySummary__r.Fixture_Set__r.Name)){
                this.fsName += ':' + rec.TransferApplySummary__r.Fixture_Set__r.Name;
            }
            if (rec.Asset__r.Pre_Reserve_TAES_Detail__c != null && rec.Asset__r.Pre_Reserve_TAES_Detail__r.After_Inspection_time__c != null) {
                this.quickCheck = Datetime.now() < rec.Asset__r.Pre_Reserve_TAES_Detail__r.After_Inspection_time__c + 30 ? true : false;
            } else {
                this.quickCheck = false;
            }

            if (rec.Asset__r.ImageAssetUploadedTime__c != null) {
                imageAssetUploadedTime = rec.Asset__r.ImageAssetUploadedTime__c.format('yyyy/MM/dd HH:mm');
            }
            if (rec.Asset__r.ImageSerialUploadedTime__c != null) {
                imageSerialUploadedTime = rec.Asset__r.ImageSerialUploadedTime__c.format('yyyy/MM/dd HH:mm');
            }
        }

        public EsdInfo(TransferApplyDetail__c rec) {
            this(rec, false);
        }
    }
}