package yangtz.cs.liu.campus.controller.teacher;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.core.utils.HolidayDateUtil;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SchoolTeacher;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.service.ISysUserService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.impl.persistence.entity.TaskEntityImpl;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.spring.integration.Activiti;
import org.apache.commons.lang3.time.DateFormatUtils;
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.teacher.SchoolTeacherLeave;
import yangtz.cs.liu.campus.domain.temp.LeaveResultTemplate;
import yangtz.cs.liu.campus.domain.temp.TeacherLeaveTemplate;
import yangtz.cs.liu.campus.service.schoolgrade.ISchoolGradeMentorService;
import yangtz.cs.liu.campus.service.teacher.ISchoolTeacherLeaveService;
import yangtz.cs.liu.campus.service.teacher.ISchoolTeacherService;
import yangtz.cs.liu.campus.service.workDay.ISchoolWorkDayService;
import yangtz.cs.liu.campus.vo.teacher.SchoolTeacherLeaveVO;
import yangtz.cs.liu.campus.vo.teacher.SchoolTeacherVO;
import yangtz.cs.liu.campus.vo.teacher.TeacherLeaveVO;
import yangtz.cs.liu.wechat.domain.template.LeaveStateTemplate;
import yangtz.cs.liu.wechat.domain.template.LeaveTemplate;
import yangtz.cs.liu.wechat.service.api.IWxApiService;

import javax.servlet.http.HttpServletResponse;
import java.util.*;

import static com.core.constant.ProcessDefinition.TEACHERLEAVE;
import static com.ruoyi.common.utils.SecurityUtils.getLoginUser;
import static yangtz.cs.liu.campus.constant.EmployeeType.TEACH;
import static yangtz.cs.liu.campus.constant.GradeConstant.*;
import static yangtz.cs.liu.campus.constant.ProcessState.*;
import static yangtz.cs.liu.campus.constant.WorkTime.*;

/**
 * 学校老师请假Controller
 *
 * @author ruoyi
 * @date 2022-09-27
 */
@RestController
@RequestMapping("/school/teacherLeave")
public class SchoolTeacherLeaveController extends BaseController {

    @Autowired
    private ISchoolTeacherLeaveService schoolTeacherLeaveService;

    @Autowired
    private ISchoolTeacherService schoolTeacherService;

    @Autowired
    private ISchoolGradeMentorService gradeMentorService;

    @Autowired
    private ISchoolWorkDayService dayService;

    @Autowired
    private IProcessService processService;

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private ISysUserService userService;

    @Autowired
    private IWxApiService wxApiService;

    @Autowired
    private TaskService taskService;

    //职工
    private static final String TYPE = "1";

    /**
     * 个人工作》请假申请列表
     */
    @GetMapping("/list")
    public TableDataInfo list(@RequestParam("submitState") String submitState, SchoolTeacherLeave schoolTeacherLeave) {
        //schoolTeacherLeave.setApplyUserId(getUserId());
        schoolTeacherLeave.setTeacherId(getUserId());
        startPage();
        List<TeacherLeaveVO> list = schoolTeacherLeaveService.selectSchoolTeacherLeaveList(submitState, schoolTeacherLeave);
        return getDataTable(list);
    }

    /**
     * 教职工信息汇总（请假申请通过的数据）
     */
    @GetMapping("/getList")
    public TableDataInfo getList(SchoolTeacherLeave schoolTeacherLeave) {
        startPage();
        List<TeacherLeaveVO> list = schoolTeacherLeaveService.getList(schoolTeacherLeave);
        return getDataTable(list);
    }

    /**
     * 查询详情
     *
     * @param id
     * @return
     */
    @GetMapping("/queryOne/{id}")
    public AjaxResult queryOne(@PathVariable("id") Long id) {
        SchoolTeacherLeave leave = schoolTeacherLeaveService.getById(id);
        TeacherLeaveVO vo = new TeacherLeaveVO();
        BeanUtils.copyProperties(leave, vo);
        if(!leave.getApplyType().equals(TYPE)){
            String dayCourse = HolidayDateUtil.dayCourse(leave.getTotalTime());
            vo.setDayCourse(dayCourse);
        }
        return AjaxResult.success(vo);
    }

    /**
     * 新增
     *
     * @param schoolTeacherLeave
     * @return
     */
    @PostMapping("/add")
    public AjaxResult add(@RequestBody @Validated SchoolTeacherLeave schoolTeacherLeave) {
        schoolTeacherLeave.setApplyType(getLoginUser().getUser().getEmployeeType());
        schoolTeacherLeave.setState(SAVE);
        schoolTeacherLeave.setApplyUserId(getUserId());
        schoolTeacherLeave.setApplyUser(getUsername());
        schoolTeacherLeaveService.judgeDate(schoolTeacherLeave);
        schoolTeacherLeaveService.judgeHandUser(schoolTeacherLeave);
       /* if(schoolTeacherLeave.getApplyType().equals(TEACH)){
            SchoolTeacherLeaveVO vo = new SchoolTeacherLeaveVO();
            BeanUtils.copyProperties(schoolTeacherLeave,vo);

        }*/
        return toAjax(schoolTeacherLeaveService.save(schoolTeacherLeave));
    }

    /**
     * 修改
     *
     * @param schoolTeacherLeave
     * @return
     */
    @PutMapping("/edit")
    public AjaxResult edit(@RequestBody @Validated SchoolTeacherLeave schoolTeacherLeave) {
        if (StringUtils.isNull(schoolTeacherLeave.getId())) {
            return AjaxResult.error("老师请假id未传");
        }
        schoolTeacherLeaveService.judgeDate(schoolTeacherLeave);
        schoolTeacherLeaveService.judgeHandUser(schoolTeacherLeave);
        //return toAjax(schoolTeacherLeaveService.updateById(schoolTeacherLeave));
        return toAjax(schoolTeacherLeaveService.editLeave(schoolTeacherLeave));
    }

    /**
     * 删除
     *
     * @param ids
     * @return
     */
    @DeleteMapping("/delete/{ids}")
    public AjaxResult delete(@PathVariable("ids") List<Long> ids) {
        return toAjax(schoolTeacherLeaveService.removeByIds(ids));
    }

    /**
     * 导出
     *
     * @param ids
     * @return
     */
    @PostMapping("/export/{ids}")
    public void export(HttpServletResponse response, @PathVariable("ids") List<Long> ids) {
        List<SchoolTeacherLeave> list = schoolTeacherLeaveService.listByIds(ids);
        ExcelUtil<SchoolTeacherLeave> util = new ExcelUtil<>(SchoolTeacherLeave.class);
        util.exportExcel(response, list, "老师请假信息");
    }

    //导出全部
    @PostMapping("/export")
    public void exportAll(HttpServletResponse response, SchoolTeacherLeave schoolTeacherLeave) {
        LambdaQueryWrapper<SchoolTeacherLeave> lqw = new LambdaQueryWrapper<>();
        lqw
                .orderByDesc(SchoolTeacherLeave::getCreateTime)
        ;
        List<SchoolTeacherLeave> list = schoolTeacherLeaveService.list(lqw);
        ExcelUtil<SchoolTeacherLeave> util = new ExcelUtil<>(SchoolTeacherLeave.class);
        util.exportExcel(response, list, "老师请假信息");
    }

    /**
     * 提交申请
     */
    @PostMapping("/submitApply/{id}")
    public AjaxResult submitApply(@PathVariable("id") Long id) {
        SchoolTeacherLeave schoolTeacherLeave = schoolTeacherLeaveService.getById(id);
        if (StringUtils.isNull(schoolTeacherLeave)) {
            throw new ServiceException("提交申请失败,未查询到相关信息");
        }

        String userName = getUsername();
        schoolTeacherLeave.setApplyTime(DateUtils.getNowDate());
        schoolTeacherLeaveService.submitApply(schoolTeacherLeave, userName, TEACHERLEAVE, new HashMap<>());

        /** 发送申请通知 */
        TeacherLeaveTemplate template = new TeacherLeaveTemplate();
        //String openId = userService.getOpenIdByUserId(schoolTeacherLeave.getHandUserId1());
        String openId = schoolTeacherService.getOpenIdByUserId(schoolTeacherLeave.getHandUserId1());
        template.setUserType(schoolTeacherLeave.getApplyType());
        template.setToUserOpenId(openId);
        //template.setReasonForLeave(schoolTeacherLeave.getReasonForLeave());
        template.setType(schoolTeacherLeave.getType());
        template.setLeaveStartTime(schoolTeacherLeave.getStartTime());
        template.setLeaveEndTime(schoolTeacherLeave.getEndTime());
        template.setStartSort(schoolTeacherLeave.getStartSort());
        template.setEndSort(schoolTeacherLeave.getEndSort());
        template.setUserName(schoolTeacherLeave.getTeacherName());
        wxApiService.sendTeacherLeaveTemplate(template);
        return AjaxResult.success("提交成功");
    }

    /**
     * 待办事项列表
     */
    @GetMapping("/taskList")
    public TableDataInfo taskList(SchoolTeacherLeave entity) {
        String userId = getUserId().toString();
        List<TeacherLeaveVO> list = schoolTeacherLeaveService.findTodoTasks(TEACHERLEAVE, entity, userId);
        //int total = processService.getTodoTotal(TEACHERLEAVE, userId);
        return getTaskTable(list, list.size());
    }

    /**
     * 完成任务
     */
    @PostMapping("/complete/{taskId}/{instanceId}")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult complete(@PathVariable("taskId") String taskId, @PathVariable("instanceId") String instanceId, @RequestBody Map<String, Object> variables) {
        LambdaQueryWrapper<SchoolTeacherLeave> lqw = new LambdaQueryWrapper<>();
        lqw.eq(SchoolTeacherLeave::getInstanceId, instanceId);
        SchoolTeacherLeave leave = schoolTeacherLeaveService.getOne(lqw);
        //获取请假总时长
        variables.put("totalTime",leave.getTotalTime());
        /** 完成任务 */
        processService.completeTask(taskId, instanceId, variables);
        String comment = (String) variables.get("comment");
        Boolean flag = Boolean.parseBoolean(variables.get("pass").toString());
        //Boolean flag = (boolean)variables.get("pass");

        /**判断流程是否结束,如果结束则更新教师请假状态*/
        ProcessInstance rpi = runtimeService
                .createProcessInstanceQuery()//创建流程实例查询对象
                .processInstanceId(instanceId)
                .singleResult();
        //说明流程实例结束了
        if(rpi==null){
            if(flag){
                leave.setState(PASS);
            }else {
                leave.setState(REFUSE);
            }
            /** 修改任务结果 */
            schoolTeacherLeaveService.updateById(leave);

            //请假结果模板消息
            LeaveResultTemplate resultTemplate = new LeaveResultTemplate();
            resultTemplate.setFirst("您好，您的请假申请已回复。");
            resultTemplate.setResult(flag ? "已批准 ": "已驳回");
            resultTemplate.setRemark("审批留言： "+comment);
            //获取请假教师openId
            //String openId = userService.getOpenIdByUserId(leave.getTeacherId());
            String openId = schoolTeacherService.getOpenIdByUserId(leave.getTeacherId());
            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("审批完成");
        }

        /** 发送申请通知 */
        TeacherLeaveTemplate template = new TeacherLeaveTemplate();
        String openId = "";
        template.setUserType(leave.getApplyType());
        //template.setReasonForLeave(schoolTeacherLeave.getReasonForLeave());
        template.setType(leave.getType());
        template.setLeaveStartTime(leave.getStartTime());
        template.setLeaveEndTime(leave.getEndTime());
        template.setStartSort(leave.getStartSort());
        template.setEndSort(leave.getEndSort());
        template.setUserName(leave.getTeacherName());

        //流程没结束，目前已到分管领导或主要领导
        List<Task> taskList = taskService.createTaskQuery()
                .processInstanceId(leave.getInstanceId())
                .list();    // 例如请假会签，会同时拥有多个任务
        if (!CollectionUtils.isEmpty(taskList)) {
            TaskEntityImpl task = (TaskEntityImpl) taskList.get(0);

            //分管领导
            if(FENGUAN.equals(task.getName())){
                //openId = userService.getOpenIdByUserId(leave.getHandUserId2());
                openId = schoolTeacherService.getOpenIdByUserId(leave.getHandUserId2());
            }
            //主要
            if(ZHUYAO.equals(task.getName())){
                //openId = userService.getOpenIdByUserId(leave.getHandUserId3());
                openId = schoolTeacherService.getOpenIdByUserId(leave.getHandUserId3());
            }
        }

        template.setToUserOpenId(openId);
        wxApiService.sendTeacherLeaveTemplate(template);
        return AjaxResult.success("审批完成");
    }

    /**
     * 我的已办列表
     */
    @GetMapping("/taskDoneList")
    public TableDataInfo taskDoneList(SchoolTeacherLeave entity) {
        String userId = getUserId().toString();
        List<TeacherLeaveVO> list = schoolTeacherLeaveService.findDoneTasks(TEACHERLEAVE, entity, userId);
        //int total = processService.getDoneTotal(TEACHERLEAVE, userId);
        return getTaskTable(list,list.size());
    }

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

    /**
     * 获取级部主任或处室主任，传已选级部或处室
     * */
    @GetMapping("/getDeptLeader/{applyOrgid}")
    public TableDataInfo getLeader(@PathVariable Long applyOrgid,SchoolTeacherVO teacherVO) {
        //判断用户是职工还是教工，来确定传过来的id是级部id还是部门id
        String employeeType = getLoginUser().getUser().getEmployeeType();
        startPage();
        return getDataTable(schoolTeacherLeaveService.getLeader(applyOrgid,employeeType,teacherVO));
    }

    /**
     * 获取校领导
     * */
    @GetMapping("/getSchoolLeader")
    public TableDataInfo getSchoolLeader(SchoolTeacherVO teacher) {
        startPage();
        return getDataTable(schoolTeacherService.getSectionLeader(null,SCHOOLLEADER,teacher));
    }

    /**
     * 请假总时长，返回值x.x天
     * 教工传参，请假开始日期（年月日）及第几节课，结束日期及第几节课
     * 职工传参，请假开始时间，结束时间（年月日 时分秒）
     * */
    @GetMapping("/getTotalTime")
    public AjaxResult getTotalTime(SchoolTeacherLeave schoolTeacherLeave) {
        AjaxResult ajax = AjaxResult.success();
        double day = 0.0;
        //判断用户是职工还是教工，来确定传过来的id是级部id还是部门id
        //String employeeType = getLoginUser().getUser().getEmployeeType();
        if(StringUtils.isNull(schoolTeacherLeave.getApplyType())){
            throw new ServiceException("申请人类型为空");
        }
        schoolTeacherLeaveService.judgeDate(schoolTeacherLeave);

        //获取周末，节假日日期
        List<String> restList = dayService.getHolidayList(schoolTeacherLeave.getStartTime(),schoolTeacherLeave.getEndTime(),TYPE);
        //如果是教工
        if(schoolTeacherLeave.getApplyType().equals(TEACH)){
            //int courseNum = teacherLeaveDeal(schoolTeacherLeave,restList);
            int courseNum = schoolTeacherLeaveService.teacherLeaveDeal(schoolTeacherLeave,restList);
            if(courseNum < 0){
                throw new ServiceException("请假时间异常，请检查");
            }
            day = courseNum / 8.0;
            //教工显示X天Y节课
            //获取day整数部分
            String dayCourse = HolidayDateUtil.dayCourse(day);
            ajax.put("data",day);
            ajax.put("dayCourse",dayCourse);
            return ajax;
        }

        //职工
        //double hours = workerLeaveDeal(schoolTeacherLeave,restList);
        double hours = schoolTeacherLeaveService.workerLeaveDeal(schoolTeacherLeave,restList);
        if(hours < 0){
            throw new ServiceException("请假时间异常，请检查");
        }
        day = hours / 7.25;
        String d = String.format("%.3f", day);
        return AjaxResult.success().put("data",d);
    }
}
