package com.jpsoft.shinestar.modules.mobile.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.github.pagehelper.Page;
import com.jpsoft.shinestar.config.WxConfig;
import com.jpsoft.shinestar.modules.base.dto.ApprovalDTO;
import com.jpsoft.shinestar.modules.base.dto.BusinessOutDTO;
import com.jpsoft.shinestar.modules.base.dto.WorkAttendanceDTO;
import com.jpsoft.shinestar.modules.base.dto.WorkDTO;
import com.jpsoft.shinestar.modules.base.entity.*;
import com.jpsoft.shinestar.modules.base.service.*;
import com.jpsoft.shinestar.modules.business.entity.FillAttendance;
import com.jpsoft.shinestar.modules.business.entity.WorkAttendance;
import com.jpsoft.shinestar.modules.common.dto.MessageResult;
import com.jpsoft.shinestar.modules.common.dto.Sort;
import com.jpsoft.shinestar.modules.common.utils.*;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.codehaus.jackson.map.BeanProperty;
import org.joda.time.DateTime;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import java.util.*;

/**
 * @author 墨鱼_mo
 * @date 2020-11-20 11:16
 */
@RestController
@RequestMapping("/mobile/businessOutApiController")
@Slf4j
public class BusinessOutApiController {

    @Value("${jwt.secret}")
    private String jwtSecret;

    @Autowired
    private PersonInfoService personInfoService;

    @Autowired
    private PersonPopedomService personPopedomService;

    @Autowired
    private BusinessOutService businessOutService;

    @Autowired
    private WxConfig wxConfig;

    @Autowired
    private ApplicationExamineService applicationExamineService;

    @Autowired
    private CompanyInfoService companyInfoService;


    @ApiOperation(value = "外出出差数据提交")
    @RequestMapping(value = "submitBusiness", method = RequestMethod.POST)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "token", value = "令牌", required = true, paramType = "form"),
            @ApiImplicitParam(name = "subject", value = "目标(不传)", paramType = "form"),
            @ApiImplicitParam(name = "type", value = "类型（1：外出，3：出差）", required = true, paramType = "form"),
            @ApiImplicitParam(name = "destination", value = "目的地", required = true, paramType = "form"),
            @ApiImplicitParam(name = "startTime", value = "开始时间", required = true, paramType = "form"),
            @ApiImplicitParam(name = "endTime", value = "结束时间", required = true, paramType = "form"),
            @ApiImplicitParam(name = "days", value = "天数", required = true, paramType = "form"),
            @ApiImplicitParam(name = "estimatedTime", value = "预估时间", required = true, paramType = "form"),
            @ApiImplicitParam(name = "content", value = "事由", required = true, paramType = "form"),
            @ApiImplicitParam(name = "formId", value = "页面路径", required = true, paramType = "form"),
            @ApiImplicitParam(name = "draft", value = "状态（0：草稿，1：提交）", required = true, paramType = "form")
    })
    public MessageResult<Map> submitBusiness(String ids,String draft,String type, String destination, String startTime, String endTime,String days,String estimatedTime, String content,String formId,@RequestAttribute String subject, String token) {
        MessageResult<Map> msgResult = new MessageResult<>();

        try {
            //查询操作人
            PersonInfo personInfo = personInfoService.get(Long.valueOf(subject));
            if (personInfo == null) {
                throw new Exception("申请人不存在");
            }

            //申请人角色
            PersonPopedom personPopedom = personPopedomService.get(personInfo.getPopedom());

            List<BusinessOut> businessOuts = businessOutService.findByPersonPopedomAndEndTimeIsNull(personPopedom.getId());

            if (businessOuts.size() > 0) {
                throw new Exception("您有一条正在进行的出差记录，不可再次提交");
            }

            if ("4".equals(personInfo.getWorkStatus())){
                throw new Exception("休假状态无法出差");
            }

            String id = businessOutService.submitBusiness(personPopedom,type,destination,startTime,endTime,days,estimatedTime,content,formId,ids,draft);


            Map<String, Object> map = new HashMap<>();
            map.put("id", id);
            msgResult.setData(map);
            msgResult.setCode(200);
            msgResult.setResult(true);


        } catch (Exception ex) {
            log.error(ex.getMessage(), ex);
            msgResult.setCode(400);
            msgResult.setResult(false);
            msgResult.setMessage(ex.getMessage());
        }

        return msgResult;
    }

    @ApiOperation(value = "外出出差数据详情")
    @RequestMapping(value = "businessOutDetail", method = RequestMethod.POST)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "token", value = "令牌", required = true, paramType = "form"),
            @ApiImplicitParam(name = "subject", value = "目标(不传)", paramType = "form"),
            @ApiImplicitParam(name = "id", value = "id", required = true, paramType = "form")
    })
    public MessageResult<BusinessOutDTO> businessOutDetail(@RequestAttribute String subject, String token, String id) {
        MessageResult<BusinessOutDTO> msgResult = new MessageResult<>();

        try {
            //查询操作人
            /*PersonInfo personInfo = personInfoService.get(Long.valueOf(subject));
            if (personInfo == null) {
                throw new Exception("申请人不存在");
            }*/

            PersonInfo person = personInfoService.get(Long.valueOf(subject));
            PersonPopedom personPopedom0 = personPopedomService.get(person.getPopedom());

            BusinessOut businessOut = businessOutService.get(id);
            //申请人角色
            PersonPopedom personPopedom = personPopedomService.get(businessOut.getPersonPopedomId());
            PersonInfo personInfo = personInfoService.get(personPopedom.getPersonId());
            //审核人
            PersonPopedom approvalPersonPopedom = personPopedomService.get(businessOut.getApprovalPersonPopedomId());

            PersonInfo approvalPersonInfo = null;
            if (approvalPersonPopedom != null) {
                approvalPersonInfo = personInfoService.get(approvalPersonPopedom.getPersonId());
            }


            //申请人公司
            CompanyInfo companyInfo = companyInfoService.get(personPopedom.getCompanyId());


            BusinessOutDTO businessOutDTO = new BusinessOutDTO();
            businessOutDTO.setPersonName(personInfo.getName());
            businessOutDTO.setFaceImageUrl(personInfo.getFaceImageUrl());
            businessOutDTO.setTypeN(businessOut.getTypeN());
            businessOutDTO.setType(businessOut.getType());
            businessOutDTO.setStatus(businessOut.getStatus());
            businessOutDTO.setStatusN(TypeNameUtil.getExamineTypeName(businessOut.getStatus()));
            businessOutDTO.setCompanyName(companyInfo.getName());
            businessOutDTO.setDestination(businessOut.getDestination());
            businessOutDTO.setStartTime(DateUtil.format(businessOut.getStartTime(), "yyyy-MM-dd HH:mm"));
            businessOutDTO.setEstimatedTime(businessOut.getEstimatedTime());
            businessOutDTO.setContent(businessOut.getContent());
            businessOutDTO.setApprovalNo(businessOut.getApprovalNo());
            businessOutDTO.setCreateTime(DateUtil.format(businessOut.getCreateTime(), "yyyy-MM-dd HH:mm"));
            businessOutDTO.setEndTime(DateUtil.format(businessOut.getEndTime(), "yyyy-MM-dd HH:mm"));
            businessOutDTO.setWorkReport(businessOut.getWorkReport());

            msgResult.setData(businessOutDTO);
            msgResult.setCode(200);
            msgResult.setResult(true);


        } catch (Exception ex) {
            log.error(ex.getMessage(), ex);
            msgResult.setCode(400);
            msgResult.setResult(false);
            msgResult.setMessage(ex.getMessage());
        }

        return msgResult;
    }

    @GetMapping("updatePersonWorkStatus")
    @ApiOperation(value="根据出差修改人员工作状态")
    public MessageResult<String> updatePersonWorkStatus(String id){
        MessageResult<String> messageResult = new MessageResult<>();

        try {
            BusinessOut businessOut = businessOutService.get(id);
            businessOutService.updatePersonWorkStatus(businessOut);

            //todo 填写具体代码
            messageResult.setData("根据出差修改人员工作状态");
            messageResult.setResult(true);
        }
        catch (Exception ex){
            log.error(ex.getMessage(),ex);

            messageResult.setResult(false);
            messageResult.setMessage(ex.getMessage());
        }

        return messageResult;
    }

    @ApiOperation(value = "外出出差数据审核")
    @RequestMapping(value = "businessOutApproval", method = RequestMethod.POST)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "token", value = "令牌", required = true, paramType = "form"),
            @ApiImplicitParam(name = "subject", value = "目标(不传)", paramType = "form"),
            @ApiImplicitParam(name = "ids", value = "ids", required = true, paramType = "form"),
            @ApiImplicitParam(name = "status", value = "1/2(1:同意，2：拒绝)", required = true, paramType = "form"),
            @ApiImplicitParam(name = "approvalContent", value = "审核意见", required = true, paramType = "form"),
            @ApiImplicitParam(name = "nextApprovalId", value = "下级审核人", required = false, paramType = "form"),
    })
    public MessageResult<Map> businessOutApproval(@RequestAttribute String subject, String token, String ids, String status, String approvalContent, String nextApprovalId) {
        MessageResult<Map> msgResult = new MessageResult<>();

        try {
            // 查询操作人
            PersonInfo personInfo = personInfoService.get(Long.valueOf(subject));
            if (personInfo == null) {
                throw new Exception("申请人不存在");
            }

            if (org.apache.commons.lang3.StringUtils.isNotBlank(approvalContent)){
                approvalContent = StrUtil.replace(approvalContent,",","，");
            }

            businessOutService.approvalBusinessOut(personInfo, ids, status, approvalContent, nextApprovalId);

            Map<String, Object> map = new HashMap<>();

            msgResult.setData(map);
            msgResult.setCode(200);
            msgResult.setResult(true);
        } catch (Exception ex) {
            log.error(ex.getMessage(), ex);
            msgResult.setCode(400);
            msgResult.setResult(false);
            msgResult.setMessage(ex.getMessage());
        }

        return msgResult;
    }

    @ApiOperation(value = "外出出差获取审核人")
    @RequestMapping(value = "getBusinessOutApprovalPerson", method = RequestMethod.POST)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "token", value = "令牌", required = true, paramType = "form"),
            @ApiImplicitParam(name = "subject", value = "目标(不传)", paramType = "form"),
            @ApiImplicitParam(name = "type", value = "1:外出，2：休假，3：出差", required = true, paramType = "form"),
            @ApiImplicitParam(name = "level", value = "级别", required = false, paramType = "form"),
            @ApiImplicitParam(name = "days", value = "天数", required = false, paramType = "form")
    })
    public MessageResult<Map> getBusinessOutApprovalPerson(@RequestAttribute String subject, String token, String type, String level, String days) {
        MessageResult<Map> msgResult = new MessageResult<>();

        try {
            // 查询操作人
            PersonInfo personInfo = personInfoService.get(Long.valueOf(subject));
            if (personInfo == null) {
                throw new Exception("申请人不存在");
            }

            PersonPopedom personPopedom = personPopedomService.get(personInfo.getPopedom());

            Map<String, Object> searchParams = new HashMap<>();
            searchParams.put("type", type);
            if (org.apache.commons.lang3.StringUtils.isBlank(level)) {
                level = "1";
            }
            searchParams.put("level", Integer.parseInt(level));
            searchParams.put("applicationRoleId", personPopedom.getPersonRoleId());
            searchParams.put("applicationCompanyId", personPopedom.getCompanyId());

            List<Sort> sortList = new ArrayList<>();
            sortList.add(new Sort("a.create_time", "desc"));
            Page<ApplicationExamine> page = applicationExamineService.pageSearch(searchParams, 1, 1, false, sortList);

            List<ApplicationExamine> list = page.getResult();

            List<PersonPopedom> popedomList = new ArrayList<>();
            if (list.size() > 0) {
                ApplicationExamine applicationExamine = list.get(0);
                List<PersonPopedom> personPopedomList = personPopedomService.findByCompanyIdAndRoleIds(applicationExamine.getExamineCompanyId(), applicationExamine.getExamineRoleId());
                if (personPopedomList.size() > 0) {
                    for (PersonPopedom personPopedom1 : personPopedomList) {
                        PersonInfo personInfo1 = personInfoService.get(personPopedom1.getPersonId());
                        if (personInfo1 != null) {
                            PersonPopedom personPopedom2 = new PersonPopedom();
                            BeanUtils.copyProperties(personPopedom1, personPopedom2);
                            personPopedom2.setPersonName(personInfo1.getName());
                            popedomList.add(personPopedom2);
                        }

                    }
                }
            }


            Map<String, Object> map = new HashMap<>();

            map.put("list", popedomList);

            msgResult.setData(map);
            msgResult.setCode(200);
            msgResult.setResult(true);


        } catch (Exception ex) {
            log.error(ex.getMessage(), ex);
            msgResult.setCode(400);
            msgResult.setResult(false);
            msgResult.setMessage(ex.getMessage());
        }

        return msgResult;
    }


    @ApiOperation(value = "外出出差个人列表")
    @RequestMapping(value = "businessOutApprovalPersonList", method = RequestMethod.POST)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "token", value = "令牌", required = true, paramType = "form"),
            @ApiImplicitParam(name = "subject", value = "目标(不传)", paramType = "form"),
            @ApiImplicitParam(name = "type", value = "1:外出，2：休假，3：出差", required = true, paramType = "form"),
            @ApiImplicitParam(name = "status", value = "0:未处理，1：已处理", required = false, paramType = "form")
    })
    public MessageResult<Map> businessOutApprovalPersonList(@RequestAttribute String subject, String token, String type, String status, @RequestParam(value = "pageIndex", defaultValue = "1") int pageIndex, @RequestParam(value = "pageSize", defaultValue = "20") int pageSize) {
        MessageResult<Map> msgResult = new MessageResult<>();

        try {
            // 查询操作人
            PersonInfo personInfo = personInfoService.get(Long.valueOf(subject));
            if (personInfo == null) {
                throw new Exception("申请人不存在");
            }

            PersonPopedom personPopedom = personPopedomService.get(personInfo.getPopedom());

            Map<String, Object> searchParams = new HashMap<>();
            searchParams.put("personPopedomId", personPopedom.getId());
            searchParams.put("type", type);
            if ("0".equals(status)) {
                searchParams.put("status", status);
            }
            if ("1".equals(status)) {
                searchParams.put("notStatus", "0");
            }
            List<Sort> sortList = new ArrayList<>();
            sortList.add(new Sort("create_time", "desc"));
            Page<BusinessOut> page = businessOutService.pageSearch(searchParams, pageIndex, pageSize, true, sortList);
            List<BusinessOut> list = page.getResult();
            if (list.size() > 0) {
                for (BusinessOut businessOut : list) {
                    PersonPopedom personPopedom1 = personPopedomService.get(businessOut.getPersonPopedomId());
                    PersonInfo personInfo1 = personInfoService.get(personPopedom1.getPersonId());
                    businessOut.setPersonName(personInfo1.getName());
                }
            }


            msgResult.setData(PojoUtils.pageWrapper(page));
            msgResult.setCode(200);
            msgResult.setResult(true);


        } catch (Exception ex) {
            log.error(ex.getMessage(), ex);
            msgResult.setCode(400);
            msgResult.setResult(false);
            msgResult.setMessage(ex.getMessage());
        }

        return msgResult;
    }

    @ApiOperation(value = "外出出差审核列表")
    @RequestMapping(value = "businessOutApprovalList", method = RequestMethod.POST)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "token", value = "令牌", required = true, paramType = "form"),
            @ApiImplicitParam(name = "subject", value = "目标(不传)", paramType = "form"),
            @ApiImplicitParam(name = "type", value = "1:外出，2：休假，3：出差", required = true, paramType = "form"),
            @ApiImplicitParam(name = "status", value = "0:未处理，1：已处理", required = false, paramType = "form")
    })
    public MessageResult<Map> businessOutApprovalList(@RequestAttribute String subject, String token, String type, String status, @RequestParam(value = "pageIndex", defaultValue = "1") int pageIndex, @RequestParam(value = "pageSize", defaultValue = "20") int pageSize) {
        MessageResult<Map> msgResult = new MessageResult<>();

        try {
            // 查询操作人
            PersonInfo personInfo = personInfoService.get(Long.valueOf(subject));
            if (personInfo == null) {
                throw new Exception("申请人不存在");
            }

            PersonPopedom personPopedom = personPopedomService.get(personInfo.getPopedom());
            CompanyInfo companyInfo = companyInfoService.get(personPopedom.getCompanyId());

            List<CompanyInfo> companyInfoList = companyInfoService.findAllCompanyByCode("%" + companyInfo.getId() + "%");

            List<String> companyIdList = new ArrayList<>();
            if (companyInfoList.size() > 0) {
                for (CompanyInfo companyInfo1 : companyInfoList) {
                    companyIdList.add(companyInfo1.getId());
                }
            }

            Map<String, Object> searchParams = new HashMap<>();
            List<Sort> sortList = new ArrayList<>();
            if ("0".equals(status)) {
                searchParams.put("approvalPersonPopedomId", personPopedom.getId());
                sortList.add(new Sort("a.create_time", "desc"));
            }
            if ("1".equals(status)) {
                searchParams.put("inCompanyId", companyIdList);

                if (!"1".equals(type)){
                    sortList.add(new Sort("a.approval_time", "desc"));
                }
                //       sortList.add(new Sort("a.update_time", "desc"));
                //       sortList.add(new Sort("a.create_time","desc"));

            }


            if ("1".equals(type)) {

            //    sortList.add(new Sort("a.update_time", "asc"));
            //    sortList.add(new Sort("a.create_time", "desc"));
                sortList.add(new Sort("IFNULL(a.end_time,a.create_time)","desc"));

            }

            searchParams.put("type", type);
            if ("0".equals(status)) {
                searchParams.put("status", status);
            } else {
                searchParams.put("notStatus", "0");
            }


            Page<BusinessOut> page = businessOutService.pageSearch(searchParams, pageIndex, pageSize, true, sortList);
            List<BusinessOut> list = page.getResult();
            if (list.size() > 0) {
                for (BusinessOut businessOut : list) {
                    PersonPopedom personPopedom1 = personPopedomService.get(businessOut.getPersonPopedomId());
                    PersonInfo personInfo1 = personInfoService.get(personPopedom1.getPersonId());
                    if (personInfo1 != null) {
                        businessOut.setPersonName(personInfo1.getName());
                    }

                }
            }


            msgResult.setData(PojoUtils.pageWrapper(page));
            msgResult.setCode(200);
            msgResult.setResult(true);


        } catch (Exception ex) {
            log.error(ex.getMessage(), ex);
            msgResult.setCode(400);
            msgResult.setResult(false);
            msgResult.setMessage(ex.getMessage());
        }

        return msgResult;
    }


    @ApiOperation(value = "外出出差结束")
    @RequestMapping(value = "businessOutEnd", method = RequestMethod.POST)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "token", value = "令牌", required = true, paramType = "form"),
            @ApiImplicitParam(name = "subject", value = "目标(不传)", paramType = "form"),
            @ApiImplicitParam(name = "id", value = "id", required = true, paramType = "form"),
            @ApiImplicitParam(name = "workReport", value = "外出事项办理情况", required = false, paramType = "form"),
            @ApiImplicitParam(name = "time", value = "结束时间", required = true, paramType = "form")
    })
    public MessageResult<Map> businessOutEnd(@RequestAttribute String subject, String token, String id, String workReport,String time) {
        MessageResult<Map> msgResult = new MessageResult<>();

        try {
            // 查询操作人
            PersonInfo personInfo = personInfoService.get(Long.valueOf(subject));
            if (personInfo == null) {
                throw new Exception("申请人不存在");
            }

            if (org.apache.commons.lang3.StringUtils.isBlank(id)) {
                throw new Exception("详情id不存在");
            }

            PersonPopedom personPopedom = personPopedomService.get(personInfo.getPopedom());

            BusinessOut businessOut = businessOutService.get(id);


            if (businessOut != null && businessOut.getEndTime() == null) {
              //  businessOut.setEndTime(DateUtil.parse(time));
                businessOut.setEndTime(new Date());
                businessOut.setEstimatedDate(new Date());
                businessOut.setWorkReport(workReport);
                //修改个人工作状态
                personInfo.setWorkStatus("1");
                businessOutService.update(businessOut);
                personInfoService.update(personInfo);

                //只有外出才会向通知人发送消息
                if ("1".equals(businessOut.getType())) {

                    PersonPopedom personPopedom1 = personPopedomService.get(businessOut.getApprovalPersonPopedomId());
                    PersonInfo personInfo1 = personInfoService.get(personPopedom1.getPersonId());

                    //被通知人的上级
                    List<PersonPopedom> personPopedomList = personPopedomService.findApprovalList(personInfo1,null,null,null);
                    new Thread(() -> {

                        String accessToken = JwtUtil2.createToken(jwtSecret, personInfo1.getId() + "", DateTime.now().plusHours(30 * 24).toDate());
                        WechatMessageUtil.sendEvenMessage(personInfo1.getOpenId(), personInfo.getName() + "的外出归来通知", personInfo.getName(), businessOut.getId().substring(0, 5), "前往查看", wxConfig.getPortalUrl() + "master/egress/info?id=" + businessOut.getId() + "&remark=1&exchange=1&role_id=" + personPopedom1.getId() + "&token=" + accessToken, wxConfig.getAppId(), wxConfig.getAppSecret());


                        //同时通知上级
                        if (personPopedomList.size()>0){
                            PersonPopedom personPopedom2 = personPopedomList.get(0);
                            PersonInfo personInfo2 = personInfoService.get(personPopedom2.getPersonId());
                            String accessToken2 = JwtUtil2.createToken(jwtSecret, personInfo2.getId() + "", DateTime.now().plusHours(30 * 24).toDate());
                            WechatMessageUtil.sendEvenMessage(personInfo2.getOpenId(), personInfo.getName() + "的外出归来通知", personInfo.getName(), businessOut.getId().substring(0, 5), "前往查看", wxConfig.getPortalUrl() + "master/egress/info?id=" + businessOut.getId() + "&remark=1&exchange=1&role_id=" + personPopedom2.getId() + "&token=" + accessToken2, wxConfig.getAppId(), wxConfig.getAppSecret());
                        }


                    }).start();

                }
            }

            msgResult.setCode(200);
            msgResult.setResult(true);


        } catch (Exception ex) {
            log.error(ex.getMessage(), ex);
            msgResult.setCode(400);
            msgResult.setResult(false);
            msgResult.setMessage(ex.getMessage());
        }

        return msgResult;
    }

    @ApiOperation(value = "外出添加备注")
    @RequestMapping(value = "addRemarkForBusinessOut", method = RequestMethod.POST)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "token", value = "令牌", required = true, paramType = "form"),
            @ApiImplicitParam(name = "subject", value = "目标(不传)", paramType = "form"),
            @ApiImplicitParam(name = "id", value = "id", required = true, paramType = "form"),
            @ApiImplicitParam(name = "remark", value = "备注", required = true, paramType = "form")
    })
    public MessageResult<Map> addRemarkForBusinessOut(@RequestAttribute String subject, String token, String id, String remark) {

        MessageResult<Map> messageResult = new MessageResult<>();
        try {

            BusinessOut businessOut = businessOutService.get(id);
            if (businessOut != null) {
                businessOut.setRemark(remark);
                businessOut.setUpdateTime(new Date());
                businessOutService.update(businessOut);
            }

            messageResult.setCode(200);
            messageResult.setResult(true);


        } catch (Exception ex) {

            log.error(ex.getMessage(), ex);
            messageResult.setCode(400);
            messageResult.setResult(false);
        }
        return messageResult;

    }


}
