package yangtz.cs.liu.wechat.controller.leave;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.util.UserInfoUtil;
import com.ruoyi.system.service.ISysUserService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.impl.persistence.entity.TaskEntityImpl;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import yangtz.cs.liu.activiti.domain.HistoricActivity;
import yangtz.cs.liu.activiti.service.IProcessService;
import yangtz.cs.liu.campus.domain.schoolClass.SchoolClass;
import yangtz.cs.liu.campus.domain.student.SchoolStudent;
import yangtz.cs.liu.campus.domain.student.SchoolStudentLeave;
import yangtz.cs.liu.campus.domain.student.SchoolStudentParent;
import yangtz.cs.liu.campus.domain.temp.LeaveResultTemplate;
import yangtz.cs.liu.campus.mapper.teacher.SchoolTeacherLeaveMapper;
import yangtz.cs.liu.campus.service.schoolClass.ISchoolClassService;
import yangtz.cs.liu.campus.service.student.ISchoolStudentLeaveService;
import yangtz.cs.liu.campus.service.student.ISchoolStudentParentService;
import yangtz.cs.liu.campus.service.student.ISchoolStudentService;
import yangtz.cs.liu.campus.service.teacher.ISchoolTeacherService;
import yangtz.cs.liu.campus.vo.student.StudentLeaveVO;
import yangtz.cs.liu.wechat.domain.template.LeaveTemplate;
import yangtz.cs.liu.wechat.domain.template.StudentLeaveTemplate;
import yangtz.cs.liu.wechat.service.api.IWxApiService;

import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

import static com.core.constant.ProcessDefinition.STUDENTLEAVE;
import static com.core.utils.HolidayDateUtil.dateToStamp;
import static com.ruoyi.common.utils.DateUtils.differentDaysByMillisecond;
import static com.ruoyi.common.utils.StringUtils.substring;
import static yangtz.cs.liu.campus.constant.ProcessState.*;
import static yangtz.cs.liu.wechat.constant.ProcessTypeConstant.*;
import static yangtz.cs.liu.wechat.constant.ProcessTypeConstant.OTHER;

/**
 * @author lyric
 * @date 2022/10/31 17:54
 * <p>
 * 学生请假
 */
@RestController
@RequestMapping("/wx/studentLeave")
public class WxStudentLeaveController extends BaseController {
    @Autowired
    private SchoolTeacherLeaveMapper schoolTeacherLeaveMapper;

    @Autowired
    private ISchoolStudentLeaveService schoolStudentLeaveService;

    @Autowired
    private IProcessService processService;

    @Autowired
    private ISysUserService userService;

    @Autowired
    private IWxApiService wxApiService;
    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private TaskService taskService;
    @Autowired
    private UserInfoUtil userInfoUtil;

    @Autowired
    private ISchoolClassService classService;

    @Autowired
    private ISchoolStudentParentService schoolStudentParentService;

    @Autowired
    private ISchoolStudentService schoolStudentService;

    @Autowired
    private ISchoolTeacherService teacherService;

    private Logger log = LoggerFactory.getLogger(WxStudentLeaveController.class);

    /**
     * 学生请假列表
     *
     * @param
     * @return
     */
    @GetMapping("/list")
    public TableDataInfo list(@RequestParam("submitState") String submitState, StudentLeaveVO studentLeave) {
        startPage();
        // TODO 按申请人过滤
        List<StudentLeaveVO> list = schoolStudentLeaveService.queryList(submitState, studentLeave);
        return getDataTable(list);
    }

//    /**
//     * 查询详情
//     *
//     * @param id
//     * @return
//     */
//    @GetMapping("/queryOne/{id}")
//    public AjaxResult queryOne(@PathVariable("id") Long id) {
//        return AjaxResult.success(schoolStudentLeaveService.getById(id));
//    }

    /**
     * 提交申请
     */
    @PostMapping("/submitApply")
    public AjaxResult submitApply(@RequestBody @Validated SchoolStudentLeave schoolStudentLeave) {
        schoolStudentLeaveService.save(schoolStudentLeave);
        String applyUser = schoolStudentLeave.getApplyUser();
        schoolStudentLeave.setApplyTime(DateUtils.getNowDate());
        schoolStudentLeaveService.submitApply(schoolStudentLeave, applyUser, STUDENTLEAVE, new HashMap<>());


        /** 提交请假模板消息 */
        LeaveTemplate leaveTemplate = new LeaveTemplate();
        String openId = userService.getOpenIdByUserId(schoolStudentLeave.getHandUserId());
        leaveTemplate.setToUserOpenId(openId);
        leaveTemplate.setIdentity(0);
        leaveTemplate.setLeaveStartTime(schoolStudentLeave.getStartTime());
        leaveTemplate.setLeaveEndTime(schoolStudentLeave.getEndTime());
        leaveTemplate.setUserName(schoolStudentLeave.getStudentName());

        return AjaxResult.success(wxApiService.sendTemplate(leaveTemplate));
    }

    /**
     * 待办事项列表
     */
    @GetMapping("/taskList/{userId}")
    public TableDataInfo taskList(@PathVariable("userId") String userId, SchoolStudentLeave entity) {
        List<StudentLeaveVO> list = schoolStudentLeaveService.findTodoTasks(STUDENTLEAVE, entity, userId);
        List<StudentLeaveVO> resList = list.stream().sorted(Comparator.comparing(StudentLeaveVO::getCreateTime).reversed()).collect(Collectors.toList());
        int total = processService.getTodoTotal(STUDENTLEAVE, userId);
        return getTaskTable(resList, total);
    }

    /**
     * 完成任务
     */
    @PostMapping("/complete/{taskId}/{instanceId}/{userId}")
    public AjaxResult complete(@PathVariable("taskId") String taskId,
                               @PathVariable("instanceId") String instanceId,
                               @PathVariable("userId") String userId,
                               @RequestBody Map<String, Object> variables) {

        try {
            LambdaQueryWrapper<SchoolStudentLeave> lqw = new LambdaQueryWrapper<>();
            lqw.eq(SchoolStudentLeave::getInstanceId, instanceId);
            SchoolStudentLeave leave = schoolStudentLeaveService.getOne(lqw);
            variables.put("totalTime", leave.getTotalTime());
            processService.completeWxTask(taskId, instanceId, userId, variables);
            String comment = (String) variables.get("comment");
            Boolean flag = Boolean.parseBoolean(variables.get("pass").toString());
            ProcessInstance rpi = runtimeService
                    .createProcessInstanceQuery()//创建流程实例查询对象
                    .processInstanceId(instanceId)
                    .singleResult();
            //说明流程实例结束了
            /*if (leave.getTotalTime()<=3){
                leave.setState(OVER);
            }*/
            schoolStudentLeaveService.updateById(leave);
            if (rpi == null) {
                if (flag) {
                    leave.setState(PASS);
                } else {
                    leave.setState(REFUSE);
                }
                schoolStudentLeaveService.updateById(leave);
                //请假结果模板消息~微信少了销假？正常的话，销假会有自己的接口，能进到这一步，一般是班主任或者级部主任驳回了请假申请
                LeaveResultTemplate resultTemplate = new LeaveResultTemplate();
                resultTemplate.setFirst("您好，"+ leave.getStudentName() + "同学的请假申请已回复");
                resultTemplate.setResult("已驳回");
                resultTemplate.setRemark("审批留言： "+ comment);
                SchoolStudentParent parent = schoolStudentParentService.getById(leave.getApplyUserId());
                //获取请假申请人openId
                //String openId = userService.getOpenIdByUserId(parent.getUserId());
                String openId = schoolStudentParentService.getOpenIdById(leave.getApplyUserId());
                resultTemplate.setToUserOpenId(openId);
                List<HistoricActivity> list = processService.selectHistoryList(instanceId,new HistoricActivity());
                if(StringUtils.isNotNull(list) && list.size() > 0){
                    HistoricActivity activity = list.get(0);
                    resultTemplate.setAuditTime(activity.getEndTime());
                }
                wxApiService.sendLeaveResultTemplate(resultTemplate);
                return AjaxResult.success("审批完成");

            }

            /** 发送申请通知 */
            StudentLeaveTemplate template = new StudentLeaveTemplate();
            String openId = "";
            template.setType(leave.getType());
            template.setReasonForLeave(leave.getLeaveReason());
            template.setStudentName(leave.getStudentName());
            SchoolStudent ss = schoolStudentService.getById(leave.getStudentId());
            SchoolClass sc = classService.getById(ss.getClassId());
            template.setClassName(sc.getClassAlias());
            template.setLeaveStartTime(leave.getStartTime());
            template.setLeaveEndTime(leave.getEndTime());
            //流程没结束，目前已到分管领导或主要领导
            List<Task> taskList = taskService.createTaskQuery()
                    .processInstanceId(leave.getInstanceId())
                    .list();    // 例如请假会签，会同时拥有多个任务
            if (!CollectionUtils.isEmpty(taskList)) {
                TaskEntityImpl task = (TaskEntityImpl) taskList.get(0);

                //级部主任审批
                if(JIBU.equals(task.getName())){
                    template.setFirst("您好，您有请假申请等待审批。");
                    //openId = userService.getOpenIdByUserId(leave.getHandUserId2());
                    openId = teacherService.getOpenIdByUserId(leave.getHandUserId2());
                }
                //等待班主任销假
                if(XIAOJIA.equals(task.getName())){
                    template.setFirst("您好，您有请假申请等待销假。");
                    //openId = userService.getOpenIdByUserId(leave.getHandUserId());
                    openId = teacherService.getOpenIdByUserId(leave.getHandUserId());
                }
            }
            template.setToUserOpenId(openId);
            return AjaxResult.success(wxApiService.sendStudentLeaveTemplate(template));
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new ServiceException("完成任务失败");
        }
    }

    /**
     * @author lyric
     * @date 2022/10/28 10:18
     * 销假
     */
    @PostMapping("/cancelLeave/{taskId}")
    public AjaxResult cancelLeave(@PathVariable("taskId") String taskId, @RequestBody SchoolStudentLeave schoolStudentLeave) {
        schoolStudentLeaveService.cancelLeave(taskId, schoolStudentLeave);
        return AjaxResult.success();
    }

    /**
     * 班主任销假
     * 需要传入返校日期revokeTime
     * 正在用
     * */
    @PostMapping("/cancel/{taskId}/{instanceId}")
    public AjaxResult cancel(@PathVariable("taskId") String taskId, @PathVariable("instanceId") String instanceId,  @RequestBody SchoolStudentLeave schoolStudentLeave) {
        if(StringUtils.isNull(schoolStudentLeave.getRevokeTime())){
            throw new ServiceException("销假时间为空");
        }
        schoolStudentLeaveService.cancel(taskId,instanceId, schoolStudentLeave);
        LambdaQueryWrapper<SchoolStudentLeave> lqw = new LambdaQueryWrapper<>();
        lqw.eq(SchoolStudentLeave::getInstanceId, instanceId);
        SchoolStudentLeave leave = schoolStudentLeaveService.getOne(lqw);
        LeaveResultTemplate resultTemplate = new LeaveResultTemplate();
        resultTemplate.setFirst("您好，"+ leave.getStudentName() + "同学的销假申请已回复");
        resultTemplate.setResult("已销假");
        resultTemplate.setRemark(leave.getStudentName() + "同学已返校");
        SchoolStudentParent parent = schoolStudentParentService.getById(leave.getApplyUserId());
        //获取请假申请人openId
        //String openId = userService.getOpenIdByUserId(parent.getUserId());
        String openId = schoolStudentParentService.getOpenIdById(leave.getApplyUserId());
        resultTemplate.setToUserOpenId(openId);
        List<HistoricActivity> list = processService.selectHistoryList(instanceId,new HistoricActivity());
        if(StringUtils.isNotNull(list) && list.size() > 0){
            HistoricActivity activity = list.get(0);
            resultTemplate.setAuditTime(activity.getEndTime());
        }
        wxApiService.sendLeaveResultTemplate(resultTemplate);
        return AjaxResult.success("销假完成");
    }


    /**
     * 学生请假 --> 我的已办列表
     */
    @GetMapping("/taskDoneList/{userId}")
    public TableDataInfo studentTaskDoneList(@PathVariable("userId") String userId, SchoolStudentLeave entity) {
        List<StudentLeaveVO> list = schoolStudentLeaveService.findDoneTasks(STUDENTLEAVE, entity, userId);
        int total = processService.getDoneTotal(STUDENTLEAVE, userId);
        return getTaskTable(list, total);
    }


    /**
     * 学生请假列表，传studentId该列表只查询当前登录学生个人请假列表
     */
    @GetMapping("/list/{studentId}")
    public TableDataInfo list(String submitState, StudentLeaveVO studentLeave, @PathVariable Long studentId) {
        studentLeave.setStudentId(studentId);
        startPage();
        List<StudentLeaveVO> list = schoolStudentLeaveService.queryList(submitState, studentLeave);
        return getDataTable(list);
    }



    /**
     * 查询详情
     *
     * @param id
     * @return
     */
    @GetMapping("/queryOne/{id}")
    public AjaxResult queryOne(@PathVariable("id") Long id) {
        SchoolStudentLeave leave = schoolStudentLeaveService.getById(id);
        StudentLeaveVO vo = new StudentLeaveVO();
        BeanUtils.copyProperties(leave, vo);
        //设置标题
        String title = "";
        if (leave.getType().equals(THINGNUM)) {
            title += THING;
        } else if (leave.getType().equals(ILLNESSNUM)) {
            title += ILLNESS;
        } else if (leave.getType().equals(OTHERNUM)) {
            title += OTHER;
        }
        title = title + "-" + leave.getClassName() + "-" + leave.getStudentName();
        vo.setTitle(title);
        //获取家长手机号
        Long parentId = leave.getApplyUserId();
        SchoolStudentParent parent = schoolStudentParentService.getById(parentId);
        vo.setParentTel(parent.getTelephone());
        vo.setRelationship(parent.getRelationship());
        return AjaxResult.success(vo);
    }



    /**
     * 新增页面的暂存
     */
    @PostMapping("/add")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult add(@RequestBody @Validated SchoolStudentLeave schoolStudentLeave) {
        schoolStudentLeaveService.judgeHandUser(schoolStudentLeave);
        schoolStudentLeave.setApplyUserId(userInfoUtil.getParentId());
        schoolStudentLeave.setApplyUser(userInfoUtil.getParentName());
        schoolStudentLeave.setState(SAVE);
        return toAjax(schoolStudentLeaveService.save(schoolStudentLeave));
    }

    /**
     * 新增页面的提交
     */
    @PostMapping("/submit")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult submit(@RequestBody @Validated SchoolStudentLeave schoolStudentLeave) {
        schoolStudentLeaveService.judgeHandUser(schoolStudentLeave);
        schoolStudentLeave.setState(SAVE);
        schoolStudentLeave.setApplyUserId(userInfoUtil.getParentId());
        schoolStudentLeave.setApplyUser(userInfoUtil.getParentName());
        schoolStudentLeaveService.save(schoolStudentLeave);
        AjaxResult ajax = submission(schoolStudentLeave.getId());
        return ajax;
    }


    /**
     * 提交申请
     */
    @PostMapping("/submitApply/{id}")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult submitApply(@PathVariable("id") Long id) {
        AjaxResult ajax = submission(id);
        return ajax;
    }

    @DeleteMapping("/delete/{ids}")
    public AjaxResult delete(@PathVariable("ids") List<Long> ids) {
        return toAjax(schoolStudentLeaveService.removeByIds(ids));
    }

    /**
     * 学生请假时获取班主任，级部主任信息
     * @return
     */
    @GetMapping("/getInfo")
    public  AjaxResult getInfo(){
        Long studentId = userInfoUtil.getStudentId();
        return AjaxResult.success(schoolStudentLeaveService.getInfo(studentId));
    }

    public AjaxResult submission(Long id) {
        SchoolStudentLeave schoolStudentLeave = schoolStudentLeaveService.getById(id);
        if (StringUtils.isNull(schoolStudentLeave)) {
            throw new ServiceException("提交申请失败,未查询到相关信息");
        }
//        String applyUser = schoolStudentLeave.getStudentName();
        String applyUser = userInfoUtil.getParentName();
        schoolStudentLeave.setApplyTime(DateUtils.getNowDate());
        schoolStudentLeaveService.submitApply(schoolStudentLeave, applyUser, STUDENTLEAVE, new HashMap<>());

        /** 提交请假模板消息 */
       /* LeaveTemplate leaveTemplate = new LeaveTemplate();
        String openId = userService.getOpenIdByUserId(schoolStudentLeave.getHandUserId());
        leaveTemplate.setToUserOpenId(openId);
        leaveTemplate.setIdentity(0);
        leaveTemplate.setLeaveStartTime(schoolStudentLeave.getStartTime());
        leaveTemplate.setLeaveEndTime(schoolStudentLeave.getEndTime());
        leaveTemplate.setUserName(schoolStudentLeave.getStudentName());
        return AjaxResult.success(wxApiService.sendTemplate(leaveTemplate));*/
        StudentLeaveTemplate template = new StudentLeaveTemplate();
        template.setFirst("您好，您有请假申请等待审批。");
        //获取班主任userId
        //SchoolStudentParent parent = schoolStudentParentService.getById(schoolStudentLeave.getApplyUserId());
        //String openId = userService.getOpenIdByUserId(schoolStudentLeave.getHandUserId());
        String openId = teacherService.getOpenIdByUserId(schoolStudentLeave.getHandUserId());
        template.setToUserOpenId(openId);
        template.setType(schoolStudentLeave.getType());
        template.setReasonForLeave(schoolStudentLeave.getLeaveReason());
        template.setStudentName(schoolStudentLeave.getStudentName());
        SchoolStudent ss = schoolStudentService.getById(schoolStudentLeave.getStudentId());
        SchoolClass sc = classService.getById(ss.getClassId());
        template.setClassName(sc.getClassAlias());
        template.setLeaveStartTime(schoolStudentLeave.getStartTime());
        template.setLeaveEndTime(schoolStudentLeave.getEndTime());
        return AjaxResult.success(wxApiService.sendStudentLeaveTemplate(template));
    }

    /**
     * 获取学生请假天数
     * @return 请假天数(保留两位小数)
     */
    @GetMapping("/getTotalDay")
    public AjaxResult getTotalDay(String startTime, String endTime) throws ParseException {
        DateFormat df=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date start = df.parse(startTime);
        Date end = df.parse(endTime);
        Double value = Double.valueOf(end.getTime() - start.getTime());
        DecimalFormat f = new DecimalFormat("#0.00");
        return AjaxResult.success("totalDay",f.format(value/(1000 * 3600 * 24)));
    }

}
