package org.enfi.modules.visitor.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.exceptions.ClientException;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import com.jfinal.weixin.sdk.api.ApiResult;
import com.jfinal.wxaapp.api.WxaUserApi;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.enfi.common.api.vo.Result;
import org.enfi.common.aspect.annotation.AutoLog;
import org.enfi.common.aspect.annotation.PrintLnTime;
import org.enfi.common.exception.EnFiBootException;
import org.enfi.common.util.DySmsEnum;
import org.enfi.common.util.DySmsHelper;
import org.enfi.common.util.QRCodeUtil;
import org.enfi.modules.visitor.entity.ApplyFor;
import org.enfi.modules.visitor.entity.ApplyForUser;
import org.enfi.modules.visitor.entity.InvitedToRecord;
import org.enfi.modules.visitor.service.IApplyForService;
import org.enfi.modules.visitor.service.IApplyForUserService;
import org.enfi.modules.visitor.service.IInvitedToRecordService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.enfi.common.aspect.annotation.AutoLog;

import java.util.HashMap;
import java.util.List;

/**
 * @Description:
 * @ClassName: VisitorsToFillInController
 * @Author: wanghao
 * @date: 2021.11.13 13:57
 * @version: 1.0
 */
@Slf4j
@Api(tags = "访客填报")
@ApiSupport(order = 3, author = "WangHao")
@RestController
@RequestMapping("/visitorsToFillIn")
public class VisitorsToFillInController {

    @Autowired //申请邀请记录
    private IInvitedToRecordService iInvitedToRecordService;
    @Autowired //申请邀请来访记录
    private IApplyForService iApplyForService;
    @Autowired //申请邀请来访用户
    private IApplyForUserService iApplyForUserService;

    @AutoLog("访客信息填报")
    @ApiOperationSupport(order = 1)
    @ApiOperation(value = "访客信息填报", notes = "访客信息填报")
    @PostMapping("visitorsToFillInInfo")
    @PrintLnTime
    @SneakyThrows
    public Result<?> visitorsToFillInInfo(@Validated @RequestBody ApplyFor applyFor) {
        InvitedToRecord result = getInvitedById(applyFor.getInviteId()).getResult();
        Integer numberOfReception = result.getNumberOfReception();//接待人数
        if (numberOfReception < 1) {
            throw new EnFiBootException("当前邀请中接待人数小于1");
        }
        Integer applyForNumber = getApplyForNumber(applyFor.getInviteId());//已填报来访人数
        if (applyForNumber >= numberOfReception) {
            throw new EnFiBootException("当前邀请中接待人数已满");
        }
        applyFor
                .setInviterId(result.getInviterId())
                .setInviterName(result.getInviterName())
                .setInviterId(result.getInviterId())
                .setInviterDeptName(result.getInviterDeptName())
                .setVisitTheReason(result.getVisitTheReason())
                .setVisitDeptName(result.getVisitDeptName())
                .setReceptionSite(result.getReceptionSite())
                .setBeginTime(result.getBeginTime())
                .setEndTime(result.getEndTime())
                .setCreateBy("微信小程序");

        DySmsHelper.sendSms("18351124321", new JSONObject() {{
            // put("code", "123456");
        }}, DySmsEnum.ENFI_GUEST_TEMPLATE_CODE);
        return Result.isResult(applyFor.insert());
    }

    @AutoLog("访客信息修改")
    @ApiOperationSupport(order = 2)
    @ApiOperation(value = "访客信息修改", notes = "访客信息修改")
    @PrintLnTime
    @PostMapping("updateVisitorsInfo")
    @SneakyThrows
    public Result<?> updateVisitorsInfo(@Validated @RequestBody ApplyFor applyFor) {
        InvitedToRecord result = getInvitedById(applyFor.getInviteId()).getResult();
        ApplyFor byId = iApplyForService.getById(applyFor.getId());
        if (ObjectUtil.isEmpty(byId)) {
            throw new EnFiBootException("访客信息id无效");
        }
        if (null != byId.getStatus() && byId.getStatus().equals(2)) {
            throw new EnFiBootException("访客信息已审核通过,无法修改");
        }
        applyFor
                .setInviterId(result.getInviterId())
                .setInviterName(result.getInviterName())
                .setInviterId(result.getInviterId())
                .setInviterDeptName(result.getInviterDeptName())
                .setVisitTheReason(result.getVisitTheReason())
                .setVisitDeptName(result.getVisitDeptName())
                .setReceptionSite(result.getReceptionSite())
                .setBeginTime(result.getBeginTime())
                .setEndTime(result.getEndTime())
                .setUpdateBy("微信小程序");
        DySmsHelper.sendSms("18351124321", new JSONObject() {{
            // put("code", "123456");
        }}, DySmsEnum.ENFI_GUEST_TEMPLATE_CODE);
        applyFor.setStatus(1);
        return Result.isResult(applyFor.updateById());
    }



    @AutoLog("根据邀请id获取获取邀请信息")
    @ApiOperationSupport(order = 3)
    @ApiOperation(value = "根据邀请id获取获取邀请信息", notes = "根据邀请id获取获取邀请信息")
    @GetMapping("getInvitedById")
    @PrintLnTime
    public Result<InvitedToRecord> getInvitedById(@ApiParam(name = "id", value = "id", required = true)
                                                  @RequestParam String id) {
        InvitedToRecord byId = iInvitedToRecordService.getById(id);
        if (ObjectUtil.isEmpty(byId)) {
            throw new EnFiBootException("邀请id无效");
        }
        return Result.OK(byId);
    }

    @AutoLog("根据邀请id和openId获取获取来访信息")
    @ApiOperationSupport(order = 4)
    @ApiOperation(value = "根据邀请id和openId获取获取来访信息", notes = "根据邀请id和openId获取获取来访信息")
    @GetMapping("getApplyForByInviteIdAndOpenId")
    @PrintLnTime
    public Result<ApplyFor> getInvitedById(@ApiParam(name = "inviteId", value = "邀请id", required = true)
                                           @RequestParam String inviteId,
                                           @ApiParam(name = "openId", value = "openId", required = true)
                                           @RequestParam String openId) {
        ApplyForUser applyForUseById = iApplyForUserService.getById(openId);
        if (ObjectUtil.isEmpty(applyForUseById)) {
            throw new EnFiBootException("openId无效");
        }
        InvitedToRecord invitedToRecordById = iInvitedToRecordService.getById(inviteId);
        if (ObjectUtil.isEmpty(invitedToRecordById)) {
            throw new EnFiBootException("邀请id无效");
        }
        LambdaQueryWrapper<ApplyFor> applyForQueryWrapper = new LambdaQueryWrapper<ApplyFor>()
                .eq(ApplyFor::getInviteId, inviteId)
                .eq(ApplyFor::getWxOpenid, openId);
        List<ApplyFor> list = iApplyForService.list(applyForQueryWrapper);
        if (list.size() > 1) {
            throw new EnFiBootException("当前邀请该用户来访信息有多条,请联系管理员");
        }
        ApplyFor applyFor = null;
        if (list.size() < 1) {
            //throw new EnFiBootException("当前邀请该用户没有来访信息");
            applyFor = new ApplyFor()
                    .setInviteId(invitedToRecordById.getId())
                    .setInviterName(invitedToRecordById.getInviterName())
                    .setInviterEmail(invitedToRecordById.getInviterEmail())
                    .setInviterDeptName(invitedToRecordById.getInviterDeptName())
                    .setInviterDeptId(invitedToRecordById.getInviterDeptId())
                    .setVisitDeptName(invitedToRecordById.getVisitDeptName())
                    .setVisitTheReason(invitedToRecordById.getVisitTheReason())
                    .setReceptionSite(invitedToRecordById.getReceptionSite())
                    .setWxOpenid(openId)
                    .setBeginTime(invitedToRecordById.getBeginTime())
                    .setEndTime(invitedToRecordById.getEndTime());
        } else {
            applyFor = list.get(0);
            String qRCode = QRCodeUtil.crateQRCode(JSONObject.toJSONString(applyFor), 400, 400);
            applyFor.setSuiShenCode(qRCode);
        }
        return Result.OK(applyFor);
    }

    @AutoLog("根据openId获取获取访客通行码")
    @ApiOperationSupport(order = 5)
    @ApiOperation(value = "根据openId获取获取访客通行码", notes = "根据openId获取获取访客通行码")
    @GetMapping("getQrCodeByOpenId")
    @PrintLnTime
    public Result<String> getQrCodeByOpenId(
            @ApiParam(name = "openId", value = "openId", required = true)
            @RequestParam String openId) {
        ApplyForUser applyForUseById = iApplyForUserService.getById(openId);
        if (ObjectUtil.isEmpty(applyForUseById)) {
            throw new EnFiBootException("openId无效");
        }
        List<ApplyFor> list = getApplyForLatestByOpenId(openId);
        if (list.size() < 1) {
            throw new EnFiBootException("当前邀请该用户没有来访信息");
        }
        ApplyFor applyFor = list.get(0);
        String qRCode = QRCodeUtil.crateQRCode(JSONObject.toJSONString(applyFor), 400, 400);
        return Result.OK("成功", qRCode);
    }

    @AutoLog("微信登录")
    @ApiOperationSupport(order = 6)
    @ApiOperation(value = "微信登录", notes = "微信登录")
    @GetMapping("wxLogin")
    @PrintLnTime
    public Result<?> wxLogin(
            @ApiParam(name = "code", value = "code", required = true)
            @RequestParam String code) {
        ApiResult apiResult = WxaUserApi.getSessionKey(code);
        if (!apiResult.isSucceed()) {
            throw new EnFiBootException("失败: " + apiResult.getJson());
        }
        ApplyForUser applyForUser = new ApplyForUser();
        String openid = (String) apiResult.getAttrs().get("openid");
        applyForUser.setId(openid);
        applyForUser.setWxOpenid(openid);
        iApplyForUserService.saveOrUpdate(applyForUser);
        return Result.OK("成功", new HashMap<String, Object>() {{
            put("data", new HashMap<String, Object>() {{
                List<ApplyFor> list = getApplyForLatestByOpenId(openid);
                put("name", list.isEmpty() ? null : list.get(0).getApplicantName());
                put("deptName", list.isEmpty() ? null : list.get(0).getApplicantDept());
                put("faceImage", list.isEmpty() ? null : list.get(0).getApplicantFaceImage());
                put("status", list.isEmpty() ? "未申请" : list.get(0).getStatus() == 1 ? "未审核" : list.get(0).getStatus() == 2 ? "审核通过" : "审核拒绝");
                put("date", list.isEmpty() ? null : DateUtil.formatDateTime(list.get(0).getBeginTime()) + "   -   " + DateUtil.formatDateTime(list.get(0).getEndTime()));
                //put("qRCode", list.isEmpty() ? null : QRCodeUtil.crateQRCode(JSONObject.toJSONString(list.get(0).getId()), 400, 400));
                put("qRCode", list.isEmpty() ? null : QRCodeUtil.crateQRCode(list.get(0).getId(), 400, 400));
            }});
            put("userInfo", apiResult.getAttrs());
        }});
    }
    @AutoLog("测试发生短信")
    @ApiOperationSupport(order = 7)
    @ApiOperation(value = "测试发生短信", notes = "测试发生短信")
    @GetMapping("testSendMessage")
    @PrintLnTime
    public Result<?> testSendMessage() throws ClientException {
        boolean b = DySmsHelper.sendSms("18351124321", new JSONObject() {{
            // put("code", "123456");
        }}, DySmsEnum.ENFI_GUEST_TEMPLATE_CODE);
        return Result.OK(b);
    }
    private List<ApplyFor> getApplyForLatestByOpenId(String openId) {
        LambdaQueryWrapper<ApplyFor> applyForQueryWrapper = new LambdaQueryWrapper<ApplyFor>()
                .eq(ApplyFor::getWxOpenid, openId).last("order by create_time desc limit 0,1");
        List<ApplyFor> list = iApplyForService.list(applyForQueryWrapper);
        return list;
    }

    private Integer getApplyForNumber(String inviteId) {
        return iApplyForService.list(new LambdaQueryWrapper<ApplyFor>().eq(ApplyFor::getInviteId, inviteId)).size();
    }
}
