package cn.hanghui.outapi.platform.tenant.service.impl;

import cn.hanghui.outapi.platform.common.entity.rest.RestCode;
import cn.hanghui.outapi.platform.common.entity.rest.RestResult;
import cn.hanghui.outapi.platform.common.utils.AppUtils;
import cn.hanghui.outapi.platform.tenant.entity.dto.IotPlatformAuthDto;
import cn.hanghui.outapi.platform.tenant.entity.dto.IotPlatformAuthReqDto;
import cn.hanghui.outapi.platform.tenant.entity.dto.IotUserInfoDto;
import cn.hanghui.outapi.platform.tenant.entity.po.IotPlatformAuth;
import cn.hanghui.outapi.platform.tenant.entity.po.IotReqLog;
import cn.hanghui.outapi.platform.tenant.entity.po.IotUserInfo;
import cn.hanghui.outapi.platform.tenant.mapper.IotPlatformAuthMapper;
import cn.hanghui.outapi.platform.tenant.mapper.IotReqLogMapper;
import cn.hanghui.outapi.platform.tenant.mapper.IotUserInfoMapper;
import cn.hanghui.outapi.platform.tenant.service.AlipayIotService;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;

/**
 * @author shisl
 * @package cn.hanghui.outapi.platform.tenant.service.impl
 * @class AlipayIotServiceImpl
 * @date 2023/6/9 下午1:25
 * @description
 */
@Slf4j
@Service
public class AlipayIotServiceImpl implements AlipayIotService {

    @Resource
    private IotUserInfoMapper iotUserInfoMapper;

    @Resource
    private IotPlatformAuthMapper iotPlatformAuthMapper;

    @Resource
    private IotReqLogMapper iotReqLogMapper;


    @Override
    public RestResult<Boolean> addAuth(IotPlatformAuthDto dto) {
        IotPlatformAuth auth = null;
        if (dto.getId() != null) {
            auth = iotPlatformAuthMapper.selectById(dto.getId());
            if (auth == null || auth.getIsDeleted()) {
                return RestResult.error("数据不存在或已删除");
            }
            if (dto.getReqTimesLimit() != null && auth.getReqTimesLimit() != null
                    && auth.getReqTimesLimit().intValue() != dto.getReqTimesLimit().intValue()) {
                //插入记录
                addIotReqLog(auth.getId(), dto.getReqTimesLimit().intValue() - auth.getReqTimesLimit().intValue(), auth.getToken());
            }
            auth.setAreaName(dto.getAreaName());
            auth.setCompanyName(dto.getCompanyName());
            auth.setContactPerson(dto.getContactPerson());
            auth.setDataSource(dto.getDataSource());
            auth.setPcsCode(dto.getPcsCode());
            auth.setPcsName(dto.getPcsName());
            auth.setPhone(dto.getPhone());
            auth.setReqTimesLimit(dto.getReqTimesLimit());
            auth.setScene(dto.getScene());
            auth.setUpdateTime(new Date());
            iotPlatformAuthMapper.updateById(auth);
        } else {
            auth = new IotPlatformAuth();
            auth.setAreaName(dto.getAreaName());
            auth.setCompanyName(dto.getCompanyName());
            auth.setContactPerson(dto.getContactPerson());
            auth.setDataSource(dto.getDataSource());
            auth.setPcsCode(dto.getPcsCode());
            auth.setPcsName(dto.getPcsName());
            auth.setPhone(dto.getPhone());
            auth.setReqTimesLimit(dto.getReqTimesLimit());
            auth.setScene(dto.getScene());
            auth.setUpdateTime(new Date());
            auth.setToken(generateToken());
            auth.setIsDeleted(Boolean.FALSE);
            auth.setCreateTime(new Date());
            auth.setVersion(1);
            auth.setStatus(Boolean.TRUE);
            auth.setUsedReqTimes(0);
            iotPlatformAuthMapper.insert(auth);
            //插入记录
            addIotReqLog(auth.getId(), auth.getReqTimesLimit(), auth.getToken());
        }
        return RestResult.ok(Boolean.TRUE);
    }

    private void addIotReqLog(Long authId, int reqTimes, String token) {
        IotReqLog log = new IotReqLog();
        log.setIotPlatformAuthId(authId);
        log.setReqTimes(reqTimes);
        log.setToken(token);
        log.setCreateTime(new Date());
        log.setIsDeleted(Boolean.FALSE);
        log.setUpdateTime(new Date());
        log.setVersion(1);
        iotReqLogMapper.insert(log);
    }

    @Override
    public RestResult<Boolean> del(Long id) {
        IotPlatformAuth auth = iotPlatformAuthMapper.selectById(id);
        if (auth != null && !auth.getIsDeleted()) {
            auth.setIsDeleted(Boolean.TRUE);
            iotPlatformAuthMapper.updateById(auth);
        }
        return RestResult.ok(Boolean.TRUE);
    }

    @Override
    public RestResult<Boolean> opStatus(Long id, Boolean status) {
        IotPlatformAuth auth = iotPlatformAuthMapper.selectById(id);
        if (auth != null && !auth.getIsDeleted()) {
            auth.setStatus(status);
            iotPlatformAuthMapper.updateById(auth);
        }
        return RestResult.ok(Boolean.TRUE);
    }

    @Override
    public RestResult<IPage<IotPlatformAuthDto>> page(IotPlatformAuthReqDto dto) {
        Page<IotPlatformAuth> page = new Page<>(dto.getPageNumber(), dto.getPageSize());
        LambdaQueryWrapper<IotPlatformAuth> wrapper = new LambdaQueryWrapper<>();
        if (dto.getCompanyName() != null && !"".equals(dto.getCompanyName().trim())) {
            wrapper.like(IotPlatformAuth::getCompanyName, dto.getCompanyName().trim());
        }
        if (dto.getToken() != null && !"".equals(dto.getToken().trim())) {
            wrapper.like(IotPlatformAuth::getToken, dto.getToken().trim());
        }
        wrapper.eq(IotPlatformAuth::getIsDeleted, Boolean.FALSE).orderByDesc(IotPlatformAuth::getId);
        IPage<IotPlatformAuth> iPage = iotPlatformAuthMapper.selectPage(page, wrapper);
        IPage<IotPlatformAuthDto> convert = iPage.convert(t -> {
            IotPlatformAuthDto item = BeanUtil.copyProperties(t, IotPlatformAuthDto.class);
            return item;
        });
        return RestResult.ok(convert);
    }

    @Override
    public RestResult<Boolean> checkToken(String token) {
        RestResult<IotPlatformAuth> authRestResult = validateToken(token);
        if (authRestResult.getCode() != RestCode.SUCCESS.getCode()) {
            return RestResult.error(Boolean.FALSE, authRestResult.getMsg());
        }
        IotPlatformAuth auth = authRestResult.getData();
        //调用次数+1
        if (auth.getReqTimesLimit() != null && auth.getReqTimesLimit().intValue() != -1) {
            iotPlatformAuthMapper.increaseReqTimesById(auth.getId());
        }
        //插入记录
        addIotReqLog(auth.getId(), -1, auth.getToken());
        return RestResult.ok(Boolean.TRUE);
    }

    @Override
    public RestResult<Boolean> userPush(IotUserInfoDto dto) {
        if (dto.getTaskId() == null
                || dto.getCertName() == null
                || dto.getCertNo() == null
                || dto.getToken() == null) {
            return RestResult.error(Boolean.FALSE, "请求参数有误，请检查后提交");
        }

        RestResult<IotPlatformAuth> authRestResult = validateToken(dto.getToken());
        if (authRestResult.getCode() != RestCode.SUCCESS.getCode()) {
            return RestResult.error(Boolean.FALSE, authRestResult.getMsg());
        }

        if (dto.getPushUrl() == null || "".equals(dto.getPushUrl().trim())) {
            LambdaQueryWrapper<IotUserInfo> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(IotUserInfo::getTaskId, dto.getTaskId())
                    .eq(IotUserInfo::getToken, dto.getToken())
                    .eq(IotUserInfo::getIsDeleted, Boolean.FALSE);
            IotUserInfo userInfo = iotUserInfoMapper.selectOne(wrapper);
            if (userInfo != null) {
                return RestResult.error(Boolean.FALSE, "数据已存在请勿重复提交");
            }

            IotUserInfo iotUserInfo = BeanUtil.copyProperties(dto, IotUserInfo.class);
            iotUserInfo.setCertType(iotUserInfo.getCertType() == null ? "IDENTITY_CARD" : iotUserInfo.getCertType());
            iotUserInfo.setCreateTime(new Date());
            iotUserInfo.setUpdateTime(new Date());
            iotUserInfo.setIsDeleted(Boolean.FALSE);
            iotUserInfo.setVersion(1);
            iotUserInfoMapper.insert(iotUserInfo);
        }

        //三方用户三要素信息数据推送
        if (dto.getPushUrl() != null && !"".equals(dto.getPushUrl().trim())) {
            //推送数据到第三方服务
            pushIotUserInfo(dto);
        }
        return RestResult.ok(Boolean.TRUE, "推送成功");
    }

    //GET请求 三方用户三要素信息数据推送
    private void pushIotUserInfo(IotUserInfoDto dto) {
        try {
            String resp = HttpUtil.post(dto.getPushUrl(), JSONObject.toJSONString(dto), 5000);
            log.info("--->三方地址推送成功:{}", JSONObject.toJSONString(resp));
        } catch (Exception e) {
            log.error("--->三方地址推送异常", e);
        }
    }

    @Override
    public RestResult<IotUserInfoDto> userQuery(IotUserInfoDto dto) {
        if (dto.getTaskId() == null
                || dto.getToken() == null) {
            return RestResult.error(new IotUserInfoDto(), "请求参数有误，请检查后提交");
        }

        RestResult<IotPlatformAuth> authRestResult = validateToken(dto.getToken());
        if (authRestResult.getCode() != RestCode.SUCCESS.getCode()) {
            return RestResult.error(new IotUserInfoDto(), authRestResult.getMsg());
        }

        LambdaQueryWrapper<IotUserInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(IotUserInfo::getTaskId, dto.getTaskId())
                .eq(IotUserInfo::getToken, dto.getToken())
                .eq(IotUserInfo::getIsDeleted, Boolean.FALSE);
        IotUserInfo userInfo = iotUserInfoMapper.selectOne(wrapper);
        if (userInfo == null) {
            return RestResult.error(new IotUserInfoDto(), "查询数据不存在");
        }
        IotUserInfoDto infoDto = BeanUtil.copyProperties(userInfo, IotUserInfoDto.class);
        return RestResult.ok(infoDto);
    }

    @Override
    public RestResult<IotPlatformAuth> validateToken(String token) {
        if (token == null) {
            return RestResult.error(new IotPlatformAuth(), "无权访问，请联系管理员");
        }
        LambdaQueryWrapper<IotPlatformAuth> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(IotPlatformAuth::getToken, token)
                .eq(IotPlatformAuth::getStatus, Boolean.TRUE)
                .eq(IotPlatformAuth::getIsDeleted, Boolean.FALSE);
        IotPlatformAuth auth = iotPlatformAuthMapper.selectOne(wrapper);
        if (auth == null) {
            return RestResult.error(auth, "无权访问，请联系管理员");
        }
        Integer reqTimes = auth.getReqTimesLimit();
        Integer usedReqTimes = auth.getUsedReqTimes();
        if (reqTimes != null && reqTimes.intValue() != -1 && reqTimes.intValue() - usedReqTimes.intValue() <= 0) {
            return RestResult.error(auth, "用户三要素授权调用次数不足，请联系管理员");
        }
        return RestResult.ok(auth);
    }

    private String generateToken() {
        boolean existFlag = true;
        String token = null;
        while (existFlag) {
            token = AppUtils.getAppSecret(AppUtils.getAppKey());
            LambdaQueryWrapper<IotPlatformAuth> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(IotPlatformAuth::getToken, token).eq(IotPlatformAuth::getIsDeleted, Boolean.FALSE);
            Long count = iotPlatformAuthMapper.selectCount(wrapper);
            if (count == null || count.longValue() == 0l) {
                existFlag = false;
            }
        }
        return token;
    }
}
