package com.fs.app.controller;

import cn.hutool.core.date.DateTime;
import com.fs.app.annotation.UserOperationLog;
import com.fs.app.param.FsUserLoginByMpParam;
import com.fs.app.utils.JwtUtils;
import com.fs.common.core.domain.R;
import com.fs.common.core.redis.RedisCache;
import com.fs.course.mapper.FsCourseSopLogsMapper;
import com.fs.course.mapper.FsCourseWatchLogMapper;
import com.fs.his.domain.FsUser;
import com.fs.his.enums.FsUserOperationEnum;
import com.fs.his.service.IFsUserService;
import com.fs.his.utils.ConfigUtil;
import com.fs.qw.mapper.QwExternalContactMapper;
import com.fs.sop.params.QwSopSettingTimeParam;
import com.fs.system.mapper.SysConfigMapper;
import com.fs.wx.mp.WxEeventType;
import com.fs.wx.mp.WxMessageType;
import com.fs.wx.mp.WxServiceMsgDto;
import io.swagger.annotations.ApiOperation;
import lombok.Synchronized;
import me.chanjar.weixin.common.bean.WxJsapiSignature;
import me.chanjar.weixin.common.bean.WxOAuth2UserInfo;
import me.chanjar.weixin.common.bean.menu.WxMenu;
import me.chanjar.weixin.common.bean.oauth2.WxOAuth2AccessToken;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpMenuService;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.WxMpUserService;
import me.chanjar.weixin.mp.bean.result.WxMpUser;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;



@RestController
@RequestMapping("/app/wx/mp")
public class WxMpController {
  Logger logger= LoggerFactory.getLogger(getClass());
  @Autowired
  private WxMpService wxMpService;
  private static final String MP_TOKEN = "U2qmxEbsp0PJFoLRvUDvIjVi9XPzuVc2";

  private static final String EncodingAESKey = "P3HE7Gd1PJVQqCLoOMop5uYfjx9LwfY53rnC3VUuLZS";

  @Autowired
  private IFsUserService userService;

  @Autowired
  JwtUtils jwtUtils;
  @Autowired
  RedisCache redisCache;

  @Autowired
  private ConfigUtil configUtil;

  @Autowired
  private SysConfigMapper sysConfigMapper;

  @Autowired
  FsCourseWatchLogMapper fsCourseWatchLogMapper;
  @Autowired
  QwExternalContactMapper qwExternalContactMapper;
  @Autowired
  private FsCourseSopLogsMapper courseSopLogsMapper;


  //公众号事件回调
  @PostMapping
  public String checkWxToken(@RequestParam(value = "signature", required = false) String signature,
                             @RequestParam(value = "timestamp", required = false) String timestamp,
                             @RequestParam(name = "nonce", required = false) String nonce,
                             @RequestParam(value = "echostr", required = false) String echostr,
                             @RequestBody(required = false) WxServiceMsgDto wxServiceMsgDto) throws WxErrorException{
    // 只处理订阅与取消订阅消息
    if (null != wxServiceMsgDto && StringUtils.isNotEmpty(wxServiceMsgDto.getMsgType()) &&
            StringUtils.isNotEmpty(wxServiceMsgDto.getEvent())) {
      String msgType = wxServiceMsgDto.getMsgType();
      String event = wxServiceMsgDto.getEvent();
      // 判断是否是订阅或取消订阅事件
      boolean isSubscribeEvent = WxMessageType.EVENT.getCode().equals(msgType) &&
              (WxEeventType.SUBSCRIBE.getCode().equals(event) || WxEeventType.UNSUBSCRIBE.getCode().equals(event));
      if (isSubscribeEvent) {
        WxEeventType wxEeventType = WxEeventType.SUBSCRIBE.getCode().equals(event) ? WxEeventType.SUBSCRIBE : WxEeventType.UNSUBSCRIBE;
        logger.info("公众号关注回调:{}",wxEeventType);
        logger.info("公众号关注回调详情:{}",wxServiceMsgDto);
        WxMpUserService wxMpUserService = wxMpService.getUserService();
        WxMpUser wxMpUser = wxMpUserService.userInfo(wxServiceMsgDto.getFromUserName());
        logger.info("获取用户信息:{}",wxMpUser);
        if (wxMpUser != null && wxMpUser.getUnionId()!=null) {
          FsUser user = userService.selectFsUserByUnionid(wxMpUser.getUnionId());
          if (user != null) {
            // 根据事件类型更新 isOfficialAccountAuth 字段
            if (WxEeventType.SUBSCRIBE.equals(wxEeventType)) {
              user.setIsOfficialAccountAuth(1); // 设置为已关注
            } else if (WxEeventType.UNSUBSCRIBE.equals(wxEeventType)) {
              user.setIsOfficialAccountAuth(0); // 设置为取消关注
            }
            userService.updateFsUser(user); // 保存更新后的用户信息
          }else {
            //写入
            user=new FsUser();
//            user.setPhone(code);
            user.setNickName("匿名用户**");
            user.setAvatar("https://hos-1309931967.cos.ap-chongqing.myqcloud.com/fs/20230725/a848605591384ec29d49773dd58d9345.jpg");
            user.setStatus(1);
            user.setMpOpenId(wxMpUser.getOpenId());
            user.setUnionId(wxMpUser.getUnionId());
            user.setIsOfficialAccountAuth(wxMpUser.getSubscribe()? 1 : 0);
            user.setCreateTime(new Date());
            userService.insertFsUser(user);
          }
        }
      }
    }
    return "success";
  }

  @GetMapping
  public String checkWxToken(
          @RequestParam("signature") String signature,
          @RequestParam("timestamp") String timestamp,
          @RequestParam("nonce") String nonce,
          @RequestParam("echostr") String echostr) {
    logger.info("数据回调URLServer-微信调用dataGet请求");
    boolean check = wxMpService.checkSignature(timestamp,nonce,signature);
    logger.info("验证结果：{}",check);
    if (check){
      return echostr;
    }
    return "error";
  }

  @PostMapping("/createMenu")
  public R createMenu(@RequestBody WxMenu wxMenu) throws WxErrorException{
    WxMpMenuService wxMpMenuService = wxMpService.getMenuService();
    try{
      wxMpMenuService.menuCreate(wxMenu);
      return R.ok("创建成功");
    }catch (WxErrorException e){
      logger.error(e.getMessage());
      return R.error("创建失败");
    }
  }



  private Date setSendTime(QwSopSettingTimeParam params) {
    Date currentTime = new Date();
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(currentTime);

    try {
      if (params.getType() == 1) {
        int hourToAdd = Integer.parseInt(params.getHour());
        int minuteToAdd = Integer.parseInt(params.getMinute());
        calendar.add(Calendar.HOUR, hourToAdd);
        calendar.add(Calendar.MINUTE, minuteToAdd);
      } else if (params.getType() == 2) {
        calendar.add(Calendar.DAY_OF_MONTH, Integer.parseInt(params.getDay()));
        SimpleDateFormat timeFormatter = new SimpleDateFormat("HH:mm");
        Date parsedTime = timeFormatter.parse(params.getTime());
        Calendar timeCalendar = Calendar.getInstance();
        timeCalendar.setTime(parsedTime);
        calendar.set(Calendar.HOUR_OF_DAY, timeCalendar.get(Calendar.HOUR_OF_DAY));
        calendar.set(Calendar.MINUTE, timeCalendar.get(Calendar.MINUTE));
        calendar.set(Calendar.SECOND, 0);
      }
    } catch (Exception e) {
      e.printStackTrace(); // 或者更好的异常处理
    }

    return calendar.getTime();
  }
    @GetMapping("/getWxConfig")
    @Synchronized
    public R getWxConfig(@RequestParam String url) throws WxErrorException {
      try {
        String sLink = URLDecoder.decode(url, "UTF-8");
        final WxJsapiSignature jsapiSignature = wxMpService.createJsapiSignature(sLink);
        return R.ok().put("data", jsapiSignature);
      } catch (UnsupportedEncodingException e) {
        // URL解码异常
        return R.error(e.getMessage());
      }

    }




}
