/**
 * 
 */
package org.springblade.modules.auth.endpoint;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.wf.captcha.SpecCaptcha;
import com.wf.captcha.base.Captcha;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springblade.common.cache.CacheNames;
import org.springblade.core.constant.AppConstant;
import org.springblade.core.tool.exception.ServiceException;
import org.springblade.core.tool.support.Kv;
import org.springblade.modules.auth.enums.UserEnum;
import org.springblade.modules.auth.granter.CaptchaTokenGranter;
import org.springblade.modules.auth.provider.ITokenGranter;
import org.springblade.modules.auth.provider.TokenGranterBuilder;
import org.springblade.modules.auth.provider.TokenParameter;
import org.springblade.modules.auth.utils.TokenUtil;
import org.springblade.modules.system.entity.User;
import org.springblade.modules.system.entity.UserInfo;
import org.springblade.modules.system.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.time.Duration;
import java.util.UUID;

/**
 * @author wookvn
 *
 */
@RestController
@RequestMapping(AppConstant.APPLICATION_AUTH_NAME)
@Api(value = "微应用用户授权认证", tags = "微应用授权接口")
public class MicroAppTokenEndPoint {
	
	@Autowired
	private StringRedisTemplate bladeRedis;
	@Autowired
	private IUserService userService;
	
	@Value("${wechatApp.appId}")
	private String appId;
	@Value("${wechatApp.secret}")
	private String secret;
	@Value("${wechatApp.code2SessionUrl}")
	private String code2SessionUrl;

//	@ApiLog("微信登录")
	@PostMapping("/microapp/wxlogin")
	@ApiOperation(value = "微信登录", notes = "传入CODE")
	public Kv wxlogin(@ApiParam(value = "code", required = true) @RequestParam String code) {
		Kv authInfo = Kv.create();
		//1.根据CODE获取openid
		String response = HttpUtil.get(String.format(code2SessionUrl, code));
		JSONObject jsonObject = JSON.parseObject(response);
		if(!jsonObject.containsKey("errcode") || jsonObject.getIntValue("errcode") != 0) {
			return authInfo.set("error_code", HttpServletResponse.SC_BAD_REQUEST).set("error_description", "获取OEPNID失败");
		}
		String openId = jsonObject.getString("openid");
		if(StrUtil.isEmpty(openId)) {
			return authInfo.set("error_code", HttpServletResponse.SC_BAD_REQUEST).set("error_description", "无效的CODE");
		}
		//2.查询openid对应的
		UserInfo userInfo = userService.loginByWx(openId);
		if(userInfo == null) {
			return authInfo.set("error_code", 500).set("error_description", "微信未绑定账号!").set("openId", openId);
		}
		return TokenUtil.createAuthInfo(userInfo);
	}
	
	@PostMapping("/microapp/wxbind")
	@ApiOperation(value = "绑定微信", notes = "传入OPENID,账号:account,密码:password|验证码KEY:header['Captcha-Key'],验证码:header['Captcha-Code']")
	public Kv wxbind(@ApiParam(value = "OPENID", required = true) @RequestParam String openId,
					@ApiParam(value = "账号", required = true) @RequestParam(required = true) String username,
					@ApiParam(value = "密码", required = true) @RequestParam(required = true) String password) {
		
		Kv authInfo = Kv.create();
		
		TokenParameter tokenParameter = new TokenParameter();
		tokenParameter.getArgs().set("tenantId", "000000").set("username", username).set("password", password)
				.set("grantType", CaptchaTokenGranter.GRANT_TYPE).set("userType", UserEnum.APP.getName());

		ITokenGranter granter = TokenGranterBuilder.getGranter(CaptchaTokenGranter.GRANT_TYPE);
		UserInfo userInfo = null;
		try {
			userInfo = granter.grant(tokenParameter);
		} catch (ServiceException e) {
			return authInfo.set("error_code", HttpServletResponse.SC_BAD_REQUEST).set("error_description", e.getMessage());
		}
		if (userInfo == null || userInfo.getUser() == null) {
			return authInfo.set("error_code", HttpServletResponse.SC_BAD_REQUEST).set("error_description", "用户名或密码不正确");
		}

		//更新OPENID
		User entity = new User();
		entity.setId(userInfo.getUser().getId());
		entity.setOpenId(openId);
		userService.updateById(entity);
		
//		if (userInfo.getUser().getIsLogin() == 1) {
//			return authInfo.set("error_code", HttpServletResponse.SC_BAD_REQUEST).set("error_description", "该用户不能使用账号密码登录");
//		}

//		if (Func.isEmpty(userInfo.getRoles())) {
//			return authInfo.set("error_code", HttpServletResponse.SC_BAD_REQUEST).set("error_description", "未获得用户的角色信息");
//		}

		return TokenUtil.createAuthInfo(userInfo);
	}
	
	@GetMapping("/microapp/captcha")
	@ApiOperation(value = "获取验证码")
	public Kv captcha() {
		SpecCaptcha specCaptcha = new SpecCaptcha(130, 48, 5);
		// 设置类型，纯数字、纯字母、字母数字混合
		specCaptcha.setCharType(Captcha.TYPE_ONLY_NUMBER);
		String verCode = specCaptcha.text().toLowerCase();
		String key = UUID.randomUUID().toString();
		// 存入redis并设置过期时间为30分钟
		bladeRedis.opsForValue().set(CacheNames.CAPTCHA_KEY + key, verCode, Duration.ofMinutes(30));
//		bladeRedis.setEx(CacheNames.CAPTCHA_KEY + key, verCode, Duration.ofMinutes(30));
		// 将key和base64返回给前端
		return Kv.create().set("key", key).set("image", specCaptcha.toBase64());
	}
	
}
