package com.mortals.xhx.busiz.h5.web;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.mortals.framework.common.Rest;
import com.mortals.framework.exception.AppException;
import com.mortals.framework.model.Context;
import com.mortals.framework.model.PageInfo;
import com.mortals.xhx.busiz.h5.req.InspectSaveReq;
import com.mortals.xhx.busiz.h5.req.PerformReq;
import com.mortals.xhx.busiz.h5.rsp.InspectStatInfo;
import com.mortals.xhx.busiz.h5.rsp.PerformDetailInfo;
import com.mortals.xhx.busiz.h5.rsp.PerformInfo;
import com.mortals.xhx.common.code.PerformTypeEnum;
import com.mortals.xhx.common.code.SubMethodEnum;
import com.mortals.xhx.common.utils.BeanUtil;
import com.mortals.xhx.module.check.model.*;
import com.mortals.xhx.module.check.model.vo.CheckAllRecordVo;
import com.mortals.xhx.module.check.service.*;
import com.mortals.xhx.module.perform.model.*;
import com.mortals.xhx.module.perform.service.*;
import com.mortals.xhx.module.staff.model.StaffEntity;
import com.mortals.xhx.module.staff.service.StaffService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.mortals.framework.ap.SysConstains.*;
import static com.mortals.xhx.common.key.ErrorCode.ERROR_TOKEN_EXPIRED;
import static com.mortals.xhx.common.key.ErrorCode.ERROR_TOKEN_EXPIRED_CONTENT;

/**
 * h5 巡查
 *
 * @author: zxfei
 * @date: 2023/7/7 15:08
 */
@RestController
@Slf4j
@RequestMapping("/api/v1/inspect")
public class InspectApiController extends AbstractBaseController<PerformReq> {

    @Autowired
    private PerformAttendRecordService attendRecordService;
    @Autowired
    private PerformReviewRecordService reviewRecordService;
    @Autowired
    private PerformComplainRecordService complainRecordService;
    @Autowired
    private PerformGoworkRecordService performGoworkRecordService;
    @Autowired
    private PerformEffectRecordService effectRecordService;
    @Autowired
    private PerformOtherRecordService otherRecordService;
    @Autowired
    private PerformRulesService rulesService;
    @Autowired
    private StaffService staffService;

    @Autowired
    private CheckAllRecordService checkAllRecordService;


    @Autowired
    private CheckAttendRecordService checkAttendRecordService;
    @Autowired
    private CheckReviewRecordService checkReviewRecordService;
    @Autowired
    private CheckComplainRecordService checkComplainRecordService;
    @Autowired
    private CheckEffectRecordService checkEffectRecordService;
    @Autowired
    private CheckGoworkRecordService checkGoworkRecordService;
    @Autowired
    private CheckOtherRecordService checkOtherRecordService;



    /**
     * 个人巡查效统计
     */
    @PostMapping(value = "stat")
    public Rest<InspectStatInfo> inspectStat() {
        String busiDesc = "H5 个人巡查统计";
        Rest<InspectStatInfo> rest = Rest.ok(busiDesc + " 【成功】");
        Context context = this.getContext();

        if (ObjectUtils.isEmpty(context) || ObjectUtils.isEmpty(context.getUser())) {
            throw new AppException(ERROR_TOKEN_EXPIRED, ERROR_TOKEN_EXPIRED_CONTENT);
        }
        log.info("【{}】【请求体】--> 用户:{}", busiDesc, context.getUser().getRealName());
        try {
            //todo
            InspectStatInfo performStatInfo = new InspectStatInfo();
            performStatInfo.setTotalTimes(12);
            performStatInfo.setTodayTimes(4);
            rest.setData(performStatInfo);
            recordSysLog(request, busiDesc + " 【成功】");
        } catch (Exception e) {
            log.error(busiDesc, e);
            rest = Rest.fail(super.convertException(e));
        }
        return rest;
    }


    /**
     * 个人巡查列表
     */
    @PostMapping(value = "list")
    public Rest<Object> performList(@RequestBody PerformReq performReq) {
        String busiDesc = "个人巡查列表";
        log.info("【{}】【请求体】--> {}", busiDesc, JSONObject.toJSONString(performReq));
        Rest<Object> rest = Rest.ok();
        Map<String, Object> model = new HashMap<>();
        Context context = this.getContext();

        if (ObjectUtils.isEmpty(context) || ObjectUtils.isEmpty(context.getUser())) {
            throw new AppException(ERROR_TOKEN_EXPIRED, ERROR_TOKEN_EXPIRED_CONTENT);
        }
        try {
            if (ObjectUtils.isEmpty(performReq.getPerformStartDate())) {
                //未设置时间的情况，默认为当月
                performReq.setPerformStartDate(DateUtil.beginOfMonth(new Date()).toDateStr());
                performReq.setPerformEndDate(DateUtil.today());
            } else {
                performReq.setPerformStartDate(DateUtil.beginOfMonth(DateUtil.parse(performReq.getPerformStartDate()).toJdkDate()).toDateStr());
                performReq.setPerformEndDate(DateUtil.endOfMonth(DateUtil.parse(performReq.getPerformStartDate()).toJdkDate()).toDateStr());
            }
            CheckAllRecordQuery query = new CheckAllRecordQuery();
            query.setCheckTimeStart(performReq.getPerformStartDate());
            query.setCheckTimeEnd(performReq.getPerformEndDate());
            query.setCreateUserId(context.getUser().getCustomerId());
            if (PerformTypeEnum.全部.getValue().equals(performReq.getPerformType())) {
                List<CheckAllRecordVo> allCheckRecord = checkAllRecordService.getAllCheckRecord(query);
                List<PerformInfo> collect = allCheckRecord.stream().map(item -> {
                    PerformInfo performInfo = new PerformInfo();
                    BeanUtils.copyProperties(item, performInfo, BeanUtil.getNullPropertyNames(item));
                    return performInfo;
                }).collect(Collectors.toList());
                model.put(KEY_RESULT_DATA, collect);
                PageInfo pageAllInfo = new PageInfo();
                pageAllInfo.setTotalResult(collect.size());
                pageAllInfo.setCurrPage(1);
                pageAllInfo.setPrePageResult(-1);
                model.put(PAGEINFO_KEY, pageAllInfo);
                parsePageInfo(model, pageAllInfo);

            }
            if(!ObjectUtils.isEmpty(performReq.getProcessStatus())){
                query.setCheckStatus(performReq.getProcessStatus());
                List<CheckAllRecordVo> allCheckRecord = checkAllRecordService.getAllCheckRecord(query);
                List<PerformInfo> collect = allCheckRecord.stream().map(item -> {
                    PerformInfo performInfo = new PerformInfo();
                    BeanUtils.copyProperties(item, performInfo, BeanUtil.getNullPropertyNames(item));
                    return performInfo;
                }).collect(Collectors.toList());
                model.put(KEY_RESULT_DATA, collect);
                PageInfo pageAllInfo = new PageInfo();
                pageAllInfo.setTotalResult(collect.size());
                pageAllInfo.setCurrPage(1);
                pageAllInfo.setPrePageResult(-1);
                model.put(PAGEINFO_KEY, pageAllInfo);
                parsePageInfo(model, pageAllInfo);
            }
            if(!ObjectUtils.isEmpty(performReq.getScoreType())){
                query.setSubAddType(performReq.getScoreType());
                List<CheckAllRecordVo> allCheckRecord = checkAllRecordService.getAllCheckRecord(query);
                List<PerformInfo> collect = allCheckRecord.stream().map(item -> {
                    PerformInfo performInfo = new PerformInfo();
                    BeanUtils.copyProperties(item, performInfo, BeanUtil.getNullPropertyNames(item));
                    return performInfo;
                }).collect(Collectors.toList());
                model.put(KEY_RESULT_DATA, collect);
                PageInfo pageAllInfo = new PageInfo();
                pageAllInfo.setTotalResult(collect.size());
                pageAllInfo.setCurrPage(1);
                pageAllInfo.setPrePageResult(-1);
                model.put(PAGEINFO_KEY, pageAllInfo);
                parsePageInfo(model, pageAllInfo);
            }


//            model.put(KEY_RESULT_DATA, result.getList());
//            model.put(PAGEINFO_KEY, result.getPageInfo());
//            parsePageInfo(model, result.getPageInfo());

            rest.setData(model);
            recordSysLog(request, busiDesc + " 【成功】");
        } catch (Exception e) {
            log.error(busiDesc, e);
            rest = Rest.fail(super.convertException(e));
        }
        return rest;
    }


    /**
     * 巡查新增
     */
    @PostMapping(value = "save")
    public Rest<PerformAttendAppealEntity> appealSave(@RequestBody InspectSaveReq req) {
        String busiDesc = "个人巡查记录新增";
        log.info("【{}】【请求体】--> {}", busiDesc, JSONObject.toJSONString(req));
        Rest<PerformAttendAppealEntity> rest = Rest.ok(busiDesc + " 【成功】");
        Context context = this.getContext();
       // req.setStaffId(context.getUser().getCustomerId());
        try {
            //根据状态 查询 当前是否已经存在正在进行的申诉
            if (ObjectUtils.isEmpty(context) || ObjectUtils.isEmpty(context.getUser())) {
                throw new AppException(ERROR_TOKEN_EXPIRED, ERROR_TOKEN_EXPIRED_CONTENT);
            }
            if (ObjectUtils.isEmpty(req.getPerformType())) throw new AppException("绩效类型不能为空！");

            if (PerformTypeEnum.考勤绩效.getValue().equals(req.getPerformType())) {
                boolean bool = attend(req,context);
                if (bool) throw new AppException(busiDesc + "失败！");
            } else if (PerformTypeEnum.评价差评绩效.getValue().equals(req.getPerformType())) {
                boolean bool = review(req,context);
                if (bool) throw new AppException(busiDesc + "失败！");
            } else if (PerformTypeEnum.评价投诉绩效.getValue().equals(req.getPerformType())) {
                boolean bool = complain(req,context);
                if (bool) throw new AppException(busiDesc + "失败！");
            } else if (PerformTypeEnum.办件绩效.getValue().equals(req.getPerformType())) {
                boolean bool = gowork(req,context);
                if (bool) throw new AppException(busiDesc + "失败！");
            } else if (PerformTypeEnum.效能绩效.getValue().equals(req.getPerformType())) {
                boolean bool = effect(req,context);
                if (bool) throw new AppException(busiDesc + "失败！");
            } else if (PerformTypeEnum.其它绩效.getValue().equals(req.getPerformType())) {
                boolean bool = other(req,context);
                if (bool) throw new AppException(busiDesc + "失败！");
            } else {
                throw new AppException("不支持当前绩效类型");
            }
            recordSysLog(request, busiDesc + " 【成功】");
        } catch (Exception e) {
            log.error(busiDesc, e);
            rest = Rest.fail(super.convertException(e));
        }
        log.info("【{}】【响应体】--> {}", busiDesc, JSONObject.toJSONString(req));
        return rest;
    }





    private boolean attend(InspectSaveReq req,Context context) throws AppException {
        //考勤保存
        PerformRulesEntity rule = getRule(req.getRuleId().toString());
        StaffEntity staffEntity = getStaff(req.getStaffId().toString());

        PerformAttendRecordEntity recordEntity = new PerformAttendRecordEntity();
        recordEntity.initAttrValue();
        BeanUtils.copyProperties(req, recordEntity);
        recordEntity.setStaffId(staffEntity.getId());
        recordEntity.setStaffName(staffEntity.getName());

        recordEntity.setDeptId(staffEntity.getDeptId());
        recordEntity.setDeptName(staffEntity.getDeptName());

        recordEntity.setSubAddType(rule.getSubAddType());
        recordEntity.setScore(rule.getScore());
        recordEntity.setRuleId(rule.getId());
        recordEntity.setRuleNme(rule.getName());
        recordEntity.setCategoryId(rule.getCategoryId());
        recordEntity.setCategoryName(rule.getCategoryName());
        recordEntity.setSubMethod(SubMethodEnum.大厅巡查.getValue());

        recordEntity.setCreateUserId(context.getUser().getCustomerId());
        recordEntity.setCreateTime(new Date());
        PerformAttendRecordEntity save = attendRecordService.save(recordEntity);

        return save.newEntity();

    }


    private boolean review(InspectSaveReq req,Context context) throws AppException {
        //评价保存
        StaffEntity staffEntity = getStaff(req.getStaffId().toString());
        PerformRulesEntity rule = getRule(req.getRuleId().toString());

        PerformReviewRecordEntity recordEntity = new PerformReviewRecordEntity();

        recordEntity.initAttrValue();
        BeanUtils.copyProperties(req, recordEntity);
      //  recordEntity.setStaffId(staffEntity.getId());
        recordEntity.setStaffName(staffEntity.getName());

        recordEntity.setDeptId(staffEntity.getDeptId());
        recordEntity.setDeptName(staffEntity.getDeptName());
        recordEntity.setSubAddType(rule.getSubAddType());
        recordEntity.setScore(rule.getScore());
        recordEntity.setRuleId(rule.getId());
        recordEntity.setRuleName(rule.getName());
        recordEntity.setCategoryId(rule.getCategoryId());
        recordEntity.setCategoryName(rule.getCategoryName());
        recordEntity.setSubMethod(SubMethodEnum.大厅巡查.getValue());
        recordEntity.setCreateUserId(context.getUser().getCustomerId());
        recordEntity.setCreateTime(new Date());
        PerformReviewRecordEntity save = reviewRecordService.save(recordEntity);
        return save.newEntity();

    }

    private boolean complain(InspectSaveReq req,Context context) throws AppException {
        //投诉保存
        StaffEntity staffEntity = getStaff(req.getStaffId().toString());
        PerformRulesEntity rule = getRule(req.getRuleId().toString());

        PerformComplainRecordEntity recordEntity = new PerformComplainRecordEntity();

        recordEntity.initAttrValue();
        BeanUtils.copyProperties(req, recordEntity);
       // recordEntity.setStaffId(staffEntity.getId());
        recordEntity.setStaffName(staffEntity.getName());

        recordEntity.setDeptId(staffEntity.getDeptId());
        recordEntity.setDeptName(staffEntity.getDeptName());

        recordEntity.setSubAddType(rule.getSubAddType());
        recordEntity.setScore(rule.getScore());
        recordEntity.setRuleId(rule.getId());
        recordEntity.setRuleName(rule.getName());
        recordEntity.setCategoryId(rule.getCategoryId());
        recordEntity.setCategoryName(rule.getCategoryName());
        recordEntity.setSubMethod(SubMethodEnum.大厅巡查.getValue());
        recordEntity.setDeductTime(new Date());

        recordEntity.setCreateUserId(context.getUser().getCustomerId());
        recordEntity.setCreateTime(new Date());
        PerformComplainRecordEntity save = complainRecordService.save(recordEntity);
        return save.newEntity();

    }

    private boolean gowork(InspectSaveReq req,Context context) throws AppException {
        //办件保存
        StaffEntity staffEntity = getStaff(req.getStaffId().toString());
        PerformRulesEntity rule = getRule(req.getRuleId().toString());

        PerformGoworkRecordEntity recordEntity = new PerformGoworkRecordEntity();

        recordEntity.initAttrValue();
        BeanUtils.copyProperties(req, recordEntity);
       // recordEntity.setStaffId(staffEntity.getId());
        recordEntity.setStaffName(staffEntity.getName());

        recordEntity.setDeptId(staffEntity.getDeptId());
        recordEntity.setDeptName(staffEntity.getDeptName());
        recordEntity.setSubAddType(rule.getSubAddType());
        recordEntity.setScore(rule.getScore());
        recordEntity.setRuleId(rule.getId());
        recordEntity.setRuleName(rule.getName());
        recordEntity.setCategoryId(rule.getCategoryId());
        recordEntity.setCategoryName(rule.getCategoryName());
        recordEntity.setSubMethod(SubMethodEnum.大厅巡查.getValue());
        recordEntity.setCreateUserId(1L);
        recordEntity.setCreateTime(new Date());
        PerformGoworkRecordEntity save = performGoworkRecordService.save(recordEntity);
        return save.newEntity();

    }

    private boolean effect(InspectSaveReq req,Context context) throws AppException {
        //效能保存
        StaffEntity staffEntity = getStaff(req.getStaffId().toString());
        PerformRulesEntity rule = getRule(req.getRuleId().toString());

        PerformEffectRecordEntity recordEntity = new PerformEffectRecordEntity();

        recordEntity.initAttrValue();
        BeanUtils.copyProperties(req, recordEntity);
        //recordEntity.setStaffId(staffEntity.getId());
        recordEntity.setStaffName(staffEntity.getName());

        recordEntity.setDeptId(staffEntity.getDeptId());
        recordEntity.setDeptName(staffEntity.getDeptName());
        recordEntity.setSubAddType(rule.getSubAddType());
        recordEntity.setScore(rule.getScore());
        recordEntity.setRuleId(rule.getId());
        recordEntity.setRuleName(rule.getName());
        recordEntity.setCategoryId(rule.getCategoryId());
        recordEntity.setCategoryName(rule.getCategoryName());
        recordEntity.setSubMethod(SubMethodEnum.大厅巡查.getValue());
        recordEntity.setCreateUserId(context.getUser().getCustomerId());
        recordEntity.setCreateTime(new Date());
        PerformEffectRecordEntity save = effectRecordService.save(recordEntity);
        return save.newEntity();
    }

    private boolean other(InspectSaveReq req,Context context) throws AppException {
        //其它保存

        StaffEntity staffEntity = getStaff(req.getStaffId().toString());
        PerformRulesEntity rule = getRule(req.getRuleId().toString());

        PerformOtherRecordEntity recordEntity = new PerformOtherRecordEntity();

        recordEntity.initAttrValue();
        BeanUtils.copyProperties(req, recordEntity);
        //recordEntity.setStaffId(staffEntity.getId());
        recordEntity.setStaffName(staffEntity.getName());

        recordEntity.setDeptId(staffEntity.getDeptId());
        recordEntity.setDeptName(staffEntity.getDeptName());
        recordEntity.setSubAddType(rule.getSubAddType());
        recordEntity.setScore(rule.getScore());
        recordEntity.setRuleId(rule.getId());
        recordEntity.setRuleName(rule.getName());
        recordEntity.setCategoryId(rule.getCategoryId());
        recordEntity.setCategoryName(rule.getCategoryName());
        recordEntity.setSubMethod(SubMethodEnum.大厅巡查.getValue());
        recordEntity.setCreateUserId(context.getUser().getCustomerId());
        recordEntity.setCreateTime(new Date());
        PerformOtherRecordEntity save = otherRecordService.save(recordEntity);
        return save.newEntity();
    }

    /**
     * 详细
     */
    @PostMapping(value = "info")
    public Rest<PerformDetailInfo> performInfo(@RequestBody PerformReq performReq) {
        Context context = this.getContext();
        String busiDesc = "个人巡查详细";
        log.info("【{}】【请求体】--> {}", busiDesc, JSONObject.toJSONString(performReq));
        Rest<PerformDetailInfo> rest = Rest.ok(busiDesc + " 【成功】");
        try {
            if (ObjectUtils.isEmpty(performReq.getId())) {
                throw new AppException("详细查询id不能为空!");
            }
            PerformDetailInfo performDetailInfo = new PerformDetailInfo();
            if (PerformTypeEnum.考勤绩效.getValue().equals(performReq.getPerformType())) {
                CheckAttendRecordEntity checkEntity = checkAttendRecordService.get(performReq.getId(), context);
                BeanUtils.copyProperties(checkEntity, performDetailInfo, BeanUtil.getNullPropertyNames(checkEntity));
            } else if (PerformTypeEnum.评价差评绩效.getValue().equals(performReq.getPerformType())) {
                CheckReviewRecordEntity checkEntity = checkReviewRecordService.get(performReq.getId(), context);
                BeanUtils.copyProperties(checkEntity, performDetailInfo, BeanUtil.getNullPropertyNames(checkEntity));
            } else if (PerformTypeEnum.评价投诉绩效.getValue().equals(performReq.getPerformType())) {
                CheckComplainRecordEntity checkEntity = checkComplainRecordService.get(performReq.getId(), context);
                BeanUtils.copyProperties(checkEntity, performDetailInfo, BeanUtil.getNullPropertyNames(checkEntity));
            } else if (PerformTypeEnum.办件绩效.getValue().equals(performReq.getPerformType())) {
                CheckGoworkRecordEntity checkEntity = checkGoworkRecordService.get(performReq.getId(), context);
                BeanUtils.copyProperties(checkEntity, performDetailInfo, BeanUtil.getNullPropertyNames(checkEntity));
            } else if (PerformTypeEnum.效能绩效.getValue().equals(performReq.getPerformType())) {
                CheckEffectRecordEntity checkEntity = checkEffectRecordService.get(performReq.getId(), context);
                BeanUtils.copyProperties(checkEntity, performDetailInfo, BeanUtil.getNullPropertyNames(checkEntity));
            } else if (PerformTypeEnum.其它绩效.getValue().equals(performReq.getPerformType())) {
                CheckOtherRecordEntity checkEntity = checkOtherRecordService.get(performReq.getId(), context);
                BeanUtils.copyProperties(checkEntity, performDetailInfo, BeanUtil.getNullPropertyNames(checkEntity));
            } else {
                throw new AppException("不支持当前绩效类型");
            }

            rest.setData(performDetailInfo);
            recordSysLog(request, busiDesc + " 【成功】");
        } catch (Exception e) {
            log.error(busiDesc, e);
            rest = Rest.fail(super.convertException(e));
        }
        return rest;
    }

    private PerformRulesEntity getRule(String ruleId) {
        PerformRulesEntity rule = rulesService.getCache(ruleId);
        if (ObjectUtils.isEmpty(rule))
            throw new AppException(String.format("当前手机号码未找到匹配的员工！rule:%s", ruleId));

        return rule;
    }


    private StaffEntity getStaff(String staffId) {
        StaffEntity staffEntity = staffService.getCache(staffId);
        if (ObjectUtils.isEmpty(staffEntity))
            throw new AppException(String.format("当前id未找到匹配的员工！staffId:%s", staffId));

        return staffEntity;
    }


    protected void parsePageInfo(Map<String, Object> model, PageInfo pageInfo) {
        model.put(TOTAL, pageInfo.getTotalResult());
        model.put(PER_PAGE, pageInfo.getPrePageResult());
        model.put(CURRENT_PAGE, pageInfo.getCurrPage());
        model.put(LAST_PAGE, pageInfo.getTotalPage());
        model.put(PAGEINFO_KEY, pageInfo);
    }


    public static void main(String[] args) {

    }

}
