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

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.mortals.framework.annotation.UnAuth;
import com.mortals.framework.common.Rest;
import com.mortals.framework.exception.AppException;
import com.mortals.xhx.busiz.h5.req.*;
import com.mortals.xhx.common.code.SubMethodEnum;
import com.mortals.xhx.common.code.YesNoEnum;
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.model.StaffQuery;
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.List;
import java.util.Set;
import java.util.stream.Collectors;

@RestController
@Slf4j
@RequestMapping("/api/v1/web/")
public class ApiWebPerformController 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 PerformRulesCategoryService categoryService;
    @Autowired
    private PerformStaffConfService performStaffConfService;
    @Autowired
    private PerformStaffConfDetailService performStaffConfDetailService;
    @Autowired
    private PerformErrorRecordService errorRecordService;


    /**
     * 考勤新增
     *
     * @param req
     * @return
     */
    @PostMapping("attend/save")
    @UnAuth
    public Rest<Void> attendSave(@RequestBody AttendSaveReq req) {
        log.info("web Api req==>{}", JSON.toJSONString(req));
        String busiDesc = "外部考勤新增";
        Rest rest = Rest.ok(busiDesc + "成功！");
        try {
            if (ObjectUtils.isEmpty(req.getPhone())) throw new AppException("手机号码不能为空！");
            if (ObjectUtils.isEmpty(req.getRuleCode())) throw new AppException("绩效规则编码不能为空！");
            boolean bool = attend(req);
            if (bool) throw new AppException(busiDesc + "失败！");
        } catch (Exception e) {
            log.error(busiDesc, e);
            return Rest.fail(e.getMessage());
        }
        log.info("响应【{}】【响应体】--> {} ", busiDesc, JSONObject.toJSONString(rest));
        return rest;
    }

    /**
     * 评价新增
     *
     * @param req
     * @return
     */
    @PostMapping("review/save")
    @UnAuth
    public Rest<Void> reviewSave(@RequestBody ReviewSaveReq req) {
        log.info("web Api req==>{}", JSON.toJSONString(req));
        String busiDesc = "外部评价新增";
        Rest rest = Rest.ok(busiDesc + "成功！");
        try {
            if (ObjectUtils.isEmpty(req.getPhone())) throw new AppException("手机号码不能为空！");
            if (ObjectUtils.isEmpty(req.getRuleCode())) throw new AppException("绩效规则编码不能为空！");
            boolean bool = review(req);
            if (bool) throw new AppException(busiDesc + "失败！");
        } catch (Exception e) {
            log.error(busiDesc, e);
            return Rest.fail(e.getMessage());
        }
        log.info("响应【{}】【响应体】--> {} ", busiDesc, JSONObject.toJSONString(rest));
        return rest;
    }

    /**
     * 投诉新增
     *
     * @param req
     * @return
     */
    @PostMapping("complain/save")
    @UnAuth
    public Rest<Void> complainSave(@RequestBody ComplainSaveReq req) {
        log.info("web Api req==>{}", JSON.toJSONString(req));
        String busiDesc = "外部投诉新增";
        Rest rest = Rest.ok(busiDesc + "成功！");
        try {
            if (ObjectUtils.isEmpty(req.getPhone())) throw new AppException("手机号码不能为空！");
            if (ObjectUtils.isEmpty(req.getRuleCode())) throw new AppException("绩效规则编码不能为空！");
            boolean bool = complain(req);
            if (bool) throw new AppException(busiDesc + "失败！");
        } catch (Exception e) {
            log.error(busiDesc, e);
            return Rest.fail(e.getMessage());
        }
        log.info("响应【{}】【响应体】--> {} ", busiDesc, JSONObject.toJSONString(rest));
        return rest;
    }

    /**
     * 办件新增
     *
     * @param req
     * @return
     */
    @PostMapping("gowork/save")
    @UnAuth
    public Rest<Void> goworkSave(@RequestBody GoWorkSaveReq req) {
        log.info("web Api req==>{}", JSON.toJSONString(req));
        String busiDesc = "外部办件新增";
        Rest rest = Rest.ok(busiDesc + "成功！");
        try {
            if (ObjectUtils.isEmpty(req.getPhone())) throw new AppException("手机号码不能为空！");
            if (ObjectUtils.isEmpty(req.getRuleCode())) throw new AppException("绩效规则编码不能为空！");
            boolean bool = gowork(req);
            if (bool) throw new AppException(busiDesc + "失败！");
        } catch (Exception e) {
            log.error(busiDesc, e);
            return Rest.fail(e.getMessage());
        }
        log.info("响应【{}】【响应体】--> {} ", busiDesc, JSONObject.toJSONString(rest));
        return rest;
    }

    /**
     * 效能新增
     *
     * @param req
     * @return
     */
    @PostMapping("effect/save")
    @UnAuth
    public Rest<Void> effectSave(@RequestBody EffectSaveReq req) {
        log.info("web Api req==>{}", JSON.toJSONString(req));
        String busiDesc = "外部效能新增";
        Rest rest = Rest.ok(busiDesc + "成功！");
        try {
            if (ObjectUtils.isEmpty(req.getRuleCode())) {
                //保存异常数据/
                effectErrorSave(req);
                rest = Rest.fail("绩效规则编码不能为空！");
            }

            if (YesNoEnum.YES.getValue() == rest.getCode()) {
                effect(req);
            }
        } catch (Exception e) {
            log.error(busiDesc, e);
            return Rest.fail(e.getMessage());
        }
        log.info("响应【{}】【响应体】--> {} ", busiDesc, JSONObject.toJSONString(rest));
        return rest;
    }

    /**
     * 其它新增
     *
     * @param req
     * @return
     */
    @PostMapping("other/save")
    @UnAuth
    public Rest<Void> otherSave(@RequestBody OtherSaveReq req) {
        log.info("web Api req==>{}", JSON.toJSONString(req));
        String busiDesc = "外部其它绩效新增";
        Rest rest = Rest.ok(busiDesc + "成功！");
        try {
            if (ObjectUtils.isEmpty(req.getPhone())) throw new AppException("手机号码不能为空！");
            if (ObjectUtils.isEmpty(req.getRuleCode())) throw new AppException("绩效规则编码不能为空！");
            boolean bool = other(req);
            if (bool) throw new AppException(busiDesc + "失败！");
        } catch (Exception e) {
            log.error(busiDesc, e);
            return Rest.fail(e.getMessage());
        }
        log.info("响应【{}】【响应体】--> {} ", busiDesc, JSONObject.toJSONString(rest));
        return rest;
    }


    private boolean attend(AttendSaveReq req) throws AppException {
        //考勤保存
        //通过手机号码查询员工属性
        PerformRulesEntity rule = getRule(req.getRuleCode());
        StaffEntity staffEntity = getStaff(req.getPhone());
        checkStaffAutoConf(staffEntity, rule);
        PerformAttendRecordEntity recordEntity = new PerformAttendRecordEntity();
        recordEntity.initAttrValue();
        recordEntity.setSubMethod(SubMethodEnum.系统自动.getValue());
        BeanUtils.copyProperties(req, recordEntity);
        recordEntity.setStaffId(staffEntity.getId());
        recordEntity.setStaffName(staffEntity.getName());
        recordEntity.setWorkNum(staffEntity.getWorkNum());
        recordEntity.setDeptId(staffEntity.getDeptId());
        recordEntity.setDeptName(staffEntity.getDeptName());
        recordEntity.setSalaId(staffEntity.getSalaId());
        recordEntity.setSalaName(staffEntity.getSalaName());
        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.setDeductPerson("系统管理员");
        recordEntity.setDeductTime(new Date());
        recordEntity.setCreateUserId(1L);
        recordEntity.setCreateTime(new Date());
        recordEntity.setWorkNum(staffEntity.getWorkNum());
        PerformRulesCategoryEntity categoryEntity = categoryService.get(rule.getCategoryId());
        recordEntity.setCategoryName(categoryEntity == null ? "" : categoryEntity.getName());


        PerformAttendRecordEntity save = attendRecordService.save(recordEntity);

        return save.newEntity();

    }


    private boolean review(ReviewSaveReq req) throws AppException {
        //评价保存
        StaffEntity staffEntity = getStaff(req.getPhone());
        PerformRulesEntity rule = getRule(req.getRuleCode());
        checkStaffAutoConf(staffEntity, rule);
        PerformReviewRecordEntity recordEntity = new PerformReviewRecordEntity();
        recordEntity.initAttrValue();
        recordEntity.setSubMethod(SubMethodEnum.系统自动.getValue());
        BeanUtils.copyProperties(req, recordEntity);
        recordEntity.setStaffId(staffEntity.getId());
        recordEntity.setStaffName(staffEntity.getName());
        recordEntity.setWorkNum(staffEntity.getWorkNum());
        recordEntity.setDeptId(staffEntity.getDeptId());
        recordEntity.setDeptName(staffEntity.getDeptName());
        recordEntity.setSalaId(staffEntity.getSalaId());
        recordEntity.setSalaName(staffEntity.getSalaName());
        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.setDeductPerson("系统管理员");
        recordEntity.setDeductTime(new Date());
        recordEntity.setCreateUserId(1L);
        recordEntity.setCreateTime(new Date());
        recordEntity.setWorkNum(staffEntity.getWorkNum());
        recordEntity.setWindowNum(req.getWindowNum());
        recordEntity.setReviewTime(DateUtil.parse(req.getReviewTime()));
        PerformRulesCategoryEntity categoryEntity = categoryService.get(rule.getCategoryId());
        recordEntity.setCategoryName(categoryEntity == null ? "" : categoryEntity.getName());
        PerformReviewRecordEntity save = reviewRecordService.save(recordEntity);
        return save.newEntity();

    }

    private void checkStaffAutoConf(StaffEntity staffEntity, PerformRulesEntity rule) {
        Boolean rulePass = false;
        //校验当前员工是否存在自动规则中
        List<PerformStaffConfEntity> performStaffConfEntities = performStaffConfService.find(new PerformStaffConfQuery());
        for (PerformStaffConfEntity performStaffConfEntity : performStaffConfEntities) {
            String staffIds = performStaffConfEntity.getStaffIds();
            Set<String> split = StrUtil.split(staffIds, ",").stream().collect(Collectors.toSet());
            if (split.contains(staffEntity.getId().toString())) {
                //查询当前规则
                List<PerformStaffConfDetailEntity> staffConfDetailEntities = performStaffConfDetailService.find(new PerformStaffConfDetailQuery().staffConfId(performStaffConfEntity.getId()));
                for (PerformStaffConfDetailEntity staffConfDetailEntity : staffConfDetailEntities) {
                    if (staffConfDetailEntity.getRuleId() == rule.getId()) {
                        rulePass = true;
                        break;
                    }
                }
            }
            if (rulePass) break;
        }
        if (rulePass) throw new AppException("当前用户与绩效规则未配置自动核查，请在后台配置后再新增！");
    }

    private boolean complain(ComplainSaveReq req) throws AppException {
        //投诉保存
        StaffEntity staffEntity = getStaff(req.getPhone());
        PerformRulesEntity rule = getRule(req.getRuleCode());
        checkStaffAutoConf(staffEntity, rule);
        PerformComplainRecordEntity recordEntity = new PerformComplainRecordEntity();
        recordEntity.initAttrValue();
        recordEntity.setSubMethod(SubMethodEnum.系统自动.getValue());
        BeanUtils.copyProperties(req, recordEntity);
        recordEntity.setStaffId(staffEntity.getId());
        recordEntity.setStaffName(staffEntity.getName());
        recordEntity.setWorkNum(staffEntity.getWorkNum());
        recordEntity.setDeptId(staffEntity.getDeptId());
        recordEntity.setDeptName(staffEntity.getDeptName());
        recordEntity.setSalaId(staffEntity.getSalaId());
        recordEntity.setSalaName(staffEntity.getSalaName());
        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.setDeductPerson("系统管理员");
        recordEntity.setDeductTime(new Date());
        recordEntity.setWorkNum(staffEntity.getWorkNum());

        recordEntity.setCreateUserId(1L);
        recordEntity.setCreateTime(new Date());
        PerformRulesCategoryEntity categoryEntity = categoryService.get(rule.getCategoryId());
        recordEntity.setCategoryName(categoryEntity == null ? "" : categoryEntity.getName());
        PerformComplainRecordEntity save = complainRecordService.save(recordEntity);
        return save.newEntity();

    }

    private boolean gowork(GoWorkSaveReq req) throws AppException {
        //办件保存
        StaffEntity staffEntity = getStaff(req.getPhone());
        PerformRulesEntity rule = getRule(req.getRuleCode());
        checkStaffAutoConf(staffEntity, rule);
        PerformGoworkRecordEntity recordEntity = new PerformGoworkRecordEntity();
        recordEntity.initAttrValue();
        recordEntity.setSubMethod(SubMethodEnum.系统自动.getValue());
        BeanUtils.copyProperties(req, recordEntity);
        recordEntity.setStaffId(staffEntity.getId());
        recordEntity.setStaffName(staffEntity.getName());
        recordEntity.setWorkNum(staffEntity.getWorkNum());
        recordEntity.setDeptId(staffEntity.getDeptId());
        recordEntity.setDeptName(staffEntity.getDeptName());
        recordEntity.setSalaId(staffEntity.getSalaId());
        recordEntity.setSalaName(staffEntity.getSalaName());
        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.setDeductPerson("系统管理员");
        recordEntity.setDeductTime(new Date());

        recordEntity.setWorkNum(staffEntity.getWorkNum());

        recordEntity.setCreateUserId(1L);
        recordEntity.setCreateTime(new Date());
        PerformRulesCategoryEntity categoryEntity = categoryService.get(rule.getCategoryId());
        recordEntity.setCategoryName(categoryEntity == null ? "" : categoryEntity.getName());
        PerformGoworkRecordEntity save = performGoworkRecordService.save(recordEntity);
        return save.newEntity();

    }

    private boolean effect(EffectSaveReq req) throws AppException {
        //效能保存
        StaffEntity staffEntity = getStaff(req);
        if (ObjectUtils.isEmpty(staffEntity)) return false;
        PerformRulesEntity rule = getRule(req.getRuleCode());
        PerformEffectRecordEntity recordEntity = new PerformEffectRecordEntity();
        recordEntity.initAttrValue();
        recordEntity.setSubMethod(SubMethodEnum.系统自动.getValue());
        BeanUtils.copyProperties(req, recordEntity);
        recordEntity.setStaffId(staffEntity.getId());
        recordEntity.setStaffName(staffEntity.getName());
        recordEntity.setWorkNum(staffEntity.getWorkNum());
        recordEntity.setDeptId(staffEntity.getDeptId());
        recordEntity.setDeptName(staffEntity.getDeptName());
        recordEntity.setSalaId(staffEntity.getSalaId());
        recordEntity.setSalaName(staffEntity.getSalaName());
        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.setDeductPerson("系统管理员");
        recordEntity.setDeductTime(new Date());
        recordEntity.setWorkNum(staffEntity.getWorkNum());
        recordEntity.setRemark(req.getExt());
        recordEntity.setWindowNum(req.getWindowNum());
        recordEntity.setCreateUserId(1L);
        recordEntity.setCreateTime(new Date());
        PerformRulesCategoryEntity categoryEntity = categoryService.get(rule.getCategoryId());
        recordEntity.setCategoryName(categoryEntity == null ? "" : categoryEntity.getName());
        PerformEffectRecordEntity save = effectRecordService.save(recordEntity);
        return save.newEntity();
    }


    private void effectErrorSave(EffectSaveReq req) throws AppException {
        //效能异常保存
        StaffEntity staffEntity = getStaff(req.getPhone());
        PerformRulesEntity rule = getRule(req.getRuleCode());
        //checkStaffAutoConf(staffEntity, rule);
        PerformErrorRecordEntity recordEntity = new PerformErrorRecordEntity();
        recordEntity.initAttrValue();
        recordEntity.setSubMethod(SubMethodEnum.系统自动.getValue());
        BeanUtils.copyProperties(req, recordEntity);
        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.setDeductPerson("系统管理员");
        recordEntity.setDeductTime(new Date());

        recordEntity.setWindowNum(req.getWindowNum());
        recordEntity.setCreateUserId(1L);
        recordEntity.setCreateTime(new Date());
        PerformRulesCategoryEntity categoryEntity = categoryService.get(rule.getCategoryId());
        recordEntity.setCategoryName(categoryEntity == null ? "" : categoryEntity.getName());
        errorRecordService.save(recordEntity);

    }


    private boolean other(OtherSaveReq req) throws AppException {
        //其它保存
        StaffEntity staffEntity = getStaff(req.getPhone());
        PerformRulesEntity rule = getRule(req.getRuleCode());
        checkStaffAutoConf(staffEntity, rule);
        PerformOtherRecordEntity recordEntity = new PerformOtherRecordEntity();
        recordEntity.initAttrValue();
        recordEntity.setSubMethod(SubMethodEnum.系统自动.getValue());
        BeanUtils.copyProperties(req, recordEntity);
        recordEntity.setStaffId(staffEntity.getId());
        recordEntity.setStaffName(staffEntity.getName());
        recordEntity.setWorkNum(staffEntity.getWorkNum());
        recordEntity.setDeptId(staffEntity.getDeptId());
        recordEntity.setDeptName(staffEntity.getDeptName());
        recordEntity.setSalaId(staffEntity.getSalaId());
        recordEntity.setSalaName(staffEntity.getSalaName());
        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.setWorkNum(staffEntity.getWorkNum());

        recordEntity.setDeductPerson("系统管理员");
        recordEntity.setDeductTime(new Date());

        recordEntity.setCreateUserId(1L);
        recordEntity.setCreateTime(new Date());
        PerformRulesCategoryEntity categoryEntity = categoryService.get(rule.getCategoryId());
        recordEntity.setCategoryName(categoryEntity == null ? "" : categoryEntity.getName());
        PerformOtherRecordEntity save = otherRecordService.save(recordEntity);
        return save.newEntity();
    }


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

    private StaffEntity getStaff(String phone) {
        StaffEntity staffEntity = staffService.selectOne(new StaffQuery().phoneNumber(phone));
        if (ObjectUtils.isEmpty(staffEntity)) {
            throw new AppException(String.format("当前手机号码未找到匹配的员工！phone:%s", phone));
        }

        return staffEntity;
    }

    private StaffEntity getStaff(EffectSaveReq req) {
        if (!ObjectUtils.isEmpty(req.getPhone())) {
            List<StaffEntity> staffEntityList = staffService.find(new StaffQuery().phoneNumber(req.getPhone()));
            if (staffEntityList.size() > 1) {
                //多个 比对名字
                for (StaffEntity staffEntity : staffEntityList) {
                    if (staffEntity.getName().equals(req.getStaffName())) {
                        return staffEntity;
                    }
                }

                if (!ObjectUtils.isEmpty(req.getStaffName())) {
                    StaffEntity staffEntity = staffService.selectOne(new StaffQuery().name(req.getStaffName()));
                    if (!ObjectUtils.isEmpty(staffEntity)) return staffEntity;
                }

                return staffEntityList.get(0);
            } else if (staffEntityList.size() == 1) {
                return staffEntityList.get(0);
            }
            StaffEntity staffEntity = staffService.selectOne(new StaffQuery().phoneNumber(req.getPhone()));
            if (!ObjectUtils.isEmpty(staffEntity)) return staffEntity;
        }
        if (!ObjectUtils.isEmpty(req.getStaffName())) {
            StaffEntity staffEntity = staffService.selectOne(new StaffQuery().name(req.getStaffName()));
            if (!ObjectUtils.isEmpty(staffEntity)) return staffEntity;
        }
        return null;

    }


    public static void main(String[] args) {

    }

}
