package com.cyksj.web.controller.manage.goods.shop;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.cyksj.common.annotation.NoSubmit;
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.UserMapper;
import com.cyksj.mapper.shop.YhShopMapper;
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.User;
import com.cyksj.model.entity.YhShop;
import com.cyksj.model.request.LoginReq;
import com.cyksj.redis.RedisService;
import com.cyksj.service.authorization.AuthorizationService;
import com.cyksj.service.cps.shop.YhShopManageService;
import com.cyksj.service.wechat.WeChatService;
import com.cyksj.web.util.StpUserUtil;
import com.cyksj.web.util.StpYhShopManageUser;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Optional;

/*
 *项目名: yhlxj
 *文件名: YhShopController
 *创建者: JavaZou
 *创建时间:2023/9/19 17:34
 */
@RestController
@RequestMapping("/yhShop/manage")
@RequiredArgsConstructor
public class YhShopLoginController {
	private final YhShopManageService yhShopManageService;

	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 YhShopMapper yhShopMapper;

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

	/**
	 * 跳转店铺后台 是否是店铺主
	 */
	@GetMapping("/redirect")
	public void yhShopManageRedirect(String redirectUrl, HttpServletResponse response) throws IOException {
		//银河官网token值
		long userId = StpUserUtil.getLoginIdAsLong();
		yhShopManageService.yhShopManageRedirect(userId);
		//校验通过重定向
		StpYhShopManageUser.login(userId);
		response.sendRedirect(redirectUrl.contains("?") ? redirectUrl + "&t=" + StpYhShopManageUser.getTokenValue() : redirectUrl + "?t=" + StpYhShopManageUser.getTokenValue());
	}


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

	/**
	 * 小店后台微信授权登录
	 */
	@GetMapping("/wx/authLogin")
	public Result<CpsAuthDto> wxAuthorize() throws Exception {
		Object authUrlObj = redisService.get(RedisService.key.WX_LOGIN_AUTH_URI.getNameFormat("yhShop", wxOpenPlatYHLXLoginConfig.getAppId()));
		if (authUrlObj != null) {
			CpsAuthDto cpsAuthDto = Jsons.parseObject(authUrlObj.toString(), CpsAuthDto.class);
			return GatewayResponse.SUCCESS.newBuilder().toResult(cpsAuthDto);
		}
		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);
		String state = Codec.DoBase64.custom().setData(Jsons.toJson(redirect)).encodeAsText();
		String wxAuthUrl = authorizationService.createWxAuthLoginUrl(state, wxOpenPlatYHLXLoginConfig.getAppId(), wxOpenPlatYHLXLoginConfig.getYhShopRedirectUri());
		cpsAuthDto.setAuthUrl(wxAuthUrl);
		cpsAuthDto.setAuthState(authState);
		redisService.set(RedisService.key.WX_LOGIN_AUTH_URI.getNameFormat("yhShop", wxOpenPlatYHLXLoginConfig.getAppId()), Jsons.toJson(cpsAuthDto), RedisService.key.WX_LOGIN_AUTH_URI.getTimeout());
		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("用户信息不存在");
		YhShop yhShop = yhShopMapper.selectOne(Wrappers.lambdaQuery(YhShop.class)
				.eq(YhShop::getVerifyStatus, YhShop.Status.success)
				.eq(YhShop::getUserId, user.getId()).last("limit 1"));
		if (yhShop == null) {
			throw BusinessRuntimeException.getInstance("您不是银河小店店铺主");
		}
		JSONObject res = new JSONObject();
		StpYhShopManageUser.login(user.getId());
		String cpsToken = StpYhShopManageUser.getTokenValue();
		res.putOpt("satoken-yhShop", cpsToken);
		res.putOpt("img", user.getHeadimgurl());
		res.putOpt("nickname", user.getNickname());
		redisService.set(RedisService.key.YH_SHOP_AUTH_SUCCESS_KEY.getNameFormat(re.getMappingId()), res.toString(), RedisService.key.YH_SHOP_AUTH_SUCCESS_KEY.getTimeout());
		response.sendRedirect(wxOpenPlatYHLXLoginConfig.getYhShopLoginUrl());
	}

	/**
	 * 店铺用户是否已授权
	 */
	@GetMapping("/get/userInfo")
	public Result<String> getCpsUserInfo(String authState) {
		String key = RedisService.key.YH_SHOP_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());
	}
}
