package com.m2pool.pool.service.impl;

import com.alibaba.fastjson.JSON;
import com.m2pool.common.core.Result.R;
import com.m2pool.common.core.utils.CodeUtils;
import com.m2pool.common.core.utils.StringUtils;
import com.m2pool.common.core.web.Result.AjaxResult;
import com.m2pool.common.redis.service.RedisService;
import com.m2pool.common.security.utils.SecurityUtils;
import com.m2pool.pool.dto.NoticeListDto;
import com.m2pool.pool.dto.UserAccountDto;
import com.m2pool.pool.mapper.NoticeMapper;
import com.m2pool.pool.mapper.UserAccountMapper;
import com.m2pool.pool.service.NoticeService;
import com.m2pool.pool.vo.*;
import com.m2pool.system.api.RemoteMailService;
import com.m2pool.system.api.entity.EmailCodeEntity;
import com.m2pool.system.api.entity.EmailEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @Description TODO
 * @Date 2024/8/22 14:50
 * @Author 杜懿
 */
@Service
public class NoticeServiceImpl implements NoticeService {

    @Autowired
    private NoticeMapper noticeMapper;

    @Autowired
    private UserAccountMapper uaMapper;

    @Autowired
    private RemoteMailService mailService;

    @Autowired
    private RedisService redisService;

    @Override
    public List<NoticeListDto> getNoticeEmailList(NoticePageVo vo) {
        String user = SecurityUtils.getUsername();
        if(StringUtils.isBlank(user)){
            return new ArrayList<>();
        }
        List<NoticeListDto> list = noticeMapper.getNoticeEmailListByMaId(vo,user);
        return list;
    }

    @Override
    public AjaxResult addNoticeEmail(NoticeAddVo vo) {
        String user = SecurityUtils.getUsername();
        if(StringUtils.isBlank(user)){
            return AjaxResult.error("token身份解析异常");
        }
        if(vo.getMaId() <= 0){
            return AjaxResult.error("挖矿账户id传参错误");
        }
        UserAccountDto userAccount = uaMapper.getAccountByUserAccountId(user, vo.getMaId());

        if(StringUtils.isNull(userAccount)){
            //未查询到对应ma_id;
            System.out.println("当前挖矿账号id和当前登录账号无关");
            return AjaxResult.error("挖矿账号id错误");
        }

        boolean exist = noticeMapper.checkEmailIfExist(vo.getMaId(), vo.getEmail());
        if(exist){
            return AjaxResult.error("不能添加相同邮箱!");
        }

        //校验邮箱验证码
        String redisKey = "notice:"+vo.getEmail()+":code";
        if(redisService.hasKey(redisKey)){

            Object o = redisService.getCacheObject(redisKey);//notice:email:code

            EmailCodeEntity emailCodeEntity = JSON.parseObject(JSON.toJSONString(o), EmailCodeEntity.class);

            //验证验证码
            if(!vo.getCode().equals(emailCodeEntity.getEmailCode())){
                return AjaxResult.error("邮箱验证码错误");
            }
        }else {
            return AjaxResult.error("邮箱验证码 未获取或已过期(有效期10分钟)，请重新获取验证码");
        }


        int count = noticeMapper.getNoticeEmailCountByMaId(userAccount.getId());

        if(count >= 3){
            return AjaxResult.error("当前挖矿账号下通知邮箱数已达上限：3");
        }

        boolean result = noticeMapper.addNoticeEmail(vo);
        if(result){
            redisService.deleteObject(redisKey);
            return AjaxResult.success("通知邮箱添加成功");
        }else {
            return AjaxResult.error("通知邮箱添加失败，请稍后再试");
        }
    }

    @Override
    public AjaxResult getCode(NoticeAddVo vo) {

        String user = SecurityUtils.getUsername();
        if(StringUtils.isBlank(user)){
            return AjaxResult.error("token身份解析异常");
        }
        UserAccountDto userAccount = uaMapper.getAccountByUserAccountId(user, vo.getMaId());

        if(StringUtils.isNull(userAccount)){
            //未查询到对应ma_id;
            System.out.println("当前挖矿账号id和当前登录账号无关");
            return AjaxResult.error("挖矿账号id错误");
        }

        //判断用户是不是恶意刷邮箱，在规定时间内进行的
        String redisKey = "notice:"+vo.email+":code";
        if (redisService.hasKey(redisKey)) {
            Object o = redisService.getCacheObject(redisKey);//notice:email:code

            EmailCodeEntity emailCodeEntity = JSON.parseObject(JSON.toJSONString(o), EmailCodeEntity.class);
            if (emailCodeEntity.getTimes() > 4) {
                return AjaxResult.error("请求次数过多，请10分钟后再试,(同一用户10分钟内只能请求4次)");
            } else {

                String emailCode = CodeUtils.creatCode(6);
                emailCodeEntity.setEmailCode(emailCode);


                emailCodeEntity.setTimes(emailCodeEntity.getTimes() + 1);
                long overTime = redisService.getExpire(redisKey);
                redisService.setCacheObject(redisKey, emailCodeEntity, overTime, TimeUnit.SECONDS
                );
                return sendEmail(vo.getEmail(), emailCode,userAccount.getAccount());
            }
        } else {
            String emailCode = CodeUtils.creatCode(6);
            // 最多允许用户在10分钟内发送2次的邮箱验证
            // 0s倒计时后用户可以再发送验证码，但是间隔在10分钟内只能再发送1次
            EmailCodeEntity emailCodeEntity = new EmailCodeEntity();
            emailCodeEntity.setEmail(vo.getEmail());
            emailCodeEntity.setEmailCode(emailCode);
            emailCodeEntity.setTimes(1);
            //设置失效时间10分钟
            redisService.setCacheObject(redisKey, emailCodeEntity,
                    10L, TimeUnit.MINUTES
            );
            return sendEmail(vo.getEmail(),emailCode,userAccount.getAccount());
        }


    }

    @Override
    public AjaxResult updateInfo(NoticeUpdateVo vo) {

        String user = SecurityUtils.getUsername();
        if(StringUtils.isBlank(user)){
            return AjaxResult.error("token身份解析异常");
        }

        boolean ifExist = noticeMapper.checkIdAndMa(vo.getId(), user);
        if(ifExist){
            //存在 执行修改
            if(vo.getRemark().length() >=299){
                return AjaxResult.error("备注过长,请控制在300字符以内！");
            }
            boolean result = noticeMapper.updateInfo(vo);
            if(result){
                return AjaxResult.success("修改成功");
            }else {
                return AjaxResult.error("修改失败，请稍后再试");
            }
        }else {
            return AjaxResult.error("当前账号与对应通知id无关联,请勿擅自修改参数");
        }
    }

    @Override
    public AjaxResult deleteEmail(NoticeDelVo vo) {
        String user = SecurityUtils.getUsername();
        if(StringUtils.isBlank(user)){
            return AjaxResult.error("token身份解析异常");
        }
        long maId = noticeMapper.getMaIdByIdAndUser(vo.getId(), user);
        if(StringUtils.isNull(maId)){
            //maId为null
            return AjaxResult.error("当前账号与对应通知id无关联,请勿擅自修改参数");
        }else if(maId < 1){
            return AjaxResult.error("当前账号与对应通知id无关联,请勿擅自修改参数");
        }else {
            boolean result = noticeMapper.deleteNoticeInfoById(vo,maId);
            if(result){
                return AjaxResult.success("删除成功");
            }else {
                return AjaxResult.error("删除成功，请稍后再试");
            }
        }
    }

    public AjaxResult sendEmail(String email,String code,String ma){
        String text = "您正在为您的挖矿账户: "+ma+" 添加离线通知邮箱！\n" +
                "当前账户将会做为接收邮箱接收您挖矿账户下的矿机离线通知！\n" +
                "您的邮箱验证验证码是:\n\t"+code +
                "\n此验证码10分钟有效。";
        EmailEntity emailEntity = new EmailEntity();
        emailEntity.setEmail(email);
        emailEntity.setSubject("[M2Pool] 接收离线通知邮箱 邮箱验证码");
        emailEntity.setText(text);
        R<?> r = mailService.sendTextMail(emailEntity);
        if(r.getCode() == 200){
            return AjaxResult.success();
        }else {
            return AjaxResult.error(r.getCode(),r.getMsg());
        }
    }



}
