package org.jeecg.modules.ctop.controller;

import cn.com.ctop.common.module.entity.CtopOauthToken;
import cn.com.ctop.common.module.entity.UserAllocation;
import cn.com.ctop.common.module.mapper.UserAllocationMapper;
import cn.com.ctop.common.module.service.IBindAccountAuthService;
import cn.com.ctop.common.module.service.ICtopOauthTokenService;
import cn.com.ctop.common.module.utils.*;
import cn.com.ctop.kuaishou.modules.batch.service.IKuaishouInterfaceService;
import cn.com.ctop.kuaishou.modules.material.entity.KuaishouAccessToken;
import cn.com.ctop.kuaishou.modules.material.entity.KuaishouResultToken;
import cn.com.ctop.toutiao.service.IByteDanceAdvertiserDataService;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.apache.commons.lang.StringUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.system.api.ISysBaseApi;
import org.jeecg.common.system.util.JwtUtil;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.modules.system.entity.SysDepart;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.service.ISysDepartService;
import org.jeecg.modules.system.service.ISysLogService;
import org.jeecg.modules.system.service.ISysUserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
public class CallbackController {
    private static final Logger logger = LoggerFactory.getLogger(CallbackController.class);
    @Autowired
    private ISysUserService sysUserService;
    @Autowired
    private ISysBaseApi sysBaseApi;
    @Autowired
    private ISysLogService logService;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private ISysDepartService sysDepartService;
    @Autowired
    private IKuaishouInterfaceService kuaishouInterfaceService;

    @Autowired
    private IBindAccountAuthService bindAccountAuthService;

    @Autowired
    private UserAllocationMapper allocationMapper;

    @Autowired
    private ICtopOauthTokenService ctopOauthTokenService;

    @GetMapping("/qywexin")
    @ResponseBody
    public void qywexin(HttpServletRequest request,
                        HttpServletResponse response,
                        @RequestParam("code") String code,
                        @RequestParam("state") String state) throws IOException {
        response.sendRedirect(state + "?code=" + code);
    }

    /**
     * 用户信息
     *
     * @param sysUser
     * @param result
     * @return
     */
    private Result<JSONObject> userInfo(SysUser sysUser, Result<JSONObject> result) {
        String syspassword = sysUser.getPassword();
        String username = sysUser.getUsername();
        // 生成token
        String token = JwtUtil.sign(username, syspassword);
        redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token);
        // 设置超时时间
        redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME / 1000);

        // 获取用户部门信息
        JSONObject obj = new JSONObject();
        List<SysDepart> departs = sysDepartService.queryUserDeparts(sysUser.getId());
        obj.put("departs", departs);
        if (departs == null || departs.size() == 0) {
            obj.put("multi_depart", 0);
        } else if (departs.size() == 1) {
            sysUserService.updateUserDepart(username, departs.get(0).getOrgCode());
            obj.put("multi_depart", 1);
        } else {
            obj.put("multi_depart", 2);
        }
        obj.put("token", token);
        obj.put("userInfo", sysUser);
        result.setResult(obj);
        result.success("登录成功");
        return result;
    }

    /**
     * TODO 授权绑定成功/失败 需要跳转特定页面
     *
     * @param request
     * @param response
     * @param authCode
     * @param state
     * @return
     */
    @GetMapping("/kuaishou")
    @ResponseBody
    public String kuaishou(HttpServletRequest request,
                           HttpServletResponse response,
                           @RequestParam("auth_code") String authCode,
                           @RequestParam("state") String state) {
        try {
            JSONObject json = JSONObject.parseObject(state);
            if (Check.isNull(json)) {
                throw new Exception("回调信息为空");
            }
            if (StringUtils.isNotBlank(authCode)) {
                KuaishouResultToken accessToken = kuaishouInterfaceService.getAccessToken(authCode);
                if (accessToken.getCode() != 0) {
                    throw new Exception("快手回调token返回错误");
                }
                KuaishouAccessToken token = accessToken.getData();
                if (token != null) {
                    Long accountId = token.getAccountId();
                    if (Check.isNull(accountId)) {
                        return "授权绑定失败！";
                    }


                    String advertiserId = json.getString("advertiserId");
                    //指定分配人姓名
                    String userName = json.getString("userName");
                    // 广告主名称
                    String advertiserName = json.getString("advertiser_name");
                    // 媒体类型： 1 头条 2 快手
                    String mediaId = json.getString("mediaId");
                    //创建人
                    String userId = json.getString("userId");
                    Long projectId = json.getLong("projectId");

                    CtopOauthToken topOauthToken = new CtopOauthToken();
                    topOauthToken.setId(String.valueOf(accountId));
                    topOauthToken.setAccountId(accountId);
                    topOauthToken.setMediaId("2");
                    topOauthToken.setAdvertiserId(advertiserId);
                    topOauthToken.setAccessToken(token.getAccessToken());
                    long accessTokenExpireIn = token.getAccessTokenExpiresIn() * 1000L;
                    long now = System.currentTimeMillis();
                    Date accessTokenExpireInDate = new Date(now + accessTokenExpireIn);
                    topOauthToken.setAccessTokenExpiresIn(accessTokenExpireInDate);
                    topOauthToken.setRefreshToken(token.getRefreshToken());
                    long refreshTokenExpireIn = token.getRefreshTokenExpiresIn() * 1000L;
                    Date refreshTokenExpireInDate = new Date(now + refreshTokenExpireIn);
                    topOauthToken.setRefreshTokenExpiresIn(refreshTokenExpireInDate);
                    topOauthToken.setUpdateTime(new Date());
                    ctopOauthTokenService.saveOrUpdate(topOauthToken);


                    QueryWrapper<UserAllocation> userAllocationQueryWrapper = new QueryWrapper<>();
                    userAllocationQueryWrapper.eq("account_id", accountId);
                    userAllocationQueryWrapper.eq("media_id", 2);
                    userAllocationQueryWrapper.orderByDesc("create_time");
                    userAllocationQueryWrapper.last("limit 1");
                    UserAllocation checkUserAllocation = allocationMapper.selectOne(userAllocationQueryWrapper);
                    if (!Check.isNull(checkUserAllocation)) {
                        return "授权失败，该账号已被：" + checkUserAllocation.getUserName() + " 绑定！";
                    }
                    String projectName = json.getString("projectName");
                    UserAllocation userAllocation = new UserAllocation();
                    userAllocation.setUserName(userName);
                    userAllocation.setUserId(userId);
                    userAllocation.setAdvertiserId(advertiserId);
                    // 获取快手昵称
                    Map<String, Object> advertiseBaseInfoMap = kuaishouInterfaceService.advertiserInfo(accountId, token.getAccessToken());
                    if ((Integer) advertiseBaseInfoMap.get("code") == 0) {
                        userAllocation.setAuthName((String) advertiseBaseInfoMap.get("userName"));
                    }
                    userAllocation.setAdvertiserName(advertiserName);
                    userAllocation.setMediaId(mediaId);
                    userAllocation.setAccountId(accountId);
                    userAllocation.setProjectId(projectId);
                    userAllocation.setProjectName(projectName);
                    userAllocation.setCreateTime(new Date());
                    userAllocation.setUpdateTime(new Date());
                    allocationMapper.deleteById(userAllocation.getId());
                    Map<String, Object> deleteUserMap = new HashMap<>();
                    deleteUserMap.put("advertiser_id", advertiserId);
                    deleteUserMap.put("account_id", accountId);
                    allocationMapper.deleteByMap(deleteUserMap);
                    int i = allocationMapper.insert(userAllocation);
                    if (i > 0) {
                        logger.info("同步分配用户表完成,task_id:{},accountId:{}", state, accountId);
                    }

                    //账号绑定
                    bindAccountAuthService.addBindAccount(accountId, KuaishouInterfaceConstant.LOGIN_TYPE_KUAISHOU, advertiserId);
                    Thread t = new Thread() {
                        @Override
                        public void run() {
                            kuaishouInterfaceService.loadKuaishouDataSingle(topOauthToken);
                        }
                    };
                    t.start();
                }
                return "授权绑定成功";
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "授权绑定失败！";
    }

    @RequestMapping("/bytedance")
    @ResponseBody
    public String bytedance(HttpServletRequest request,
                            HttpServletResponse response,
                            @RequestParam("auth_code") String authCode,
                            @RequestParam("state") String state) {

        if (StringUtils.isNotBlank(authCode)) {
            Map<String, Object> map = this.getByteDanceAccessToken(authCode, state);
            Integer code = (Integer) map.get("code");
            if (code == 0) {
                return "授权绑定成功";
            }
        }
        return "授权绑定失败";
    }

    @Autowired
    private IByteDanceAdvertiserDataService advertiserDataService;

    public Map<String, Object> getByteDanceAccessToken(String authCode, String state) {
        Map<String, Object> param = new HashMap<>();
        param.put("app_id", PropertiesUtils.getValue("bytedance_config", "bytedance_appid"));
        param.put("secret", PropertiesUtils.getValue("bytedance_config", "bytedance_secret"));
        param.put("grant_type", "auth_code");
        param.put("auth_code", authCode);
        logger.info("authCode:{}", authCode);
        logger.info("state:{}", state);
        Map<String, Object> returnMap = new HashMap<>();
        try {
            JSONObject json = JSONObject.parseObject(state);
            if (Check.isNull(json)) {
                throw new Exception("回调信息为空");
            }
            String result = HttpUtils.httpPostRequest(PropertiesUtils.getValue("bytedance_config", "bytedance_api_url") + BytedanceInterfaceConstant.AUTH_TOKEN, param, new HashMap<>());
            JSONObject resultObject = JSONObject.parseObject(result);
            logger.info("返回信息：{}", resultObject);
            Integer code = resultObject.getInteger("code");
            String message = resultObject.getString("message");
            if (null == code || code != 0) {
                logger.error("获取token失败,state:{},message:{}", state, message);
                throw new Exception("token返回码异常");
            }
            //广告主id
            String advertiserId = json.getString("advertiserId");
            // 媒体类型： 1 头条 2 快手
            String mediaId = json.getString("mediaId");

            // 广告主名称
            String advertiserName = json.getString("advertiser_name");
            //创建人
            String userId = json.getString("userId");
            //创建人
            String userName = json.getString("userName");
            Long projectId = json.getLong("projectId");
            String projectName = json.getString("projectName");

            JSONObject data = resultObject.getJSONObject("data");
            CtopOauthToken token = new CtopOauthToken(advertiserId, data);
            ctopOauthTokenService.saveOrUpdate(token);
            //获取广告主信息
            Map<String, Object> advertiserDataMap = advertiserDataService.getAdvertiserInfo(token.getAccountId() + "");
            Boolean getSuccess = (Boolean) advertiserDataMap.get("success");
            if (null == getSuccess || !getSuccess) {
                logger.info("获取广告主信息失败,accountId:{},message:{}", token.getAccountId(), (String) advertiserDataMap.get("message"));
                throw new Exception("获取广告主信息失败");
            }

            Long accountId = token.getAccountId();
            QueryWrapper<UserAllocation> userAllocationQueryWrapper = new QueryWrapper<>();
            userAllocationQueryWrapper.eq("account_id", accountId);
            userAllocationQueryWrapper.eq("media_id", 1);
            userAllocationQueryWrapper.orderByDesc("create_time");
            userAllocationQueryWrapper.last("limit 1");
            UserAllocation checkUserAllocation = allocationMapper.selectOne(userAllocationQueryWrapper);
            if (!Check.isNull(checkUserAllocation)) {
                returnMap.put("code", -1);
                returnMap.put("desc", "授权失败，账号已被：" + checkUserAllocation.getUserName() + "绑定");
            }

            UserAllocation userAllocation = new UserAllocation();
            userAllocation.setUserId(userId);
            userAllocation.setUserName(userName);
            userAllocation.setAccountId(token.getAccountId());
            userAllocation.setAdvertiserName(advertiserName);
            userAllocation.setMediaId(mediaId);
            userAllocation.setProjectId(projectId);
            userAllocation.setProjectName(projectName);
            userAllocation.setAuthName((String) advertiserDataMap.get("name"));
            userAllocation.setAdvertiserId(advertiserId);
            userAllocation.setCreateTime(new Date());
            userAllocation.setUpdateTime(new Date());
            allocationMapper.deleteById(userAllocation.getId());
            Map<String, Object> deleteUserMap = new HashMap<>();
            deleteUserMap.put("advertiser_id", advertiserId);
            deleteUserMap.put("account_id", token.getAccountId());
            allocationMapper.deleteByMap(deleteUserMap);
            int i = allocationMapper.insert(userAllocation);
            if (i > 0) {
                logger.info("同步分配用户表完成,task_id:{},accountId:{}", state, token.getAccountId());

            }
            //账号绑定
            bindAccountAuthService.addBindAccount(token.getAccountId(), KuaishouInterfaceConstant.LOGIN_TYPE_BYTEDANCE, advertiserId);
            returnMap.put("code", 0);
            returnMap.put("desc", "success");
        } catch (Exception e) {
            e.printStackTrace();
            returnMap.put("code", -1);
            returnMap.put("desc", "回调token异常");

        }
        return returnMap;
    }

}
