package com.patzn.lims.frame.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.patzn.lims.common.StringHandleUtils;
import com.patzn.lims.core.api.PtAssert;
import com.patzn.lims.core.oss.OssClient;
import com.patzn.lims.core.web.Account;
import com.patzn.lims.core.web.BaseServiceImpl;
import com.patzn.lims.core.web.LoginHelper;
import com.patzn.lims.frame.entity.LmsAbilityMainPlan;
import com.patzn.lims.frame.entity.LmsAbilityMainPlanAttachment;
import com.patzn.lims.frame.entity.LmsAbilityMainPlanRecord;
import com.patzn.lims.frame.entity.LmsAbilitySubPlan;
import com.patzn.lims.frame.enums.PlanStatusEnum;
import com.patzn.lims.frame.mapper.LmsAbilityMainPlanMapper;
import com.patzn.lims.frame.service.ILmsAbilityMainPlanAttachmentService;
import com.patzn.lims.frame.service.ILmsAbilityMainPlanRecordService;
import com.patzn.lims.frame.service.ILmsAbilityMainPlanService;
import com.patzn.lims.frame.service.ILmsAbilitySubPlanService;
import com.patzn.lims.frame.vo.LmsAbilityMainPlanVO;
import com.patzn.lims.res.service.ILmsBaseDictService;
import com.patzn.lims.res.service.ILmsPropertyService;
import com.patzn.lims.workflow.FlowInfo;
import com.patzn.lims.workflow.FlowProcess;
import com.patzn.lims.workflow.FlowType;
import com.patzn.lims.workflow.FlowVariables;
import com.patzn.lims.workflow.service.IFlowProcessService;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 能力验证计划主表 服务实现类
 * </p>
 *
 * @author patzn
 * @since 2018-07-19
 */
@Service
public class LmsAbilityMainPlanServiceImpl extends BaseServiceImpl<LmsAbilityMainPlanMapper, LmsAbilityMainPlan> implements ILmsAbilityMainPlanService {

    @Autowired
    private ILmsPropertyService lmsPropertyService;
    @Autowired
    private ILmsAbilityMainPlanRecordService lmsAbilityMainPlanRecordService;
    @Autowired
    private IFlowProcessService flowProcessClient;
    @Autowired
    private ILmsAbilitySubPlanService lmsAbilitySubPlanService;
//    @Autowired
//    private ILmsExportService lmsExportService;
    @Autowired
    private ILmsBaseDictService lmsBaseDictService;
    @Autowired
    private ILmsAbilityMainPlanAttachmentService lmsAbilityMainPlanAttachmentService;
    @Autowired
    private OssClient ossClient;
    @Override
    public Page<LmsAbilityMainPlan> page(Page<LmsAbilityMainPlan> page, LmsAbilityMainPlan lmsAbilityMainPlan) {
        QueryWrapper wrapper = Wrappers.query(lmsAbilityMainPlan);
        return page(page, wrapper);
    }


    @Override
    public List<LmsAbilityMainPlan> list(LmsAbilityMainPlan lmsAbilityMainPlan) {
        return list(Wrappers.query(lmsAbilityMainPlan));
    }

    @Override
    public Page<LmsAbilityMainPlan> pagePlan(Page<LmsAbilityMainPlan> page, LmsAbilityMainPlan lmsAbilityMainPlan, Date startDate, Date endDate) {
        return page.setRecords(baseMapper.selectPagePlan(page, lmsAbilityMainPlan, startDate, endDate));
    }


    @Override
    public boolean copy(LmsAbilityMainPlan lmsAbilityMainPlan, Account account) {
        lmsAbilityMainPlan.setMaker(account.getUserName());
        lmsAbilityMainPlan.setMakeDate(new Date());
        lmsAbilityMainPlan.setMakerId(account.getUserId());
        lmsAbilityMainPlan.setStatus((Integer)PlanStatusEnum.DRAFT.getValue());
        lmsAbilityMainPlan.setProgress((Integer)PlanStatusEnum.DRAFT.getValue());
        lmsAbilityMainPlan.setId(IdWorker.getId());
        return super.save(lmsAbilityMainPlan);
    }

    @Override
    public boolean removeByIds(Long[] ids) {
        PtAssert.fail(ArrayUtils.isEmpty(ids), "请选择计划");
        int num = super.count(Wrappers.<LmsAbilityMainPlan>query().in("id", ids).eq("status", PlanStatusEnum.DRAFT));
        PtAssert.fail(ids.length != num, "只能删除草稿计划");
        return super.remove(Wrappers.<LmsAbilityMainPlan>query().in("id", ids)) &&
                lmsAbilitySubPlanService.remove(Wrappers.<LmsAbilitySubPlan>query().in("main_plan_id", ids));
    }

    @Override
    public boolean updatePlanById(LmsAbilityMainPlan lmsAbilityMainPlan) {
        PtAssert.fail(null == lmsAbilityMainPlan.getId(), "id不能为空");
        LmsAbilityMainPlan dbPlan = super.getById(lmsAbilityMainPlan.getId());
        String remark = lmsPropertyService.getCompareDifferent(lmsAbilityMainPlan, dbPlan, "能力验证计划对比", "能力验证计划修改内容：");
        if (StringUtils.isNotEmpty(remark)) {
            lmsAbilityMainPlanRecordService.saveAbilityMainPlanRecordByIds(dbPlan, PlanStatusEnum.valueOf(dbPlan.getStatus()), 2, new Long[]{dbPlan.getId()}, remark);
        }
        return super.updateById(lmsAbilityMainPlan);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public List<FlowProcess> submitCheckFlow(Long[] ids, Account account) {
        if (ArrayUtils.isEmpty(ids)) {
            return null;
        }
        List<LmsAbilityMainPlan> mainPlanList = super.list(Wrappers.<LmsAbilityMainPlan>query().in("id", ids));
        for (LmsAbilityMainPlan plan : mainPlanList) {
            PtAssert.fail((Integer)PlanStatusEnum.DRAFT.getValue() != plan.getStatus(), "只能提交草稿计划");
        }
        List<FlowInfo> flowInfoList = new ArrayList<>();
        List<LmsAbilityMainPlanRecord> recordList = new ArrayList<>();
        List<LmsAbilityMainPlan> updateList = mainPlanList.stream().filter(mainPlan -> null != mainPlan).map(mainPlan -> {
            flowInfoList.add(FlowInfo.convertFlowInfo(FlowType.ABILITY_PLAN_CHECK, account, mainPlan.getId(),
                    StringHandleUtils.getObjectValue(mainPlan.getName()).toString()));
            LmsAbilityMainPlan plan = new LmsAbilityMainPlan();
            plan.setId(mainPlan.getId());
            plan.setStatus((Integer)PlanStatusEnum.AUDIT.getValue());
            plan.setProgress((Integer)PlanStatusEnum.AUDIT.getValue());

            LmsAbilityMainPlanRecord record = new LmsAbilityMainPlanRecord();
            record.setMainPlanId(mainPlan.getId());
            record.setType(0);
            record.setOperator(account.getUserName());
            record.setLiable(account.getUserName());
            record.setOrigin(PlanStatusEnum.DRAFT.getDisplay());
            record.setTarget(PlanStatusEnum.AUDIT.getDisplay());
            record.setRemark("能力验证计划提交审批");
            recordList.add(record);
            return plan;
        }).collect(Collectors.toList());
        super.updateBatchById(updateList);
        if (CollectionUtils.isNotEmpty(recordList)) {
            lmsAbilityMainPlanRecordService.saveBatch(recordList);
        }
        return flowProcessClient.saveTask(flowInfoList,account);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean approveFlow(String taskId, String status, String reason) {
        FlowVariables flowVariables = new FlowVariables(taskId);
        FlowInfo flowInfo;
        Map<String, Object> map = new HashMap<>(2);
        Account account = LoginHelper.getAccount();
        PtAssert.fail(StringUtils.isBlank(status), "status不能为空");
        PtAssert.fail(!(status.equalsIgnoreCase("pass") || status.equalsIgnoreCase("back")), "通过状态为'pass'，驳回状态为'back'");

        LmsAbilityMainPlan plan = new LmsAbilityMainPlan();
        plan.setApproveOpinion(reason);
        plan.setApproveDate(new Date());
        plan.setApproverId(account.getUserId());
        plan.setApprover(account.getUserName());

        LmsAbilityMainPlanRecord record = new LmsAbilityMainPlanRecord();
        record.setOperator(account.getUserName());
        record.setLiable(account.getUserName());
        record.setOrigin(PlanStatusEnum.AUDIT.getDisplay());

        if ("pass".equals(status)) {
            //审批通过
            map.put("abilityPlanCheckPass", true);
            plan.setStatus((Integer) PlanStatusEnum.PASS.getValue());
            plan.setProgress((Integer)PlanStatusEnum.PASS.getValue());

            record.setType(0);
            record.setTarget(PlanStatusEnum.PASS.getDisplay());
            record.setRemark("能力验证计划审批通过：" + reason);
        } else if ("back".equals(status)) {
            //审批驳回
            map.put("abilityPlanCheckPass", false);
            plan.setStatus((Integer)PlanStatusEnum.DRAFT.getValue());
            plan.setProgress((Integer)PlanStatusEnum.BACK.getValue());

            record.setType(1);
            record.setTarget(PlanStatusEnum.BACK.getDisplay());
            record.setRemark("能力验证计划审批驳回：" + reason);
        }
        map.put(FlowInfo.APPLY_ID, account.getUserId());
        flowVariables.setVariables(map);
        flowInfo = flowProcessClient.complete(flowVariables);
        PtAssert.fail(null == flowInfo, "流程审批错误");
        plan.setId(flowInfo.getId());
        record.setMainPlanId(flowInfo.getId());
        lmsAbilityMainPlanRecordService.save(record);
        return updateById(plan);
    }

    @Override
    public void exportPlan(HttpServletResponse response, Long id) {
//        LmsAbilityMainPlan mainPlan = getById(id);
//        PtAssert.fail(null == mainPlan, "数据有误");
//        List<LmsAbilitySubPlan> subPlanList = lmsAbilitySubPlanService.list(Condition.create().eq("main_plan_id", id));
//        Map<String, String> replaceMap = new HashMap<>();
//        Map<String, Object> objectMap = lmsExportService.wordToMap("ability_plan.docx");
//        Iterator<XWPFTable> tableIterator = (Iterator<XWPFTable>) objectMap.get("table");
//        XWPFDocument doc = (XWPFDocument) objectMap.get("doc");
//        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
//        replaceMap.put("system_code", lmsBaseDictService.getCodeByKeyword("受控编号", "ability_plan_code"));
//        replaceMap.put("make_date", sdf.format(mainPlan.getMakeDate()).substring(0, 4));
//        replaceMap.put("maker", mainPlan.getMaker());
//        replaceMap.put("approver", null == mainPlan.getApprover() ? "" : mainPlan.getApprover());
//        PoiUtil2007ForReplace.replaceText(doc, replaceMap);
//        PoiUtil2007ForReplace.replaceHeadText(doc, replaceMap);
//        while (tableIterator.hasNext()) {
//            XWPFTable table = tableIterator.next();
//
//            int total = subPlanList.size();
//            if (total > 0) {
//                for (int i = 1; i <= total; i++) {
//                    //表格指定位置插入一行, index为新增行所在的行位置(不能大于表行数)
//                    PoiUtil2007.insertTableRowAtIndex(table, 1);
//                }
//            }
//
//            int rowsLength = table.getNumberOfRows();
//            for (int rowIndex = 1; rowIndex < rowsLength; rowIndex++) {
//                //从第2行开始
//                LmsAbilitySubPlan subPlan = subPlanList.get(rowIndex - 1);
//                StringHandleUtils.setText(table, rowIndex, 0, String.valueOf(rowIndex));
//                StringHandleUtils.setText(table, rowIndex, 1, subPlan.getSubfield());
//                StringHandleUtils.setText(table, rowIndex, 2, subPlan.getName());
//                StringHandleUtils.setText(table, rowIndex, 3, subPlan.getMethod());
//                StringHandleUtils.setText(table, rowIndex, 4, String.valueOf(subPlan.getFrequency()));
//                StringHandleUtils.setText(table, rowIndex, 5, subPlan.getTestRoom());
//            }
//        }
//        lmsExportService.downloadDoc(response, mainPlan.getName() + "能力验证计划.docx", doc);
    }

    @Override
    public LmsAbilityMainPlan getTempVO() {
        LmsAbilityMainPlan entity = new LmsAbilityMainPlan();
        entity.setTempStatus(0);
        LmsAbilityMainPlan abilityMainPlan = baseMapper.selectOne(Wrappers.query(entity));
        if (null != abilityMainPlan) {
            LmsAbilityMainPlanVO vo = abilityMainPlan.convert(LmsAbilityMainPlanVO.class);
            //获取附件
            LmsAbilityMainPlanAttachment attachment = new LmsAbilityMainPlanAttachment();
            attachment.setMainPlanId(abilityMainPlan.getId());
            List<LmsAbilityMainPlanAttachment> lmsFrameFileList = lmsAbilityMainPlanAttachmentService.list(attachment);
            lmsFrameFileList.forEach(e->{
                e.setObjectKey(ossClient.getUrl(e.getObjectKey()).toString());
            });
            vo.setFileList(lmsFrameFileList);
            return vo;
        }
        LmsAbilityMainPlan plan = new LmsAbilityMainPlan();
        plan.setTempStatus(0);
        plan.setStatus((Integer) PlanStatusEnum.DRAFT.getValue());
        plan.setProgress((Integer)PlanStatusEnum.DRAFT.getValue());
        plan.setName(" ");
        if (save(plan)) {
            LmsAbilityMainPlanVO vo = new LmsAbilityMainPlanVO();
            vo.setTempStatus(plan.getTempStatus());
            vo.setId(plan.getId());
            return vo;
        }
        return null;
    }

    @Override
    public LmsAbilityMainPlanAttachment uploadFile(MultipartFile file, LmsAbilityMainPlan lmsAbilityMainPlan) {
        Long companyId = LoginHelper.getAccount().getCompanyId();
        String folderPath = "base/abilityMainPlan/" + companyId + "/";
        return lmsAbilityMainPlanAttachmentService.saveAndUpload(file, "lims", folderPath, lmsAbilityMainPlan.getId(), 0);
    }

    @Override
    public Boolean deleteFile(Long id) {
        Long[] ids = new Long[]{id};
        return lmsAbilityMainPlanAttachmentService.deleteBatch(ids);
    }

    @Override
    public LmsAbilityMainPlanVO getVOById(Long id) {
        LmsAbilityMainPlanVO lmsAbilityMainPlanVO = new LmsAbilityMainPlanVO();
        LmsAbilityMainPlan lmsAbilityMainPlan = getById(id);
        if (null != lmsAbilityMainPlan) {
            BeanUtils.copyProperties(lmsAbilityMainPlan, lmsAbilityMainPlanVO);
            //获取附件
            LmsAbilityMainPlanAttachment attachment = new LmsAbilityMainPlanAttachment();
            attachment.setMainPlanId(lmsAbilityMainPlan.getId());
            List<LmsAbilityMainPlanAttachment> list = lmsAbilityMainPlanAttachmentService.list(attachment);
            list.forEach(e -> {
                e.setObjectKey(ossClient.getUrl(e.getObjectKey()).toString());
            });
            lmsAbilityMainPlanVO.setFileList(list);
        }
        return lmsAbilityMainPlanVO;
    }

    @Override
    public Boolean add(LmsAbilityMainPlan lmsAbilityMainPlan) {
        LmsAbilityMainPlan entity = new LmsAbilityMainPlan();
        entity.setTempStatus(0);
        LmsAbilityMainPlan temp = baseMapper.selectOne(Wrappers.query(entity));
        lmsAbilityMainPlan.setTempStatus(1);
        if (null != temp) {
            lmsAbilityMainPlan.setId(temp.getId());
            updateById(lmsAbilityMainPlan);
        } else {
            save(lmsAbilityMainPlan);
        }
        return true;
    }
    }


