package com.mortals.xhx.module.attendance.web;

import com.mortals.framework.annotation.RepeatSubmit;
import com.mortals.framework.annotation.UnAuth;
import com.mortals.framework.common.Rest;
import com.mortals.framework.exception.AppException;
import com.mortals.framework.model.*;
import com.mortals.framework.service.IUser;
import com.mortals.framework.util.DateUtils;
import com.mortals.framework.utils.BeanUtil;
import com.mortals.framework.utils.ReflectUtils;
import com.mortals.framework.web.BaseCRUDJsonBodyMappingController;
import com.mortals.xhx.base.system.param.service.ParamService;
import com.mortals.xhx.busiz.h5.req.AttendSaveReq;
import com.mortals.xhx.busiz.h5.web.ApiWebPerformController;
import com.mortals.xhx.common.code.ErrorStatusEnum;
import com.mortals.xhx.common.code.ProcessStatusEnum;
import com.mortals.xhx.common.code.YesNoEnum;
import com.mortals.xhx.module.attendance.model.*;
import com.mortals.xhx.module.attendance.model.vo.ErrorSummaryVo;
import com.mortals.xhx.module.attendance.service.*;
import com.mortals.xhx.module.dept.model.DeptQuery;
import com.mortals.xhx.module.dept.service.DeptService;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.mortals.framework.web.BaseCRUDJsonBodyMappingController;
import org.apache.commons.lang3.ArrayUtils;
import com.mortals.framework.util.StringUtils;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

import com.alibaba.fastjson.JSONObject;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import static com.mortals.framework.ap.SysConstains.*;

/**
 * 考勤打卡记录异常信息
 *
 * @author zxfei
 * @date 2023-04-08
 */
@RestController
@RequestMapping("attendance/record/error")
public class AttendanceRecordErrorController extends BaseCRUDJsonBodyMappingController<AttendanceRecordErrorService, AttendanceRecordErrorEntity, Long> {

    @Autowired
    private ParamService paramService;
    @Autowired
    private AttendanceGroupService attendanceGroupService;
    @Autowired
    private DeptService deptService;
    @Autowired
    private AttendanceClassService attendanceClassService;
    @Autowired
    private AttendanceRecordErrorService errorService;


    public AttendanceRecordErrorController() {
        super.setModuleDesc("考勤打卡记录异常信息");
    }

    @Override
    protected void init(Map<String, Object> model, Context context) {
        this.addDict(model, "errorStatus", ErrorStatusEnum.getEnumMap());
        this.addDict(model, "processResult", ErrorStatusEnum.getEnumMap());
        this.addDict(model, "processStatus", paramService.getParamBySecondOrganize("AttendanceRecordError", "processStatus"));
        this.addDict(model, "deptId", deptService.find(new DeptQuery()).stream().collect(Collectors.toMap(x -> x.getId().toString(), y -> y.getDeptName())));
        this.addDict(model, "attendanceGroupId", attendanceGroupService.find(new AttendanceGroupQuery()).stream().collect(Collectors.toMap(x -> x.getId().toString(), y -> y.getGroupName())));
        this.addDict(model, "classId", attendanceClassService.find(new AttendanceClassQuery()).stream().collect(Collectors.toMap(x -> x.getId().toString(), y -> y.getClassName())));
        super.init(model, context);
    }


    @PostMapping(value = "revokeError")
    public Rest<String> disposeError(@RequestBody AttendanceRecordErrorEntity query) {
        Rest<String> ret = new Rest();
        Context context = this.getContext();
        query.setOpertor(context.getUser().getRealName());
        query.setOperDateTime(new Date());
        query.setProcessStatus(0);
        query.setProcessResult("已撤销处理");
        errorService.update(query);
        return Rest.ok();
    }


    @Override
    protected void saveBefore(AttendanceRecordErrorEntity entity, Map<String, Object> model, Context context) throws AppException {
        for (AttendanceRecordErrorEntity recordErrorEntity : entity.getRecordErrorEntities()) {
            AttendanceRecordErrorEntity updateEntity = new AttendanceRecordErrorEntity();
            updateEntity.setId(recordErrorEntity.getId());
            updateEntity.setProcessStatus(entity.getProcessStatus());
            updateEntity.setProcessResult(entity.getProcessResult());
            updateEntity.setStaffId(recordErrorEntity.getStaffId());
            updateEntity.setErrorStatus(entity.getErrorStatus());
            updateEntity.setOpertor(context.getUser().getRealName());
            updateEntity.setOperDateTime(new Date());
            updateEntity.setRemark(entity.getRemark());
            updateEntity.setUpdateTime(new Date());
            updateEntity.setUpdateUserId(this.getContextUserId(getContext()));
            updateEntity.setDuration(entity.getDuration());
            this.service.update(updateEntity, getContext());
            entity.setId(recordErrorEntity.getId());
        }
        super.saveBefore(entity, model, context);
    }

    @Override
    @PostMapping({"save"})
    @RepeatSubmit
    public String save(@RequestBody AttendanceRecordErrorEntity entity) {
        Map<String, Object> model = new HashMap();
        Context context = this.getContext();
        String busiDesc = "保存" + this.getModuleDesc();

        int code = 1;
        try {
            this.saveBefore(entity, model, context);
            if (entity.newEntity()) {
                Class<AttendanceRecordErrorEntity> tClass = ReflectUtils.getClassGenricType(this.getClass(), 1);
                AttendanceRecordErrorEntity initEntity =  tClass.newInstance();
                initEntity.initAttrValue();
                BeanUtils.copyProperties(entity, initEntity, BeanUtil.getNullPropertyNames(entity));
                entity = initEntity;
                busiDesc = "新增" + this.getModuleDesc();
                initEntity.setCreateTime(new Date());
                IUser user = this.getCurUser();
                if (user != null) {
                    initEntity.setCreateUserId(user.getId());
                    initEntity.setCreateUser(user.getLoginName());
                    initEntity.setCreateUserName(user.getRealName());
                    initEntity.setCreateUserDeptId(user.getDeptId());
                    initEntity.setCreateUserDeptName(user.getDeptName());
                }

                this.service.save(initEntity, context);
            }

            model.put("id", entity.getId());
            code = this.saveAfter(entity, model, context);
            model.put("entity", entity);
            model.put("message_info", busiDesc + "成功");
            this.recordSysLog(this.request, busiDesc + " 【成功】 [id:" + entity.getId() + "]");
        } catch (Exception var9) {
            this.doException(this.request, busiDesc, model, var9);
            model.put("entity", entity);
            this.init(model, context);
            code = this.saveException(entity, model, context, var9);
        }

        this.init(model, context);
        JSONObject ret = new JSONObject();
        ret.put("code", code);
        ret.put("msg", model.remove("message_info"));
        ret.put("data", model);
        return ret.toJSONString();
    }


    @Override
    protected int editAfter(Long id, Map<String, Object> model, AttendanceRecordErrorEntity entity, Context context) throws AppException {
        this.addDict(model, "errorStatus", paramService.getParamBySecondOrganize("AttendanceRecordDetail", "goWorkResult"));
        return super.editAfter(id, model, entity, context);
    }


    @Override
    protected void doListBefore(AttendanceRecordErrorEntity query, Map<String, Object> model, Context context) throws AppException {
        if (ObjectUtils.isEmpty(query.getOrderColList())) {
            query.setOrderColList(Arrays.asList(new OrderCol("errorDateTime", OrderCol.DESCENDING), new OrderCol("staffName", OrderCol.DESCENDING)));
        } else {
            query.getOrderColList().add(new OrderCol("errorDateTime", OrderCol.DESCENDING));
        }

    }

    @Override
    protected void doListAfter(AttendanceRecordErrorEntity query, List<AttendanceRecordErrorEntity> list, Context context) throws AppException {
        super.doListAfter(query, list, context);
    }

    /**
     * 从新生成已处理的绩效考勤核查数据
     *
     * @param query
     * @return
     */
    @PostMapping({"doReprocess"})
    @UnAuth
    public Rest<String> doReprocess(@RequestBody AttendanceRecordErrorQuery query) {
        Rest<String> ret = new Rest();
        Context context = this.getContext();

        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                service.doReprocess(query, context);
            }
        });
        thread.start();
        return Rest.ok();
    }

    /**
     * 查询当月异常考勤次数排行榜
     *
     * @return
     */
    @PostMapping({"month/top"})
    @UnAuth
    public Rest<Object> getMonthTopList() {
        Rest<Object> ret = new Rest();
        Map<String, Object> model = new HashMap();
        Context context = this.getContext();
        String busiDesc = "查询当月异常考勤次数排行榜";
        int code = 1;
        try {
            AttendanceRecordErrorQuery query = new AttendanceRecordErrorQuery();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            Calendar calendar = Calendar.getInstance();
            calendar.set(Calendar.DAY_OF_MONTH, 1);
            query.setErrorDateTimeStart(sdf.format(calendar.getTime()));
            calendar.roll(Calendar.DAY_OF_MONTH, -1);
            query.setErrorDateTimeEnd(sdf.format(calendar.getTime()));
            List<ErrorSummaryVo> result = this.getService().getMonthTop10(query);
            model.put("data", result);
            model.put("message_info", busiDesc + "成功");
            if (!ObjectUtils.isEmpty(context) && !ObjectUtils.isEmpty(context.getUser())) {
                this.recordSysLog(this.request, busiDesc + " 【成功】");
            }
        } catch (Exception var9) {
            code = -1;
            this.doException(this.request, busiDesc, model, var9);
        }
        this.init(model, context);
        ret.setCode(code);
        ret.setData(model.get("data"));
        ret.setMsg(model.get("message_info") == null ? "" : model.remove("message_info").toString());
        return ret;
    }

}
