package com.cyksj.web.controller.cps;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.cyksj.common.annotation.NoSubmit;
import com.cyksj.common.constant.Constant;
import com.cyksj.common.exception.BusinessRuntimeException;
import com.cyksj.common.snowflake.Sequence;
import com.cyksj.common.util.Codec;
import com.cyksj.common.util.Jsons;
import com.cyksj.config.wxlogin.WxOpenPlatYHLXLoginConfig;
import com.cyksj.dto.Result;
import com.cyksj.enums.GatewayResponse;
import com.cyksj.mapper.CpsUserGuideRecordMapper;
import com.cyksj.mapper.UserMapper;
import com.cyksj.mapper.manage.cps.CpsUserAdRecordMapper;
import com.cyksj.mapper.manage.distribute.UserDistributeMapper;
import com.cyksj.mapper.manage.distribute.equipment.UserDistributeEquipmentMapper;
import com.cyksj.mapper.sys.SysConfigMapper;
import com.cyksj.model.dto.AuthRedirect;
import com.cyksj.model.dto.AuthToken;
import com.cyksj.model.dto.CpsAuthDto;
import com.cyksj.model.dto.GzhOAuth2UserInfo;
import com.cyksj.model.entity.*;
import com.cyksj.model.request.LoginReq;
import com.cyksj.model.response.GoogleLoginRep;
import com.cyksj.model.response.UserAuthLoginResp;
import com.cyksj.model.views.UserInfoView;
import com.cyksj.redis.RedisService;
import com.cyksj.service.authorization.AuthorizationService;
import com.cyksj.service.cps.CpsManageService;
import com.cyksj.service.user.UserService;
import com.cyksj.service.wechat.WeChatService;
import com.cyksj.web.util.StpCpsManageUser;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Optional;

/*
 *项目名: netflix
 *文件名: CpsBackLoginController
 *创建者: JavaZou
 *创建时间:2023/5/12 11:00
 */
@RestController
@RequestMapping("/cps/manage")
@RequiredArgsConstructor
@Slf4j
public class CpsBackLoginController {
	private final CpsManageService cpsManageService;

	private final RedisService redisService;

	private final static Sequence SEQUENCE = new Sequence(0);

	private final WxOpenPlatYHLXLoginConfig wxOpenPlatYHLXLoginConfig;

	private final AuthorizationService authorizationService;

	private final WeChatService weChatService;

	private final UserMapper userMapper;

	private final UserDistributeMapper userDistributeMapper;

	private final UserDistributeEquipmentMapper userDistributeEquipmentMapper;

	private final CpsUserAdRecordMapper cpsUserAdRecordMapper;

	private final SysConfigMapper sysConfigMapper;

	private final CpsUserGuideRecordMapper cpsUserGuideRecordMapper;

	private final HttpServletRequest request;

	private final UserService userService;

	/**
	 * 获取登录验证码
	 */
	@GetMapping("/get/LoginCode")
	@NoSubmit
	public Result getLoginCode(@RequestParam(defaultValue = "1") Integer type, String login, Integer cid, String verifyCode, String ticket, String randStr) {
		cpsManageService.getLoginCode(type, login, cid, verifyCode, ticket, randStr);
		return GatewayResponse.SUCCESS.newBuilder().toResult();
	}


	/**
	 * 手机号、邮箱登录
	 */
	@PostMapping("/login")
	public Result login(@RequestBody LoginReq loginReq) {
		User user = cpsManageService.login(loginReq.getType(), loginReq.getLogin(), loginReq.getCode());
		StpCpsManageUser.login(user.getId());
		String cpsToken = StpCpsManageUser.getTokenValue();
		JSONObject re = new JSONObject();
		re.putOpt("satoken-cpsUser", cpsToken);
		re.putOpt("img", user.getHeadimgurl());
		re.putOpt("nickname", user.getNickname());
		return GatewayResponse.SUCCESS.newBuilder().toResult(re.toString());
	}

	/**
	 * cps后台微信授权登录
	 */
	@GetMapping("/wx/authLogin")
	public Result<CpsAuthDto> wxAuthorize(String redirectUrl) throws Exception {
		CpsAuthDto cpsAuthDto = new CpsAuthDto();
		Long mappingId = SEQUENCE.nextId();
		String authState = mappingId.toString();
		redisService.set(authState, authState, 60 * 60 * 24L);
		AuthRedirect redirect = new AuthRedirect().setMappingId(mappingId);
		redirect.setUrl(redirectUrl);
		String state = Codec.DoBase64.custom().setData(Jsons.toJson(redirect)).encodeAsText();
		String wxAuthUrl = authorizationService.createWxAuthLoginUrl(state, wxOpenPlatYHLXLoginConfig.getAppId(), wxOpenPlatYHLXLoginConfig.getCpsRedirectUri());
		cpsAuthDto.setAuthUrl(wxAuthUrl);
		cpsAuthDto.setAuthState(authState);
		return GatewayResponse.SUCCESS.newBuilder().toResult(cpsAuthDto);
	}

	/**
	 * 网页微信授权后跳转
	 */
	@GetMapping("/wx/authLogin/baseRedirect")
	public void wxAuthLoginRedirect(String code, String state, HttpServletResponse response) throws Exception {
		if (StrUtil.isEmpty(state)) throw BusinessRuntimeException.getInstance("授权错误,请重新授权");
		String json = Codec.DoBase64.custom().setData(state).decodeAsText();
		AuthRedirect re = Jsons.parseObject(json, AuthRedirect.class);
		AuthToken token = weChatService.getAuthToken(code, wxOpenPlatYHLXLoginConfig.getAppId());
		GzhOAuth2UserInfo userinfo = weChatService.getUserInfo(token.getAccessToken(), token.getOpenid());
		String unionId = userinfo.getUnionid();
		String openId = userinfo.getOpenid();
		User user = Optional.ofNullable(
				userMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getUnionid, unionId)
						.orderByAsc(User::getId)
						.last("limit 1")))
				.orElseGet(() -> userMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getOpenId, openId)
						.orderByAsc(User::getId)
						.last("limit 1")));
		if (user == null) throw BusinessRuntimeException.getInstance("用户信息不存在");
		UserDistribute userDistribute = userDistributeMapper.selectOne(Wrappers.lambdaQuery(UserDistribute.class).eq(UserDistribute::getUserId, user.getId()).eq(UserDistribute::getDeleted, 1).select(UserDistribute::getId).last("limit 1"));
		if (userDistribute == null) throw BusinessRuntimeException.getInstance("只支持渠道分销用户登录");
		StpCpsManageUser.login(user.getId());
		String cpsToken = StpCpsManageUser.getTokenValue();
		String url = re.getUrl();
		if (StrUtil.isNotBlank(url)) {
			response.sendRedirect(url.contains("?") ? url + "&t=" + cpsToken : url + "?t=" + cpsToken);
			return;
		}
		JSONObject res = new JSONObject();
		res.putOpt("satoken-cpsUser", cpsToken);
		res.putOpt("img", user.getHeadimgurl());
		res.putOpt("nickname", user.getNickname());
		redisService.set(RedisService.key.CPS_AUTH_SUCCESS_KEY.getNameFormat(re.getMappingId()), res.toString(), RedisService.key.CPS_BACK_LOGIN_KEY.getTimeout());
		response.sendRedirect(wxOpenPlatYHLXLoginConfig.getCpsLoginUrl());
	}

	/**
	 * 用户是否已授权
	 */
	@GetMapping("/get/userInfo")
	public Result<String> getCpsUserInfo(String authState) {
		String key = RedisService.key.CPS_AUTH_SUCCESS_KEY.getNameFormat(authState);
		Object o = redisService.get(key);
		if (o == null) return GatewayResponse.SUCCESS.newBuilder().toResult();
		redisService.del(key);
		return GatewayResponse.SUCCESS.newBuilder().toResult(o.toString());
	}

	/**
	 * 广告弹窗是否展示
	 */
	@GetMapping("/get/ad")
	public Result<String> getAd() {
		String key = Constant.CPS_AD_KEY;
		long cpsUserId = StpCpsManageUser.getLoginIdAsLong();
		CpsUserAdRecord cpsUserAdRecord = cpsUserAdRecordMapper.selectOne(Wrappers.lambdaQuery(CpsUserAdRecord.class)
				.eq(CpsUserAdRecord::getUserId, cpsUserId)
				.eq(CpsUserAdRecord::getSysKey, key)
				.last("limit 1"));
		if (cpsUserAdRecord == null) {
			SysConfig sysConfig = sysConfigMapper.selectOne(Wrappers.lambdaQuery(SysConfig.class)
					.eq(SysConfig::getSysKey, key).last("limit 1"));
			if (sysConfig != null){
				cpsUserAdRecord = new CpsUserAdRecord();
				cpsUserAdRecord.setUserId(cpsUserId);
				cpsUserAdRecord.setSysKey(key);
				cpsUserAdRecordMapper.insert(cpsUserAdRecord);
				return GatewayResponse.SUCCESS.newBuilder().toResult(sysConfig.getSysValue());
			}
		}
		return GatewayResponse.SUCCESS.newBuilder().toResult();
	}

	/**
	 * 获取cps用户基本信息
	 */
	@GetMapping("/get/redirect/userInfo")
	public Result<UserInfoView> getUserInfoView() {
		long cpsUserId = StpCpsManageUser.getLoginIdAsLong();
		User user = userMapper.selectById(cpsUserId);
		Assert.notNull(user, "用户不存在");
		UserDistribute userDistribute = userDistributeMapper.selectOne(Wrappers.lambdaQuery(UserDistribute.class).eq(UserDistribute::getUserId, user.getId()).eq(UserDistribute::getDeleted, 1).select(UserDistribute::getId, UserDistribute::getIsPoster).last("limit 1"));
		Assert.notNull(userDistribute, "只支持渠道分销用户登录");
		UserInfoView userInfoView = new UserInfoView();
		userInfoView.setImg(user.getHeadimgurl());
		userInfoView.setNickname(user.getNickname());
		Integer selectCount = userDistributeEquipmentMapper.selectCount(Wrappers.lambdaQuery(UserDistributeEquipment.class)
				.eq(UserDistributeEquipment::getUserId, cpsUserId));
		userInfoView.setIsEp(selectCount > 0 ? true : false);
		userInfoView.setIsPoster(userDistribute.getIsPoster());
		return GatewayResponse.SUCCESS.newBuilder().toResult(userInfoView);
	}

	/**
	 * 是否首次进入cps后台
	 */
	@GetMapping("/get/first")
	public Result<Boolean> firstLogin() {
		long cpsUserId = StpCpsManageUser.getLoginIdAsLong();

		Integer selectCount = cpsUserGuideRecordMapper.selectCount(Wrappers.lambdaQuery(CpsUserGuideRecord.class)
				.eq(CpsUserGuideRecord::getUserId, cpsUserId));
		Boolean flag = false;
		if (selectCount == 0) {
			CpsUserGuideRecord cpsUserGuideRecord = new CpsUserGuideRecord();
			cpsUserGuideRecord.setUserId(cpsUserId);
			cpsUserGuideRecordMapper.insert(cpsUserGuideRecord);
			flag = true;
		}
		return GatewayResponse.SUCCESS.newBuilder().toResult(flag);
	}

	/**
	 * cps谷歌授权登录
	 */
	@PostMapping("/google/login")
	public Result<UserAuthLoginResp> googleLogin(LoginReq loginReq, String credential) throws Exception {
		log.info("google loginReq:{},credential:{}", loginReq, credential);
		String result = HttpUtil.post("https://galaxyva.com/8081/api/auth/google/login/inner?credential=" + credential, new HashMap<>());
		log.info("google result:{}", result);
		GoogleLoginRep googleLoginRep = Jsons.parseObject(Jsons.toMap(result).get("data"), GoogleLoginRep.class);
		loginReq.setType(3);
		loginReq.setEmail(googleLoginRep.getEmail());
		loginReq.setSubject(googleLoginRep.getSubject());
		User user = userService.webLogin(loginReq, request);

		//是否非cps分销用户
		UserDistribute userDistribute = userDistributeMapper.selectOne(Wrappers.lambdaQuery(UserDistribute.class)
				.eq(UserDistribute::getUserId, user.getId())
				.eq(UserDistribute::getDeleted, 1).last("limit 1"));
		if (userDistribute == null) {
			throw BusinessRuntimeException.getInstance("只支持分销用户登录");
		}

		Optional.ofNullable(user.getIsBlack())
				.ifPresent(black -> {
					if (black) {
						throw BusinessRuntimeException.getInstance("您的账号已被注销...");
					}
				});
		//写回登陆信息
		StpCpsManageUser.login(user.getId());
		UserAuthLoginResp loginPhoneRep = new UserAuthLoginResp(StpCpsManageUser.getTokenValue(), user.getShowId(), user.getNickname(), user.getHeadimgurl());
		return GatewayResponse.SUCCESS.newBuilder().toResult(loginPhoneRep);
	}
}
