package bus.service.impl;

import bus.model.RedisUtil;
import bus.model.SnowflakeUtil;
import bus.model.dto.CommonLoginDto;
import bus.model.dto.WChatUserDto;
import bus.model.dto.page.WChatUserPageDto;
import bus.model.dto.req.WxLoginReq;
import bus.model.po.WChatUserPo;
import bus.mapper.WChatUserMapper;

import bus.service.CommonService;
import bus.service.WChatUserService;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import com.jcraft.jsch.HASH;
import com.orcas.common.sso.model.SsoUserAuthDto;
import com.orcas.common.usercenter.entity.RoleEntity;
import com.orcas.common.usercenter.entity.StaffEntity;
import com.orcas.common.usercenter.model.StaffBindRoleDto;
import com.orcas.common.usercenter.model.StaffRequest;
import com.orcas.iso.service.RoleClient;
import com.orcas.iso.service.StaffClient;
import com.orcas.iso.service.UserClient;
import com.qzwisdom.qzframework.core.tool.exception.BusinessException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.BeanUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @Program: bus
 * @Description: 描述
 * @Author: zy
 * @Date: 2025-02-28 16:46:43
 **/
@Service
public class WChatUserServiceImpl implements WChatUserService {

    @Autowired
    private WChatUserMapper wChatUserMapper;
    @Autowired
    private StaffClient staffClient;
    @Autowired
    private UserClient userClient;
    @Autowired
    private RoleClient roleClient;
    @Autowired
    private CommonService commonService;
    @Value("${orcas.organizeId}")
    private String organizeId;
    @Value("${orcas.creditCode}")
    private String creditCode;
    @Value("${orcas.productId}")
    private String productId;
    @Value("${orcas.productNo}")
    private String productNo;
    @Resource
    private SnowflakeUtil snowflakeUtil;
    @Resource
    private RedisUtil redisUtil;

    private static final String WX_ACCESS_TOKEN_KEY = "wx:access_token";
    // access_token 有效期为 7200 秒，我们设置缓存时间为 7000 秒，留出一些余量
    private static final long ACCESS_TOKEN_EXPIRE = 7000L;
    private static final int TIME_OUT  = 3000;

    private static final String ERROR_CODE_STR = "errcode";

    @Override
    public SsoUserAuthDto wxLogin(HttpServletRequest request, HttpServletResponse response, WxLoginReq wxLoginReq) {
        //根据用户名称查询底座接口
        String mobile = wxLoginReq.getMobile();
        String sub = "wx@" + StrUtil.sub(mobile, mobile.length() - 6, mobile.length());
        String wxName = wxLoginReq.getWxName();
        StaffEntity staffByUserName = staffClient.getStaffByUserName(mobile, organizeId);
        if (staffByUserName == null) {
            //注册用户
            StaffRequest req = new StaffRequest();
            req.setPhone(mobile);
            req.setAccountName(mobile);
            req.setPassword(sub);
            req.setStaffName(mobile);
            req.setUnitOrganizeId(organizeId);
            req.setUniformCreditCode(creditCode);
            req.setIsAdmin(0);
            staffByUserName = staffClient.addStaff(req);
            //保存数据库
            WChatUserDto dto = new WChatUserDto();
            dto.setMiniOpenId(dto.getMiniOpenId());
            dto.setLastLoginTime(new Date());
            dto.setWxName(mobile);
            dto.setWxPhone(mobile);
            save(dto);
        }
        List<HashMap<String,Object>> roleListByProId = (List<HashMap<String,Object>>) roleClient.getRoleListByProId(productId);
        List<String> filteredRoles = new ArrayList<>();
        for (HashMap<String,Object> roleEntity : roleListByProId) {
            if ("wx".equals(roleEntity.get("code"))) {
                filteredRoles.add(roleEntity.get("id").toString());
                break;
            }
        }
        //绑定角色
        StaffBindRoleDto staffBindRoleDto = new StaffBindRoleDto();
        staffBindRoleDto.setRoleIds(filteredRoles);
        staffBindRoleDto.setProductNo(productNo);
        staffBindRoleDto.setUnitOrganizeId(organizeId);
        staffBindRoleDto.setStaffId(staffByUserName.getId());
        roleClient.staffBindRole(staffBindRoleDto);
        //登录
        CommonLoginDto userLoginRequest = new CommonLoginDto();
        userLoginRequest.setAccount(mobile);
        userLoginRequest.setPassword(sub);
        SsoUserAuthDto ssoUserAuthDto = commonService.doLogin(request, response, userLoginRequest);

        return ssoUserAuthDto;
    }

    /**
     * 详情
     *
     * @param id
     * @return
     */
    @Override
    public WChatUserPo getDetailById(String id) {
        return this.wChatUserMapper.selectById(id);
    }

    /**
     * 保存
     *
     * @param dto
     * @return
     */
    @Override
    public void save(WChatUserDto dto) {
        WChatUserPo po = new WChatUserPo();
        BeanUtils.copyProperties(dto, po);
        po.setId(snowflakeUtil.snowflakeId());
        po.setCreateTime(new Date());
        po.setUpdateTime(new Date());
        this.wChatUserMapper.insert(po);
    }

    /**
     * 列表
     *
     * @param dto
     * @return
     */
    @Override
    public List<WChatUserDto> list(WChatUserPageDto dto) {
        return this.wChatUserMapper.list(dto);
    }

    /**
     * 修改
     *
     * @param dto
     * @return
     */
    @Override
    public void update(WChatUserDto dto) {
        WChatUserPo po = new WChatUserPo();
        BeanUtils.copyProperties(dto, po);
        wChatUserMapper.updateById(po);
    }

    /**
     * 删除
     *
     * @param id
     * @return
     */
    @Override
    public void delete(String id) {
        wChatUserMapper.deleteById(id);
    }

    @Override
    public String getAccessToken(String appId, String appSecret)  {
        // 先从Redis获取
        String accessToken = redisUtil.get(WX_ACCESS_TOKEN_KEY);
        if (StrUtil.isNotBlank(accessToken)) {
            return accessToken;
        }
        // Redis中不存在，则从微信服务器获取
        String accessTokenUrl = "https://api.weixin.qq.com/cgi-bin/token" +
                "?grant_type=client_credential" +
                "&appid=" + appId +
                "&secret=" + appSecret;

        String tokenJson = HttpUtil.get(accessTokenUrl, TIME_OUT);
        JSONObject tokenObj = new JSONObject(tokenJson);
        if (tokenObj.get(ERROR_CODE_STR) != null && tokenObj.get(ERROR_CODE_STR, Integer.class) != 0) {
            throw new BusinessException("获取access_token失败");
        }

        // 获取新的access_token
        accessToken = tokenObj.getStr("access_token");
        // 存入Redis并设置过期时间
        redisUtil.set(
                WX_ACCESS_TOKEN_KEY,
                accessToken,
                ACCESS_TOKEN_EXPIRE,
                TimeUnit.SECONDS
        );
        return accessToken;
    }
}
