package com.fs.app.controller;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.hutool.core.date.DateTime;
import com.fs.app.annotation.UserOperationLog;
import com.fs.app.param.FsUserLoginByCourseMpParam;
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.company.domain.Company;
import com.fs.company.domain.CompanyUser;
import com.fs.company.service.ICompanyService;
import com.fs.company.service.ICompanyUserService;
import com.fs.core.config.WxMaConfiguration;
import com.fs.course.domain.FsUserCompanyUser;
import com.fs.course.mapper.FsCourseWatchLogMapper;
import com.fs.course.service.IFsUserCompanyUserService;
import com.fs.his.domain.FsUser;
import com.fs.his.domain.FsUserWx;
import com.fs.his.enums.FsUserOperationEnum;
import com.fs.his.service.IFsUserService;
import com.fs.his.service.IFsUserWxService;
import com.fs.qw.mapper.QwExternalContactMapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.bean.WxOAuth2UserInfo;
import me.chanjar.weixin.common.bean.oauth2.WxOAuth2AccessToken;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import org.apache.commons.lang3.StringUtils;
import org.checkerframework.checker.units.qual.C;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

@Api("会员-h5-微信相关接口")
@RestController
@RequestMapping("/app/wx/h5/mp")
@Slf4j
public class WxH5MpController {
    Logger logger = LoggerFactory.getLogger(getClass());
    @Autowired
    private WxMpService wxMpService;

    @Autowired
    private IFsUserService userService;

    @Autowired
    JwtUtils jwtUtils;
    @Autowired
    RedisCache redisCache;

    @Autowired
    FsCourseWatchLogMapper fsCourseWatchLogMapper;
    @Autowired
    QwExternalContactMapper qwExternalContactMapper;
    @Autowired
    ICompanyService companyService;
    @Autowired
    ICompanyUserService companyUserService;
    @Autowired
    private IFsUserCompanyUserService userCompanyUserService;
    @Autowired
    private IFsUserWxService fsUserWxService;

    @ApiOperation("课程分享链接公众号登录")
    @PostMapping("/loginByMp")
    @UserOperationLog(operationType = FsUserOperationEnum.H5LOGIN)
    public R loginByMp(@Valid @RequestBody FsUserLoginByMpParam param) {
        log.info("=====================进入小程序授权登录, 入参: {}", param);

        // 参数校验
        if (StringUtils.isBlank(param.getCode())) {
            return R.error("code不存在");
        }

        // 公司状态校验
        Company company = companyService.selectCompanyById(param.getCompanyId());
        if (company == null || company.getStatus() == 0) {
            return R.error("注册失败团队已停用，或不存在！");
        }

        // 客服状态校验
        CompanyUser companyUser = companyUserService.selectCompanyUserById(param.getCompanyUserId());
        if (companyUser == null || "1".equals(companyUser.getStatus())) {
            return R.error("注册失败客服已停用，或不存在！");
        }

        try {
            // 获取微信用户信息
            WxOAuth2AccessToken wxMpOAuth2AccessToken = wxMpService.getOAuth2Service().getAccessToken(param.getCode());
            WxOAuth2UserInfo wxMpUser = wxMpService.getOAuth2Service().getUserInfo(wxMpOAuth2AccessToken, null);

            if (StringUtils.isEmpty(wxMpUser.getUnionId())){
                return R.error("未绑定开放平台");
            }

            // 处理用户信息
            FsUser user = processUserInfo(wxMpUser, company,companyUser,param);

//            // 检查用户是否已绑定其他销售
//            FsUserCompanyUser userCompanyUser = userCompanyUserService.selectByUserIdAndProjectId(user.getUserId(), param.getProjectId());
//            if (Objects.nonNull(userCompanyUser) && !param.getCompanyUserId().equals(userCompanyUser.getCompanyUserId())){
//                return R.error(500, "该用户("+user.getUserId() + ")已成为其他销售会员");
//            }

//            // 处理用户与公司的关系
//            processUserCompanyRelationship(user, param, companyUser, company);



            // 生成token并返回结果
            return generateLoginResult(user);


        } catch (WxErrorException e) {
            this.logger.error(e.getMessage(), e);
            return R.error("授权失败," + e.getMessage());
        }
    }

    @ApiOperation("炮灰小程序-公众号登录转小程序")
    @PostMapping("/courseLoginByMp")
    @UserOperationLog(operationType = FsUserOperationEnum.H5LOGIN)
    public R courseLoginByMp(@Valid @RequestBody FsUserLoginByCourseMpParam param) {
        log.info("=====================进入炮灰小程序-公众号授权登录, 入参: {}", param);

        // 参数校验
        if (StringUtils.isBlank(param.getCode())) {
            return R.error("code不存在");
        }

        // 公司状态校验
        Company company = companyService.selectCompanyById(param.getCompanyId());
        if (company == null || company.getStatus() == 0) {
            return R.error("注册失败团队已停用，或不存在！");
        }

        // 客服状态校验
        CompanyUser companyUser = companyUserService.selectCompanyUserById(param.getCompanyUserId());
        if (companyUser == null || "1".equals(companyUser.getStatus())) {
            return R.error("注册失败客服已停用，或不存在！");
        }

        try {
            // 获取微信用户信息
            WxOAuth2AccessToken wxMpOAuth2AccessToken = wxMpService.getOAuth2Service().getAccessToken(param.getCode());
            WxOAuth2UserInfo wxMpUser = wxMpService.getOAuth2Service().getUserInfo(wxMpOAuth2AccessToken, null);
            if (StringUtils.isEmpty(wxMpUser.getUnionId())){
                return R.error("未绑定开放平台");
            }

            if (StringUtils.isEmpty(wxMpUser.getUnionId())){
                return R.error("未绑定开放平台");
            }

            // 处理用户信息
            FsUser user = processUserInfoByCourseLoginByMp(wxMpUser, param);

            // 生成token并返回结果
            return generateLoginResult(user);
        } catch (WxErrorException e) {
            this.logger.error(e.getMessage(), e);
            return R.error("授权失败," + e.getMessage());
        }
    }


    private FsUser processUserInfo(WxOAuth2UserInfo wxMpUser, Company company,CompanyUser companyUser,FsUserLoginByMpParam param) {
        FsUser user = userService.selectFsUserByUnionId(wxMpUser.getUnionId());

        if (user != null) {
            // 更新现有用户信息
            FsUser userUpdate = new FsUser();
            userUpdate.setUserId(user.getUserId());
            userUpdate.setMpOpenId(wxMpUser.getOpenid());
            userUpdate.setUnionId(wxMpUser.getUnionId());
            userUpdate.setUpdateTime(new DateTime());
            userUpdate.setNickName(wxMpUser.getNickname());
            userUpdate.setAvatar(wxMpUser.getHeadImgUrl());
            userService.updateFsUser(userUpdate);
            // 重新查询完整的用户信息返回（包含更新后的appId）
            return userService.selectFsUserById(user.getUserId());
        } else {
            // 创建新用户
            FsUser newUser = new FsUser();
            newUser.setNickName(wxMpUser.getNickname());
            newUser.setAvatar(wxMpUser.getHeadImgUrl());
            newUser.setStatus(1);
            newUser.setMpOpenId(wxMpUser.getOpenid());
//            newUser.setCompanyId(company.getCompanyId());
//            newUser.setCompanyUserId(companyUser.getUserId());
            newUser.setUnionId(wxMpUser.getUnionId());
            newUser.setCreateTime(new Date());
//            newUser.setStatus(company != null && company.getFsUserIsDefaultBlack() == 1 ? 0 : 1);
            // 新用户 - 添加 appId
            newUser.setAppId(param.getAppId());
            userService.insertFsUser(newUser);

            return newUser;
        }
    }

    private FsUser processUserInfoByCourseLoginByMp(WxOAuth2UserInfo wxMpUser, FsUserLoginByCourseMpParam param) {
        FsUser user = userService.selectFsUserByUnionId(wxMpUser.getUnionId());

        if (user != null) {
            // 更新现有用户信息
            FsUser userUpdate = new FsUser();
            userUpdate.setUserId(user.getUserId());
            userUpdate.setMpOpenId(wxMpUser.getOpenid());
            userUpdate.setUnionId(wxMpUser.getUnionId());
            userUpdate.setUpdateTime(new DateTime());
            userUpdate.setNickName(wxMpUser.getNickname());
            userUpdate.setAvatar(wxMpUser.getHeadImgUrl());
            userService.updateFsUser(userUpdate);
            // 重新查询完整的用户信息返回（包含更新后的appId）
            return userService.selectFsUserById(user.getUserId());
        } else {
            // 创建新用户
            FsUser newUser = new FsUser();
            newUser.setNickName(wxMpUser.getNickname());
            newUser.setAvatar(wxMpUser.getHeadImgUrl());
            newUser.setStatus(1);
            newUser.setMpOpenId(wxMpUser.getOpenid());
//            newUser.setCompanyId(company.getCompanyId());
//            newUser.setCompanyUserId(companyUser.getUserId());
            newUser.setUnionId(wxMpUser.getUnionId());
            newUser.setCreateTime(new Date());
            // 新用户 - 添加 appId
            newUser.setAppId(param.getAppId());
            userService.insertFsUser(newUser);
            return newUser;
        }
    }

    private void processUserCompanyRelationship(FsUser user, FsUserLoginByMpParam param,
                                                CompanyUser companyUser, Company company) {
        if ((companyUser.getIsAllowedAllRegister() == null || companyUser.getIsAllowedAllRegister() == 1)
                && companyUser.getIsNeedRegisterMember() != null && companyUser.getIsNeedRegisterMember() != 1) {
            int defaultStatus = (company != null && company.getFsUserIsDefaultBlack() == 1) ? 0 : 1;
            userCompanyUserService.bindRelationship(
                    user.getUserId(),
                    param.getProjectId(),
                    companyUser.getCompanyId(),
                    companyUser.getUserId(),
                    defaultStatus
            );
        }
    }

    private R generateLoginResult(FsUser user) {
        String token = jwtUtils.generateToken(user.getUserId());
        redisCache.setCacheObject("token:" + user.getUserId(), token, 604800, TimeUnit.SECONDS);

        Map<String, Object> result = new HashMap<>();
        result.put("token", token);
        result.put("user", user);
        return R.ok(result);
    }



    @ApiOperation("处理用户与小程序的绑定")
    @PostMapping("/handleFsUserWx")
    public R handleFsUserWx(@RequestBody FsUserLoginByMpParam param) {
        try {
            final WxMaService wxService = WxMaConfiguration.getMaService(param.getAppId());
            //获取微信用户信息
            WxMaJscode2SessionResult session = wxService.getUserService().getSessionInfo(param.getCode());

            FsUser user = userService.selectFsUserById(param.getUserId());
            handleFsUserWx(user, param, session);
            return R.ok();
        } catch (WxErrorException e) {
            if (e.getError().getErrorCode() == 40163) {
                return R.error(40163, e.getError().getErrorMsg());
            } else {
                return R.error("获取用户信息失败," + e.getMessage());
            }
        }
    }
    private void handleFsUserWx(FsUser user, FsUserLoginByMpParam param, WxMaJscode2SessionResult session) {
        if (user == null) return;
        FsUserWx fsUserWx = new FsUserWx();
        fsUserWx.setType(1);
        fsUserWx.setFsUserId(user.getUserId());
        fsUserWx.setAppId(param.getAppId());
        fsUserWx.setOpenId(session.getOpenid());
        fsUserWx.setUnionId(session.getUnionid() != null ? session.getUnionid() : null);
        fsUserWx.setCreateTime(new Date());
        fsUserWx.setUpdateTime(new Date());
        fsUserWxService.saveOrUpdateByUniqueKey(fsUserWx);
    }

}
