package com.ytpm.question.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ytpm.app.enums.AppTypeEnums;
import com.ytpm.app.enums.LoginType;
import com.ytpm.app.model.YtAppDefaultConfig;
import com.ytpm.app.model.YtDyzUser;
import com.ytpm.app.param.AppConfigUpdateParam;
import com.ytpm.app.param.WxLoginParam;
import com.ytpm.app.view.WxDefaultConfig;
import com.ytpm.app.view.WxLoginResult;
import com.ytpm.app.view.WxUserInfo;
import com.ytpm.feign.RiskFeign;
import com.ytpm.general.RepMessage;
import com.ytpm.general.Result;
import com.ytpm.general.StatusCode;
import com.ytpm.question.dao.AppUserMapper;
import com.ytpm.question.service.AppUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
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.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;


@Slf4j
@RestController
@RequestMapping("/wx")
@Api(tags = "微信开放能力模块")
public class WxController {
    private final static String GRANT_TYPE = "authorization_code";

    @Resource
    private AppUserMapper appUserMapper;
    @Resource
    private RiskFeign riskFeign;
    @Resource
    private AppUserService appUserService;

    @PostMapping("/login")
    @ApiOperation("微信登录")
    @Transactional
    public Result<YtDyzUser> wxLogin(@RequestBody WxLoginParam param, HttpServletRequest request) {
        if (StrUtil.isEmpty(param.getDeviceId())) {
            log.warn("[wx login validate]deviceId is empty!");
            // 尝试从phoneJson中获取
            if (StrUtil.isNotEmpty(param.getPhoneJson())) {
                JSONObject phoneJson = JSONObject.parseObject(param.getPhoneJson());
                if (phoneJson.get("device_basic") != null) {
                    String deviveId = phoneJson.getJSONObject("device_basic").getString("device_id");
                    param.setDeviceId(deviveId);
                }
            }
        }
        //根据应用获取配置调用微信接口登录
        WxDefaultConfig defaultConfig = appUserMapper.getDefaultConfig(param.getAppType());
        if (Objects.isNull(defaultConfig)) {
            return new Result<>(StatusCode.ACCESS_ERR, "微信登录失败，未找到相应配置！");
        }
        param.setAppId(defaultConfig.getPlatformAppId());
        WxLoginResult loginResult = getWechatLoginInfo(param.getWxCode(), param.getAppType(), defaultConfig.getAppId(), defaultConfig.getSecret());
        if (Objects.isNull(loginResult) || StrUtil.isBlank(loginResult.getOpenid())) {
            return new Result<>(StatusCode.ACCESS_ERR, "微信登录失败，请刷新授权码！");
        }
        WxUserInfo wxUserInfo = getWechatUserInfo(loginResult.getAccess_token(), loginResult.getOpenid());
        if (Objects.isNull(wxUserInfo)) {
            return new Result<>(StatusCode.ACCESS_ERR, "微信用户登录失败");
        }
        param.setLoginIp(getClientIp(request));
        YtDyzUser old = appUserService.crudForNewTrans(param, wxUserInfo, loginResult);
        old.setLoginType(LoginType.WX);
        //调用风控服务校验默认风控配置
        old.setRiskCode("313");
        Result<?> result = riskFeign.checkRisk(old);
        if (result.getCode() != 200) {
            return new Result<>(StatusCode.ACCESS_ERR, result.getMessage());
        }
        return Result.resultOk(RepMessage.LOGIN_SUCCESS, old);
    }

    private String getClientIp(HttpServletRequest request) {
        String xfHeader = request.getHeader("X-Forwarded-For");
        if (xfHeader == null) {
            return request.getRemoteAddr();
        }
        return xfHeader.split(",")[0]; // 可能会有多个IP，这里取第一个逗号前的IP
    }

    /**
     * 获取微信用户信息
     */
    private WxUserInfo getWechatUserInfo(String accessToken, String openid) {
        // 根据token和openid 获取用户信息
        String userInfoUrl = "https://api.weixin.qq.com/sns/userinfo?access_token=" + accessToken + "&openid=" + openid + "&lang=zh_CN";
        String curUser = HttpUtil.get(userInfoUrl);
        WxUserInfo wxUserInfo = JSON.parseObject(curUser, WxUserInfo.class);
        log.info("[wx Login]获取的用户信息:{}", wxUserInfo);
        return wxUserInfo;
    }

    /**
     * 微信登录
     */
    private WxLoginResult getWechatLoginInfo(String wxCode, int appType, String appId, String secret) {

        String wxLoginUrl;
        if (AppTypeEnums.QNJZ.getCode() == appType) {
            wxLoginUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?appid="
                    + appId + "&secret=" + secret + "&code=" + wxCode + "&grant_type=" + GRANT_TYPE;
        } else {
            wxLoginUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + appId
                    + "&secret=" + secret + "&code=" + wxCode + "&grant_type=" + GRANT_TYPE;
        }
        //拿到授权码 请求微信登录返回access_token
        String result = HttpUtil.get(wxLoginUrl);
        WxLoginResult loginResult = JSON.parseObject(result, WxLoginResult.class);
        log.info("[wx Login]授权码获取的登录结果:{}", loginResult);
        return loginResult;
    }

    @ApiOperation("获取微信默认配置项")
    @GetMapping("/defaultConfig")
    public Result<WxDefaultConfig> getWxDefaultConfig(int appType) {
        WxDefaultConfig config = appUserMapper.getDefaultConfig(appType);
        if (Objects.isNull(config)) {
            return Result.resultErr("应用类型有误！");
        }
        return Result.resultObjOk(config);
    }

    @ApiOperation("体力增加")
    @GetMapping("/addPower")
    @Transactional(rollbackFor = Exception.class)
    @Deprecated
    public Result<YtDyzUser> addPower(@RequestParam("userId") String userId) {
//        appUserMapper.addOnePower(userId);
//        YtDyzPowerRecord record = new YtDyzPowerRecord();
//        record.setUserId(userId);
//        record.setRecordId(IdUtil.fastSimpleUUID());
//        record.setAddTime(new Date());
//        record.setType(1);
//        record.setRemark("增加体力");
//        appUserMapper.addPowerRecord(record);
        return Result.resultOk(RepMessage.ADD_SUCCESS);
    }

    @ApiOperation("保存应用默认配置")
    @PostMapping("/saveAppConfig")
    public Result<String> saveAppConfig(@RequestBody YtAppDefaultConfig defaultConfig) {
        appUserMapper.saveAppConfig(defaultConfig);
        return Result.resultOk(RepMessage.SAVE_SUCCESS);
    }

    @ApiOperation("修改应用默认配置")
    @PostMapping("/updateAppConfig")
    public Result<String> updateAppConfig(@RequestBody YtAppDefaultConfig defaultConfig) {
        appUserMapper.updateAppConfig(defaultConfig);
        return Result.resultOk(RepMessage.SAVE_SUCCESS);
    }

    @ApiOperation("同步子应用默认配置")
    @PostMapping("/updateAppsConfig")
    public void updateAppsConfig(@RequestBody AppConfigUpdateParam param){
        if (CollUtil.isNotEmpty(param.getApps()) && param.getDefaultConfig() != null) {
            String appIds = String.join(",", param.getApps());
            List<WxDefaultConfig> configs = appUserMapper.getConfigByIds(appIds);
            YtAppDefaultConfig updateInfo = param.getDefaultConfig();
            for (WxDefaultConfig config : configs) {
                YtAppDefaultConfig appConfig = new YtAppDefaultConfig();
                BeanUtils.copyProperties(config, appConfig);
                if(StrUtil.isNotEmpty(updateInfo.getTakuAppId())) {
                    appConfig.setTakuAppId(updateInfo.getTakuAppId());
                }
                if(StrUtil.isNotEmpty(updateInfo.getTakuKey())) {
                    appConfig.setTakuKey(updateInfo.getTakuKey());
                }
                if(StrUtil.isNotEmpty(updateInfo.getTakuBannerPid())) {
                    appConfig.setTakuBannerPid(updateInfo.getTakuBannerPid());
                }
                if(StrUtil.isNotEmpty(updateInfo.getTakuNativePid())) {
                    appConfig.setTakuNativePid(updateInfo.getTakuNativePid());
                }
                if(StrUtil.isNotEmpty(updateInfo.getTakuRewardPid())) {
                    appConfig.setTakuRewardPid(updateInfo.getTakuRewardPid());
                }
                if(StrUtil.isNotEmpty(updateInfo.getTakuInterstitialPid())) {
                    appConfig.setTakuInterstitialPid(updateInfo.getTakuInterstitialPid());
                }
                appUserMapper.updateAppConfig(appConfig);
            }
        }
    }

    @ApiOperation("根据APP_ID获取配置")
    @GetMapping("/getConfigs")
    public List<WxDefaultConfig> getConfigs(@RequestParam(name = "appIds") String appIds) {
        List<WxDefaultConfig> configs = new ArrayList<>();
        List<WxDefaultConfig> dyzConfigs = appUserMapper.getConfigByIds(appIds);
        if (CollUtil.isNotEmpty(dyzConfigs)) {
            configs.addAll(dyzConfigs);
        }
        return configs;
    }

    @ApiOperation("删除默认配置")
    @GetMapping("/delDefaultConfig")
    public void delDefaultConfig(@RequestParam(name = "appId") String appId) {
        List<WxDefaultConfig> dyzConfig = appUserMapper.getConfigByIds(appId);
        if (CollUtil.isNotEmpty(dyzConfig)) {
            appUserMapper.delByAppId(appId);
        }
    }
}
