package jnpf.workflow.controller;

import cn.hutool.json.JSONUtil;
import jnpf.base.ActionResult;
import jnpf.constant.MsgCode;
import jnpf.engine.enums.FlowStatusEnum;
import jnpf.entity.workflow.ApplyAttendanceChange;
import jnpf.entity.workflow.ApplyAttendanceOutside;
import jnpf.entity.workflow.ApplyAttendanceRepair;
import jnpf.enums.personnel.FtbPersonnelsCheckStatusCodeEnum;
import jnpf.model.workflow.dto.ApplyAttendanceChangeDto;
import jnpf.model.workflow.dto.ApplyAttendanceOutsideDto;
import jnpf.model.workflow.dto.ApplyAttendanceRepairDto;
import jnpf.model.workflow.dto.ApplyAttendanceViolationDto;
import jnpf.model.workflow.vo.ApplyAttendanceChangeVo;
import jnpf.model.workflow.vo.ApplyAttendanceOutsideVo;
import jnpf.model.workflow.vo.ApplyAttendanceRepairVo;
import jnpf.model.workflow.vo.ClockKindVo;
import jnpf.util.ConstantUtil;
import jnpf.util.JsonUtil;
import jnpf.util.StringUtil;
import jnpf.workflow.service.ApplyAttendanceChangeService;
import jnpf.workflow.service.ApplyAttendanceOutsideService;
import jnpf.workflow.service.ApplyAttendanceRepairService;
import jnpf.workflow.service.ApplyAttendanceViolationService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.List;

/**
 * 打卡申请控制器
 *
 * @author yanwenfu
 * @create 2023-12-11
 */
@Slf4j
@RestController
@RequestMapping(value = "/apply")
public class ApplyClockInController {

    @Resource
    private ApplyAttendanceChangeService applyAttendanceChangeService;

    @Resource
    private ApplyAttendanceRepairService applyAttendanceRepairService;

    @Resource
    private ApplyAttendanceOutsideService applyAttendanceOutsideService;

    @Resource
    private ApplyAttendanceViolationService applyAttendanceViolationService;

    /**
     * 查询审批记录
     * @param id 审批id
     * @return jnpf.base.ActionResult<jnpf.model.workflow.vo.ApplyAttendanceChangeVo>
     */
    @GetMapping(value = "/clockIn/{id}")
    public ActionResult<ApplyAttendanceChangeVo> getApplyAttendanceChange(@PathVariable(value = "id") String id) {

        ApplyAttendanceChangeVo vo = applyAttendanceChangeService.getApplyAttendanceChange(id);
        return ActionResult.success(vo);
    }

    /**
     * 新建考勤变更申请
     * @param applyAttendanceChangeDto 表单对象
     * @return java.lang.Object
     */
    @PostMapping("/clockIn")
    public Object create(@RequestBody @Valid ApplyAttendanceChangeDto applyAttendanceChangeDto) {

        log.error("出勤变更发起 -> {}", JSONUtil.toJsonStr(applyAttendanceChangeDto));
        ActionResult<Void> actionResult = new ActionResult<>();
        try {
            // 解析 changeData
            if (null == applyAttendanceChangeDto.getChangeData() || applyAttendanceChangeDto.getChangeData().length != 2) {
                throw new Exception("变更类型异常");
            }
            applyAttendanceChangeDto.setChangeType(Integer.parseInt(applyAttendanceChangeDto.getChangeData()[0]));
            applyAttendanceChangeDto.setChangeMinute(Integer.parseInt(applyAttendanceChangeDto.getChangeData()[1]));
            ApplyAttendanceChange entity = JsonUtil.getJsonToBean(applyAttendanceChangeDto, ApplyAttendanceChange.class);
            entity.setStatus(ConstantUtil.STATUS_PENDING_APPROVAL);
            applyAttendanceChangeService.save(entity, applyAttendanceChangeDto);
        } catch (Exception e) {
            actionResult.setCode(FtbPersonnelsCheckStatusCodeEnum.CHECK_REFUSE.getCode());
            actionResult.setMsg(e.getMessage());
            return actionResult;
        }
        actionResult.setCode(FtbPersonnelsCheckStatusCodeEnum.CHECK_PASS.getCode());
        actionResult.setMsg(FtbPersonnelsCheckStatusCodeEnum.CHECK_PASS.getMsg());
        return actionResult;
    }

    /**
     * 修改考勤变更申请
     * @param applyAttendanceChangeDto 表单对象
     * @param id 主键
     * @return java.lang.Object
     */
    @PutMapping("/clockIn/{id}")
    public Object update(@RequestBody @Valid ApplyAttendanceChangeDto applyAttendanceChangeDto, @PathVariable("id") String id) throws Exception {

        ApplyAttendanceChange entity = JsonUtil.getJsonToBean(applyAttendanceChangeDto, ApplyAttendanceChange.class);
        entity.setId(id);
        if (FlowStatusEnum.save.getMessage().equals(applyAttendanceChangeDto.getStatus())) {
            applyAttendanceChangeService.save(entity, applyAttendanceChangeDto);
            return ActionResult.success(MsgCode.SU002.get());
        }
        applyAttendanceChangeService.submit(id, entity, applyAttendanceChangeDto);
        return ActionResult.success(MsgCode.SU006.get());
    }

    /**
     * 查询补卡审批记录
     * @param id 审批id
     * @return jnpf.base.ActionResult<jnpf.model.workflow.vo.ApplyAttendanceChangeVo>
     */
    @GetMapping(value = "/repair/{id}")
    public ActionResult<ApplyAttendanceRepairVo> getApplyAttendanceRepair(@PathVariable(value = "id") String id) {

        ApplyAttendanceRepairVo vo = applyAttendanceRepairService.getApplyAttendanceRepair(id);
        return ActionResult.success(vo);
    }

    /**
     * 新建补卡审批申请
     * @param applyAttendanceRepairDto 表单对象
     * @return java.lang.Object
     */
    @PostMapping("/repair11")
    public ActionResult<Void> create(@RequestBody @Valid ApplyAttendanceRepairDto applyAttendanceRepairDto) {

        ApplyAttendanceRepair entity = JsonUtil.getJsonToBean(applyAttendanceRepairDto, ApplyAttendanceRepair.class);
        entity.setStatus(ConstantUtil.STATUS_PENDING_APPROVAL);
        ActionResult<Void> actionResult = new ActionResult<>();
        try {
            applyAttendanceRepairService.save(entity, applyAttendanceRepairDto);
        } catch (Exception e) {
            actionResult.setCode(FtbPersonnelsCheckStatusCodeEnum.CHECK_REFUSE.getCode());
            actionResult.setMsg(e.getMessage());
            return actionResult;
        }
        actionResult.setCode(FtbPersonnelsCheckStatusCodeEnum.CHECK_PASS.getCode());
        actionResult.setMsg(FtbPersonnelsCheckStatusCodeEnum.CHECK_PASS.getMsg());
        return actionResult;
        /*if (FlowStatusEnum.save.getMessage().equals(applyAttendanceRepairDto.getStatus())) {
            applyAttendanceRepairService.save(id, entity, applyAttendanceRepairDto);
            return ActionResult.success(MsgCode.SU002.get());
        }
        applyAttendanceRepairService.submit(id, entity, applyAttendanceRepairDto);
        return ActionResult.success(MsgCode.SU006.get());*/
    }


    /**
     * 修改补卡审批申请
     * @param applyAttendanceRepairDto 表单对象
     * @param id 主键
     * @return java.lang.Object
     */
    @GetMapping("/repair/{id}")
    public Object update(@RequestBody @Valid ApplyAttendanceRepairDto applyAttendanceRepairDto, @PathVariable("id") String id) throws Exception {

        ApplyAttendanceRepair entity = JsonUtil.getJsonToBean(applyAttendanceRepairDto, ApplyAttendanceRepair.class);
        entity.setId(id);
        if (FlowStatusEnum.save.getMessage().equals(applyAttendanceRepairDto.getStatus())) {
            applyAttendanceRepairService.save(entity, applyAttendanceRepairDto);
            return ActionResult.success(MsgCode.SU002.get());
        }
        applyAttendanceRepairService.submit(id, entity, applyAttendanceRepairDto);
        return ActionResult.success(MsgCode.SU006.get());
    }

    /**
     * 查询外勤审批记录
     * @param id 审批id
     * @return jnpf.base.ActionResult<jnpf.model.workflow.vo.ApplyAttendanceChangeVo>
     */
    @GetMapping(value = "/outside/{id}")
    public ActionResult<ApplyAttendanceOutsideVo> getApplyAttendanceOutside(@PathVariable(value = "id") String ids) {

        ApplyAttendanceOutsideVo vo = applyAttendanceOutsideService.getApplyAttendanceOutside(id);
        return ActionResult.success(vo);
    }

    /**
     * 新建外勤审批申请
     * @param applyAttendanceOutsideDto 表单对象
     * @return java.lang.Object
     */
    @PostMapping("/outside")
    public Object create(@RequestBody @Valid ApplyAttendanceOutsideDto applyAttendanceOutsideDto) {
        if (StringUtil.isNotEmpty(applyAttendanceOutsideDto.getSpecialBusinessId())) {
            applyAttendanceOutsideDto.setClockInId(applyAttendanceOutsideDto.getSpecialBusinessId());
        }
        ApplyAttendanceOutside entity = JsonUtil.getJsonToBean(applyAttendanceOutsideDto, ApplyAttendanceOutside.class);
        entity.setStatus(ConstantUtil.STATUS_PENDING_APPROVAL);
        ActionResult<Void> actionResult = new ActionResult<>();
        try {
            applyAttendanceOutsideService.save(entity, applyAttendanceOutsideDto);
        } catch (Exception e) {
            actionResult.setCode(FtbPersonnelsCheckStatusCodeEnum.CHECK_REFUSE.getCode());
            actionResult.setMsg(e.getMessage());
            return actionResult;
        }
        actionResult.setCode(FtbPersonnelsCheckStatusCodeEnum.CHECK_PASS.getCode());
        actionResult.setMsg(FtbPersonnelsCheckStatusCodeEnum.CHECK_PASS.getMsg());
        return actionResult;
    }

    /**
     * 修改外勤审批申请
     * @param applyAttendanceOutsideDto 表单对象
     * @return java.lang.Object
     */
    @PutMapping("/outside")
    public Object update(@RequestBody @Valid ApplyAttendanceOutsideDto applyAttendanceOutsideDto) throws Exception {
        ApplyAttendanceOutside entity = JsonUtil.getJsonToBean(applyAttendanceOutsideDto, ApplyAttendanceOutside.class);
        entity.setId(applyAttendanceOutsideDto.getTaskId());
        if (FlowStatusEnum.save.getMessage().equals(applyAttendanceOutsideDto.getStatus())) {
            applyAttendanceOutsideService.save(entity, applyAttendanceOutsideDto);
            return ActionResult.success(MsgCode.SU002.get());
        }
        applyAttendanceOutsideService.submit(entity, applyAttendanceOutsideDto);
        return ActionResult.success(MsgCode.SU006.get());
    }

    /**
     * 修改外勤审批申请
     * @param applyAttendanceOutsideDto 表单对象
     * @return java.lang.Object
     */
    @PutMapping("/test")
    public Object test(@RequestBody @Valid ApplyAttendanceOutsideDto applyAttendanceOutsideDto) throws Exception {
        ApplyAttendanceOutside entity = JsonUtil.getJsonToBean(applyAttendanceOutsideDto, ApplyAttendanceOutside.class);
        entity.setId(applyAttendanceOutsideDto.getTaskId());
        if (FlowStatusEnum.save.getMessage().equals(applyAttendanceOutsideDto.getStatus())) {
            applyAttendanceOutsideService.save(entity, applyAttendanceOutsideDto);
            return ActionResult.success(MsgCode.SU002.get());
        }
        applyAttendanceOutsideService.submit(entity, applyAttendanceOutsideDto);
        return ActionResult.success(MsgCode.SU006.get());
    }

    /**
     * 新建违规打卡审批申请
     * @param applyAttendanceViolationDto 表单对象
     * @return java.lang.Object
     */
    @PostMapping("/violation")
    public Object createViolation(@RequestBody @Valid ApplyAttendanceViolationDto applyAttendanceViolationDto) {

        log.error("违规打卡审批: {}", applyAttendanceViolationDto.toString());
        if (StringUtil.isNotEmpty(applyAttendanceViolationDto.getSpecialBusinessId())) {
            applyAttendanceViolationDto.setClockInId(applyAttendanceViolationDto.getSpecialBusinessId());
        }
        ActionResult<Void> actionResult = new ActionResult<>();
        try {
            applyAttendanceViolationService.saveRecord(applyAttendanceViolationDto);
        } catch (Exception e) {
            e.printStackTrace();
            actionResult.setCode(FtbPersonnelsCheckStatusCodeEnum.CHECK_REFUSE.getCode());
            actionResult.setMsg(e.getMessage());
            return actionResult;
        }
        actionResult.setCode(FtbPersonnelsCheckStatusCodeEnum.CHECK_PASS.getCode());
        actionResult.setMsg(FtbPersonnelsCheckStatusCodeEnum.CHECK_PASS.getMsg());
        return actionResult;
    }

    /**
     * 获取打卡类型
     * @return jnpf.base.ActionResult<java.util.List<jnpf.model.workflow.vo.ClockKindVo>>
     */
    @GetMapping(value = "/violation/clock-kind1")
    public ActionResult<List<ClockKindVo>> getClockKindList() {

        List<ClockKindVo> list = List.of(new ClockKindVo(1, "内勤打卡"), new ClockKindVo(2, "外勤打卡"));
        return ActionResult.success(list);
    }

    /**
     * 获取打卡设备类型
     * @return jnpf.base.ActionResult<java.util.List<jnpf.model.workflow.vo.ClockKindVo>>
     */
    @GetMapping(value = "/violation/device-type")
    public ActionResult<List<ClockKindVo>> getDeviceTypeList() {

        List<ClockKindVo> list = List.of(new ClockKindVo(1, "地点打卡"), new ClockKindVo(2, "WIFI打卡"), new ClockKindVo(3, "考勤机打卡"));
        return ActionResult.success(list);
    }
}
