package com.testor.module.train.project.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.testor.biz.file.model.dto.FileDTO;
import com.testor.biz.rule.service.SysRuleService;
import com.testor.biz.sys.org.model.domain.SysOrg;
import com.testor.biz.sys.org.service.SysOrgService;
import com.testor.common.constant.DefaultRule;
import com.testor.common.util.DateUtil;
import com.testor.common.util.PageUtil;
import com.testor.module.train.course.dao.TTrainSmallNodeDao;
import com.testor.module.train.course.model.domain.TTrainSection;
import com.testor.module.train.course.model.domain.TTrainSmallNode;
import com.testor.module.train.course.service.TTrainSectionService;
import com.testor.module.train.myManagement.model.domain.TTrainMyManagement;
import com.testor.module.train.myManagement.model.domain.TTrainMyManagementRead;
import com.testor.module.train.myManagement.service.TTrainMyManagementReadService;
import com.testor.module.train.project.model.domain.TTrainEvaluateManage;
import com.testor.module.train.project.model.domain.TTrainProject;
import com.testor.module.train.project.model.dto.TTrainEvaluateManageParam;
import com.testor.module.train.project.model.dto.TTrainProjectDelParam;
import com.testor.module.train.project.model.dto.TTrainProjectParam;
import com.testor.module.train.project.model.dto.TreeVO;
import com.testor.module.train.project.service.TTrainEvaluateManageService;
import com.testor.module.train.project.service.TTrainProjectService;
import com.tongtech.tfw.backend.common.biz.constants.BizConstants;
import com.tongtech.tfw.backend.common.biz.models.BaseResponse;
import com.tongtech.tfw.backend.common.biz.models.BaseResponseList;
import com.tongtech.tfw.backend.common.biz.models.BizGeneralResponse;
import com.tongtech.tfw.backend.common.context.ContextUtils;
import com.tongtech.tfw.backend.common.models.supers.SuperController;
import com.tongtech.tfw.backend.common.models.sys.UserInfo;
import com.tongtech.tfw.backend.core.helper.ObjectHelper;
import com.tongtech.tfw.backend.core.helper.StringHelper;
import com.tongtech.tfw.backend.core.helper.TypeHelper;
import com.tongtech.tfw.backend.core.helper.bean.BeanHelper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 教育培训计划—安全培训教育Controller
 *
 * @author testor-framework
 * @date 2022-07-28 15:15:20
 */
@RestController
@RequestMapping("/project")
@Api(value = "TTrainProject", tags = "安全培训教育——教育培训计划")
@Slf4j
public class TTrainProjectController extends SuperController {
    @Autowired
    private TTrainProjectService tTrainProjectService;
    @Autowired
    private SysOrgService sysOrgService;
    @Autowired
    private SysRuleService sysRuleService;
    @Autowired
    private TTrainEvaluateManageService tTrainEvaluateManageService;
    @Autowired
    private TTrainProjectScan tTrainProjectScan;
    @Autowired
    private TTrainSectionService tTrainSectionService;
    @Autowired
    private TTrainMyManagementReadService tTrainMyManagementReadService;
    @Autowired
    private TTrainSmallNodeDao tTrainSmallNodeDao;

    @ApiOperation(value = "评价管理端 新增或者修改 ", notes = "Add TTrainEvaluateManage")
    @PostMapping(value = "/addEvaluate")
    public BaseResponse<TTrainEvaluateManage> addEvaluate(@RequestBody TTrainEvaluateManageParam addRequest) {
        return tTrainEvaluateManageService.addEvaluate(addRequest);
    }

    @ApiOperation(value = "获取管理端详情", notes = "")
    @PostMapping(value = "/getEvaluate")
    public BaseResponse<TTrainEvaluateManageParam> getEvaluate(TTrainEvaluateManage addRequest) {
        return tTrainEvaluateManageService.getEvaluate(addRequest);
    }

    //    @ApiOperation(value = "根据当前登录用户获取子组织机构树及子部门信息 教育培训计划—安全培训教育", notes = "Add TTrainProject")
//    @GetMapping(value = "/getOrgAndTree")
    public BaseResponse<TreeVO> getOrgAndTree(String orgId) {
        BaseResponse<TreeVO> baseResponse = new BaseResponse<>();
        List<SysOrg> list = sysOrgService.list(new QueryWrapper<SysOrg>()
                .eq(SysOrg.ORG_ID, orgId)
                .ne(SysOrg.STATUS, BizConstants.STATUS_DELETE)
        );
        TreeVO treeVO = null;
        for (SysOrg sysOrg : list) {
            treeVO = BeanHelper.beanToBean(sysOrg, TreeVO.class);
            List<SysOrg> list1 = sysOrgService.list(new QueryWrapper<SysOrg>().eq(SysOrg.PARENT_ID, treeVO.getOrgId())
                    .ne(SysOrg.STATUS, BizConstants.STATUS_DELETE));
            List<TreeVO> treeVOS = new ArrayList<>();
            for (SysOrg org : list1) {
                TreeVO treeVO1 = BeanHelper.beanToBean(org, TreeVO.class);
                List<SysOrg> list2 = sysOrgService.list(new QueryWrapper<SysOrg>().eq(SysOrg.PARENT_ID, treeVO1.getOrgId())
                        .ne(SysOrg.STATUS, BizConstants.STATUS_DELETE));
                List<TreeVO> treeVOS1 = new ArrayList<>();
                for (SysOrg sysOrg1 : list2) {
                    TreeVO treeVO2 = BeanHelper.beanToBean(sysOrg1, TreeVO.class);
                    treeVOS1.add(treeVO2);
                }
                treeVO1.setChildren(treeVOS1);
                treeVOS.add(treeVO1);
            }
            treeVO.setChildren(treeVOS);
        }
        baseResponse.setData(treeVO);
        return baseResponse;
    }


    /* Generated Method*/
    @ApiOperation(value = "新增 编辑 教育培训计划—安全培训教育", notes = "Add TTrainProject")
    @PostMapping(value = "/add")
    public BaseResponse<TTrainProject> addEntity(@RequestBody TTrainProjectParam addRequest) throws Exception {
        return tTrainProjectService.addEntity(addRequest);
    }

    @ApiOperation(value = "获取 教育培训计划—安全培训教育 ", notes = "Get TTrainProject By Id")
    @GetMapping(value = "/get")
    public BaseResponse<TTrainProjectParam> getById(String id) throws Exception {
        return tTrainProjectService.getByIds(id);
    }

    //    @ApiOperation(value = "修改 教育培训计划—安全培训教育 ", notes = "Update TTrainProject By Id")
//    @PutMapping(value = "/update")
    public BaseResponse<BizGeneralResponse> updateEntity(@RequestBody TTrainProject updateRequest) throws Exception {
        return tTrainProjectService.updateEntity(updateRequest);
    }

    @ApiOperation(value = "删除 教育培训计划—安全培训教育 ", notes = "delete TTrainProject By Id")
    @PutMapping(value = "/delete")
    public BaseResponse<BizGeneralResponse> deleteEntity(@RequestBody TTrainProjectDelParam deleteRequest) throws Exception {
        return tTrainProjectService.deleteEntity(deleteRequest);
    }

    //    @ApiOperation(value = "批量删除教育培训计划—安全培训教育", notes = "delete TTrainProject by batch Id")
//    @PutMapping(value = "/batch_delete")
    public BaseResponse<BizGeneralResponse> deleteEntityBatch(
            @RequestBody TTrainProjectDelParam deleteRequest) {
        BaseResponse<BizGeneralResponse> baseResponse = new BaseResponse<>();
        if (ObjectHelper.isNotEmpty(deleteRequest) && (!deleteRequest.getIds().isEmpty())) {
            /* 批量删除 */
            List<TTrainProject> tTrainProjectList = new ArrayList<>();
            for (String id : deleteRequest.getIds()) {
                TTrainProject data = new TTrainProject();
                data.setId(id);
                data.setStatus(BizConstants.STATUS_DELETE);
                tTrainProjectList.add(data);
            }
            boolean result = tTrainProjectService.updateBatchById(tTrainProjectList);
            baseResponse.setData(
                    BizGeneralResponse.builder().result(TypeHelper.castToString(result)).build());
        }
        return baseResponse;
    }

    @ApiOperation(value = "获取 教育培训计划—安全培训教育 分页列表", notes = "List TTrainProject with page")
    @PostMapping(value = "/list")
    public BaseResponse<BaseResponseList<TTrainProjectParam>> listEntity(@RequestBody TTrainProjectParam param) throws Exception {
        BaseResponse<BaseResponseList<TTrainProjectParam>> baseResponse = new BaseResponse<>();
        UserInfo loginUser = ContextUtils.getLoginUser();
        SysOrg sysOrg = sysOrgService.getById(loginUser.getOrgId());
        String parentIds = sysOrg.getParentIds();
        String orgId = sysOrg.getOrgId();
        if (ObjectHelper.isNotEmpty(param.getVisitStartTime())) {
            //String startTime = param.getVisitStartTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            String startTime = DateUtil.convertDateToStr(param.getVisitStartTime(), "yyyy-MM-dd HH:mm:ss");

            param.setStartTime(startTime);
        }
        if (ObjectHelper.isNotEmpty(param.getVisitEndTime())) {
           // String endTime = param.getVisitEndTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            String endTime = DateUtil.convertDateToStr(param.getVisitEndTime(), "yyyy-MM-dd HH:mm:ss");
            param.setEndTime(endTime);
        }
        IPage<TTrainProjectParam> affiliation = tTrainProjectService.getAffiliation(param, parentIds, orgId);
        List<TTrainProjectParam> records = affiliation.getRecords();
        List<TTrainProjectParam> tTrainProjectParams2 = new ArrayList<>();
        if (records.size() > 0) {
            // 按计划名称进行分组
            Map<String, List<TTrainProjectParam>> collect = records.stream().collect(Collectors.groupingBy(TTrainProjectParam::getId));
            for (String s : collect.keySet()) {
                // 获取每条计划关联的人员
                List<TTrainProjectParam> tTrainProjectParams = tTrainProjectService.getProjectPerson(s);

                // 存储完成率
                List<String> saveFinish = saveFinish(tTrainProjectParams);
                // 拼接后每一条计划关联的人
                List<TTrainProjectParam> tTrainProjectParams1 = new ArrayList<>();
                for (TTrainProjectParam record : tTrainProjectParams) {
                    String affiliation1 = "";
                    if ("1".equals(record.getPersonAffiliation())) {
                        affiliation1 = "内部单位";
                    } else if ("2".equals(record.getPersonAffiliation())) {
                        affiliation1 = "相关方";
                    }
                    TTrainProjectParam tTrainProjectParam = BeanHelper.beanToBean(record, TTrainProjectParam.class);
                    String company = affiliation1 + "-" + record.getCompany();
                    // 存储计划完成率
                    record.setPercentage(saveFinish.get(2));
                    record.setFinishNumber(saveFinish.get(1));
                    record.setShouldLearnNumber(saveFinish.get(0));
                    tTrainProjectParam.setPersonAffiliation(company);
                    tTrainProjectParams1.add(tTrainProjectParam);
                }
                if (tTrainProjectParams1.size() == 0) {
                    continue;
                }
                // 获取一个计划
                TTrainProjectParam tTrainProjectParam = tTrainProjectParams1.get(0);
                if ("1".equals(tTrainProjectParam.getVisitWay()) && StringHelper.isEmpty(tTrainProjectParam.getQrCode())) {
                    String str = "扫码签到";
                    BaseResponse<FileDTO> fileDTOBaseResponse = tTrainProjectScan.scanProject(tTrainProjectParam.getId(), str);
                    String filePath = fileDTOBaseResponse.getData().getFilePath();
                    tTrainProjectService.update(new UpdateWrapper<TTrainProject>()
                            .eq(TTrainProject.ID, tTrainProjectParam.getId())
                            .set(TTrainProject.QR_CODE, filePath)
                    );
                }
                String personAffiliation = "";
                for (TTrainProjectParam trainProjectParam : tTrainProjectParams1) {
                    personAffiliation += trainProjectParam.getPersonAffiliation() + " ";
                }
                tTrainProjectParam.setPersonAffiliation(personAffiliation);
                tTrainProjectParams2.add(tTrainProjectParam);
            }
            tTrainProjectParams2 = tTrainProjectParams2.stream().sorted(Comparator.comparing(TTrainProjectParam::getCreateDate).reversed()).collect(Collectors.toList());
        }
        //ToDo 组装参数：完成率和完成人数
/*        if (!CollectionUtils.isEmpty(tTrainProjectParams2) && tTrainProjectParams2.size() > 0) {
            tTrainProjectParams2.forEach(t -> {
                try {
                    BaseResponse<TTrainProjectParam> byIds = tTrainProjectService.getByIds(t.getId());
                    TTrainProjectParam data = byIds.getData();
                    t.setFinishNumber(data.getFinishNumber());
                    t.setPercentage(data.getPercentage());
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });

        }*/
        List list = PageUtil.startPage(tTrainProjectParams2, Integer.valueOf(param.getPage()), Integer.valueOf(param.getLimit()));
        BaseResponseList<TTrainProjectParam> baseResponseList = new BaseResponseList<>();
        baseResponseList.setData(list);
        baseResponseList.setTotal(tTrainProjectParams2.size());
        baseResponse.setData(baseResponseList);
        return baseResponse;
    }

    /**
     * 存储完成率
     *
     * @param tTrainProjectParams
     */
    private List<String> saveFinish(List<TTrainProjectParam> tTrainProjectParams) {
        // 全部人数
        int size = tTrainProjectParams.size();
        // 完成人数
        int count = 0;
        // 计划id
        String id = null;

        for (TTrainProjectParam tTrainProjectParam : tTrainProjectParams) {
            String courseId = tTrainProjectParam.getCourseId();
            String personId = tTrainProjectParam.getPersonId();
            String myManagementId = tTrainProjectParam.getMyManagementId();

            TTrainMyManagement record = new TTrainMyManagement();
            record.setId(myManagementId);
            record.setVisitStartTime(tTrainProjectParam.getVisitStartTime());
            record.setPersonId(personId);
            record.setVisitEndTime(tTrainProjectParam.getVisitEndTime());
            record.setTabStatus("1");
            tTrainProjectService.updateStatus(record, courseId);
            if ("3".equals(record.getCurrentStatus())) {
                count++;
            }
        }
        // 完成率
        String percentage = getRatio(count, size);
        tTrainProjectService.update(new UpdateWrapper<TTrainProject>()
                .eq(TTrainProject.ID, id)
                .set(TTrainProject.SHOULD_LEARN_NUMBER, size)
                .set(TTrainProject.FINISH_NUMBER, count)
                .set(TTrainProject.PERCENTAGE, percentage)
        );
        List<String> list = new ArrayList<>();
        list.add(Integer.toString(size));
        list.add(Integer.toString(count));
        list.add(percentage);
        return list;


    }

    /**
     * 计算完成率
     *
     * @param dividend 被除数
     * @param divisor  除数
     * @return
     */
    public static String getRatio(Integer dividend, Integer divisor) {
        int percentage = (int) Math.round((double) dividend / divisor * 100);
        String chapterProgress = percentage + "%";
        return chapterProgress;
    }


    //    @ApiOperation(value = "获取 教育培训计划—安全培训教育 列表", notes = "List TTrainProject all")
//    @GetMapping(value = "/datas")
    public BaseResponse<BaseResponseList<TTrainProject>> listAllEntity(TTrainProjectParam param) {
        BaseResponse<BaseResponseList<TTrainProject>> baseResponse = new BaseResponse<>();
        // TODO 根据需求修改查询条件及查询参数
        QueryWrapper<TTrainProject> queryWrapper = this.createQuery(param);
        List<TTrainProject> resultList = tTrainProjectService.list(queryWrapper);
        BaseResponseList<TTrainProject> baseResponseList = new BaseResponseList<>();
        baseResponseList.setData(resultList);
        baseResponseList.setTotal(resultList.size());
        baseResponse.setData(baseResponseList);
        return baseResponse;
    }

    /* Private Methods */

    /**
     * 列表查询条件及查询参数
     */
    private QueryWrapper<TTrainProject> createQuery(TTrainProjectParam queryParam) {
        QueryWrapper<TTrainProject> queryWrapper = new QueryWrapper<>();
        String rule = sysRuleService.dataRuleScope(DefaultRule.DEPT_ALL.name());
        if (StringUtils.isNotEmpty(rule)) {
            queryWrapper.apply(rule);
        }
        if (StringHelper.isNotEmpty(queryParam.getParentId())) {
            queryWrapper.eq(TTrainProject.PARENT_ID, queryParam.getParentId());
        }
        if (StringHelper.isNotEmpty(queryParam.getProjectName())) {
            queryWrapper.like(TTrainProject.PROJECT_NAME, queryParam.getProjectName());
        }
        if (ObjectHelper.isNotEmpty(queryParam.getVisitStartTime())) {
            queryWrapper.eq(TTrainProject.VISIT_START_TIME, queryParam.getVisitStartTime());
        }
        if (ObjectHelper.isNotEmpty(queryParam.getVisitEndTime())) {
            queryWrapper.eq(TTrainProject.VISIT_END_TIME, queryParam.getVisitEndTime());
        }
        if (StringHelper.isNotEmpty(queryParam.getVisitWay())) {
            queryWrapper.eq(TTrainProject.VISIT_WAY, queryParam.getVisitWay());
        }
        if (StringHelper.isNotEmpty(queryParam.getVisitType())) {
            queryWrapper.eq(TTrainProject.VISIT_TYPE, queryParam.getVisitType());
        }
        if (StringHelper.isNotEmpty(queryParam.getCourseId())) {
            queryWrapper.eq(TTrainProject.COURSE_ID, queryParam.getCourseId());
        }
        if (StringHelper.isNotEmpty(queryParam.getIsAddExam())) {
            queryWrapper.eq(TTrainProject.IS_ADD_EXAM, queryParam.getIsAddExam());
        }
        if (StringHelper.isNotEmpty(queryParam.getTestPaperId())) {
            queryWrapper.eq(TTrainProject.TEST_PAPER_ID, queryParam.getTestPaperId());
        }
        if (StringHelper.isNotEmpty(queryParam.getExamType())) {
            queryWrapper.eq(TTrainProject.EXAM_TYPE, queryParam.getExamType());
        }
        if (StringHelper.isNotEmpty(queryParam.getExamName())) {
            queryWrapper.like(TTrainProject.EXAM_NAME, queryParam.getExamName());
        }
        if (ObjectHelper.isNotEmpty(queryParam.getExamStartTime())) {
            queryWrapper.eq(TTrainProject.EXAM_START_TIME, queryParam.getExamStartTime());
        }
        if (ObjectHelper.isNotEmpty(queryParam.getExamEndTime())) {
            queryWrapper.eq(TTrainProject.EXAM_END_TIME, queryParam.getExamEndTime());
        }
        if (StringHelper.isNotEmpty(queryParam.getExamSite())) {
            queryWrapper.eq(TTrainProject.EXAM_SITE, queryParam.getExamSite());
        }
        if (StringHelper.isNotEmpty(queryParam.getExamDuration())) {
            queryWrapper.eq(TTrainProject.EXAM_DURATION, queryParam.getExamDuration());
        }
        if (StringHelper.isNotEmpty(queryParam.getShouldLearnNumber())) {
            queryWrapper.eq(TTrainProject.SHOULD_LEARN_NUMBER, queryParam.getShouldLearnNumber());
        }
        if (StringHelper.isNotEmpty(queryParam.getFinishNumber())) {
            queryWrapper.eq(TTrainProject.FINISH_NUMBER, queryParam.getFinishNumber());
        }
        if (StringHelper.isNotEmpty(queryParam.getPercentage())) {
            queryWrapper.eq(TTrainProject.PERCENTAGE, queryParam.getPercentage());
        }
        if (StringHelper.isNotEmpty(queryParam.getTenantId())) {
            queryWrapper.eq(TTrainProject.TENANT_ID, queryParam.getTenantId());
        }
        if (StringHelper.isNotEmpty(queryParam.getProcessId())) {
            queryWrapper.eq(TTrainProject.PROCESS_ID, queryParam.getProcessId());
        }
        if (StringHelper.isNotEmpty(queryParam.getProcessStatus())) {
            queryWrapper.eq(TTrainProject.PROCESS_STATUS, queryParam.getProcessStatus());
        }
        if (StringHelper.isNotEmpty(queryParam.getStatus())) {
            queryWrapper.eq(TTrainProject.STATUS, queryParam.getStatus());
        } else {
            queryWrapper.ne(TTrainProject.STATUS, BizConstants.STATUS_DELETE);
        }
        if (StringHelper.isNotEmpty(queryParam.getOrderBy())) {
            if (StringHelper.isNotEmpty(queryParam.getOrderType())
                    && BizConstants.ASC.equals(queryParam.getOrderType())) {
                queryWrapper.orderByAsc(queryParam.getOrderBy());
            } else {
                queryWrapper.orderByDesc(queryParam.getOrderBy());
            }
        } else {
            queryWrapper.orderByDesc(TTrainProject.UPDATE_DATE);
        }
        return queryWrapper;
    }


    public static void main(String[] args) {
        int percentage = (int) Math.round((double) 2 / 3 * 100);
        System.out.println(percentage);
        BigDecimal divide = new BigDecimal(2).divide(new BigDecimal(3), 6, RoundingMode.HALF_UP)
                .multiply(BigDecimal.valueOf(100)).setScale(0, RoundingMode.HALF_UP);
        System.out.println(divide);

    }
}
