package com.ruoyi.frequency.customer.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.code.DictConstant;
import com.ruoyi.code.PublicCommon;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.core.redis.RedisService;
import com.ruoyi.common.exception.CustomException;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.exception.enums.CoreExceptionEnum;
import com.ruoyi.common.page.PageResult;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.controller.req.CustomerPageReq;
import com.ruoyi.controller.req.RegisterUserReq;
import com.ruoyi.controller.req.UserEditReqVo;
import com.ruoyi.controller.resp.UserResultInfo;
import com.ruoyi.enums.IntegralDetailEnums;
import com.ruoyi.enums.PlatformRecordEnums;
import com.ruoyi.enums.WalletDetailEnums;
import com.ruoyi.enums.user.UserEnums;
import com.ruoyi.frequency.customer.entity.Customer;
import com.ruoyi.frequency.customer.mapper.CustomerMapper;
import com.ruoyi.frequency.customer.model.param.CustomerParam;
import com.ruoyi.frequency.customer.model.result.CustomerCount;
import com.ruoyi.frequency.customer.service.CustomerService;
import com.ruoyi.frequency.customer.service.UserService;
import com.ruoyi.frequency.integralrecord.service.IntegralRecordService;
import com.ruoyi.frequency.level.service.LevelService;
import com.ruoyi.frequency.platformrecord.service.PlatformRecordService;
import com.ruoyi.frequency.store.entity.Store;
import com.ruoyi.frequency.store.mapper.StoreMapper;
import com.ruoyi.frequency.wallerecord.service.WalletRecordService;
import com.ruoyi.response.ResponseData;
import com.ruoyi.utils.BusinessUtil;
import com.ruoyi.utils.SnowIdUtils;
import com.ruoyi.vo.UserInfo;
import com.ruoyi.vo.UserVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 用户Service业务层处理
 *
 * @author liwenlong
 * @date 2023-09-22
 */
@Service
public class CustomerServiceImpl extends ServiceImpl<CustomerMapper, Customer> implements CustomerService {
    @Autowired
    private CustomerMapper customerMapper;

    @Autowired
    private BusinessUtil businessUtil;

    /**
     * 查询用户
     *
     * @param id 用户主键
     * @return 用户
     */
    @Override
    public Customer selectCustomerById(Long id) {
        return customerMapper.selectCustomerById(id);
    }

    @Autowired
    private RedisService redisService;

    /**
     * 查询用户列表
     *
     * @param customer 用户
     * @return 用户
     */
    @Override
    public List<Customer> selectCustomerList(Customer customer) {

        //上次调用此接口的时间
        String last_time_map_key = "last_time_" + 1;

        List<Customer> customers = customerList(customer);
        if (customers.size() > 0) {
            customers.stream().forEach(s -> {

                //在线状态;1:在线,2离线
                Integer onlineStatus = 2;

                if (redisTemplate.opsForHash().hasKey(last_time_map_key, s.getId().toString())) {
                    long lastTimes = Long.valueOf(redisTemplate.opsForHash().get(last_time_map_key, s.getId().toString()).toString());

                    //判断当前时间和上次时间是否超过6分钟(考虑到网络延时和程序卡顿,多1分钟)
                    if (System.currentTimeMillis() - lastTimes < (6 * 60 * 1000)) {
                        onlineStatus = 1;
                    }
                }

                s.setOnlineStatus(onlineStatus);
            });
        }
        return customers;
    }

    private List<Customer> customerList(Customer customer) {

        //上次调用此接口的时间
        String last_time_map_key = "last_time_" + 1;

        //在线状态;1:在线,2离线
        if (ObjectUtil.isNotEmpty(customer.getOnlineStatus())) {

            List<Long> userIds = new ArrayList<>();

            if (redisTemplate.hasKey(last_time_map_key)) {

                Map<String, Object> cacheMap = redisService.getCacheMap(last_time_map_key);

                cacheMap.forEach((key, value) -> {

                    long lastTimes = Long.valueOf(value.toString());

                    if (ObjectUtil.equal(1, customer.getOnlineStatus()) && System.currentTimeMillis() - lastTimes < (6 * 60 * 1000)) {
                        userIds.add(Long.valueOf(key));
                    }
                });
                //userIds为空 直接返回
                if (userIds.size() == 0) {
                    if (ObjectUtil.equal(1, customer.getOnlineStatus())) {
                        return new ArrayList<>();
                    } else {
                        customer.setOnlineStatus(null);
                    }
                } else {
                    customer.setUserIds(userIds);
                }

            } else {
                if (ObjectUtil.equal(1, customer.getOnlineStatus())) {
                    return new ArrayList<>();
                } else {
                    customer.setOnlineStatus(null);
                }
            }


        }

        List<Customer> customers = customerMapper.selectCustomerList(customer);
        return customers;
    }

    @Override
    public CustomerCount statistics(Customer customer) {

        List<Customer> customerList = customerList(customer);
        List<Long> customerIdList = customerList.stream().map(x -> x.getId()).collect(Collectors.toList());
        customerIdList.add(-1L);

        CustomerCount statistics = customerMapper.statistics(customerIdList);

        if (ObjectUtil.isNotEmpty(customer.getOnlineStatus()) && customer.getOnlineStatus() == 2) {
            statistics.setOnlineNumber(0);
            return statistics;
        }

        //在线设计师数
        String last_time_map_key = "last_time_" + 1;

        Map<String, Object> cacheMap = redisService.getCacheMap(last_time_map_key);

        List<Long> userIds = new ArrayList<>();

        cacheMap.forEach((key, value) -> {

            long lastTimes = Long.valueOf(value.toString());

            if (System.currentTimeMillis() - lastTimes < (6 * 60 * 1000)) {
                userIds.add(Long.valueOf(key));
            }
        });

        Integer onlineNumber = 0;
        if (userIds.size() > 0) {
            customer.setOnlineStatus(1);
            customer.setUserIds(userIds);
            onlineNumber = customerMapper.onlineNumber(customer);
        }
        statistics.setOnlineNumber(onlineNumber);


        return statistics;
    }

    /**
     * 新增用户
     *
     * @param customer 用户
     * @return 结果
     */
    @Override
    public int insertCustomer(Customer customer) {
        customer.setCreateTime(DateUtils.getNowDate());
        return customerMapper.insert(customer);
    }

    /**
     * 修改用户
     *
     * @param customer 用户
     * @return 结果
     */
    @Override
    public int updateCustomer(Customer customer) {
        customer.setUpdateTime(DateUtils.getNowDate());
        return customerMapper.updateById(customer);
    }

    /**
     * 批量删除用户
     *
     * @param ids 需要删除的用户主键
     * @return 结果
     */
    @Override
    public int deleteCustomerByIds(Long[] ids, Integer delFlag) {
        this.lambdaUpdate().set(Customer::getDelFlag, delFlag).in(Customer::getId, ids).update();
        return ids.length;
    }

    /**
     * 删除用户信息
     *
     * @param id 用户主键
     * @return 结果
     */
    @Override
    public int deleteCustomerById(Long id) {
        this.lambdaUpdate().set(Customer::getDelFlag, PublicCommon.删除).eq(Customer::getId, id).update();
        return 1;
    }

    @Autowired
    private WalletRecordService walletRecordService;

    @Autowired
    private IntegralRecordService integralRecordService;

    @Autowired
    private PlatformRecordService platformRecordService;

    @Override
    public AjaxResult updateBalance(Customer customer) {

        BigDecimal balanceSub = customer.getBalance();
        if (balanceSub != null) {
            //修改余额
            if (balanceSub.compareTo(BigDecimal.ZERO) > 0) {
                walletRecordService.updateBalance(new UserVo(UserEnums.customer.getCode(), customer.getId()), WalletDetailEnums.PLAT_ADD, customer.getRemark(), customer.getId(), balanceSub, PublicCommon.Wallet.可提现);
                //平台流水
                platformRecordService.addPlatformRecord(new UserVo(UserEnums.customer.getCode(), customer.getId()), customer.getId(), balanceSub.negate(), PlatformRecordEnums.PLAT_ADD);

            }
            if (balanceSub.compareTo(BigDecimal.ZERO) < 0) {
                walletRecordService.updateBalance(new UserVo(UserEnums.customer.getCode(), customer.getId()), WalletDetailEnums.PLAT_SUB, customer.getRemark(), customer.getId(), balanceSub, PublicCommon.Wallet.可提现);
                //平台流水
                platformRecordService.addPlatformRecord(new UserVo(UserEnums.customer.getCode(), customer.getId()), customer.getId(), balanceSub, PlatformRecordEnums.PLAT_ADD);
            }
        }
        return AjaxResult.success();
    }


    @Override
    public AjaxResult updateIntegral(Customer customer) {

        BigDecimal integral = customer.getIntegral();
        if (integral != null) {

            //修改积分
            if (integral.compareTo(BigDecimal.ZERO) > 0) {
                integralRecordService.updateIntegral(new UserVo(UserEnums.customer.getCode(), customer.getId()), customer.getId(), integral, IntegralDetailEnums.PLAT_ADD,customer.getRemark());

            } else if (integral.compareTo(BigDecimal.ZERO) < 0) {
                integralRecordService.updateIntegral(new UserVo(UserEnums.customer.getCode(), customer.getId()), customer.getId(), integral, IntegralDetailEnums.PLAT_SUB,customer.getRemark());
            }
        }

        return AjaxResult.success();
    }


    /**
     * 组装用户
     *
     * @param req    账号
     * @param md5Pwd 登录密码
     * @return
     */
    @Override
    public Customer assembleCustomer(RegisterUserReq req, String md5Pwd) {

        Customer customer = new Customer();
        customer.setId(SnowIdUtils.uniqueLong());

        //账号
        customer.setAccount(ObjectUtil.isNotEmpty(req.getAccount()) ? req.getAccount() : req.getMobile());

        //手机号
        customer.setMobile(ObjectUtil.isNotEmpty(req.getMobile()) ? req.getMobile() : req.getAccount());


        //默认头像
        SysDictData dict = businessUtil.getDict(DictConstant.默认头像);
        customer.setAvatar(dict.getImages());

        Customer maxCustomer = this.getOne(new QueryWrapper<Customer>().lambda().orderByDesc(Customer::getNickname).last("limit 1"));

        Integer num = maxCustomer == null ? 0 : Integer.valueOf(maxCustomer.getNickname().replace("SJS", ""));

        //默认昵称
        SysDictData sjs_dict = businessUtil.getDict(DictConstant.SJS_name_pre);
        String name = sjs_dict.getDictValue();
        if (ObjectUtil.isNotEmpty(name)) {

            String str = customer.getMobile();
            String lastFour = "";
            if (ObjectUtil.isNotEmpty(str)) {
                int length = str.length();
                lastFour = (length > 4) ? str.substring(length - 4) : str;
            }
            name = name.concat(lastFour);
        }
        customer.setName(name);

        customer.setNickname(getNickname(num));
        customer.setLoginPwd(md5Pwd);
        customer.setClientId(req.getClientId());
        customer.setCreateTime(new Date());
        customer.setUpdateTime(new Date());
        customer.setAreaCode(req.getAreaCode());

        return customer;
    }

    @Autowired
    private LevelService levelService;

    private String getNickname(Integer num) {
        String template = "SJS%06d";
        num++;
        String id = String.format(template, num);
        return id;
    }

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public ResponseData info(UserVo userVo) {

        UserResultInfo info = baseMapper.info(userVo.getUserId());

        //上次调用此接口的时间
        String last_time_map_key = "last_time_" + userVo.getUserType();

        //在线状态;1:在线,2离线
        Integer onlineStatus = 2;

        if (redisTemplate.opsForHash().hasKey(last_time_map_key, info.getUserId().toString())) {
            long lastTimes = Long.valueOf(redisTemplate.opsForHash().get(last_time_map_key, info.getUserId().toString()).toString());

            //判断当前时间和上次时间是否超过6分钟(考虑到网络延时和程序卡顿,多1分钟)
            if (System.currentTimeMillis() - lastTimes < (6 * 60 * 1000)) {
                onlineStatus = 1;
            }
        }

        info.setOnlineStatus(onlineStatus);

        return ResponseData.success(info);
    }

    @Autowired
    private UserService userService;

    @Override
    public ResponseData<PageResult<Page<Customer>>> customerPage(CustomerPageReq req, UserVo userVo) {

        //筛去拉黑与被拉黑用户
//        if (req.getType() != null && req.getType() == 1) {
//            List<UserVo> blockUserList = userService.blockUserList(userVo);
//            req.setBlockUserList(blockUserList);
//
//            //筛去屏蔽用户
//            List<UserVo> shieldUserList = userService.shieldUserList(userVo);
//            req.setShieldUserList(shieldUserList);
//        }

        Page<Customer> page = customerMapper.customerPage(new Page<>(req.getPageNo(), req.getPageSize()), req, userVo);

        if (page.getRecords().size() > 0) {
            Set<UserVo> userVoSet = page.getRecords().stream().map(resp -> new UserVo(UserEnums.customer.getCode(), resp.getId())).collect(Collectors.toSet());
            //查询用户信息
            Map<UserVo, UserInfo> userMap = userService.selectUserInfoMap(userVoSet, userVo);

            page.getRecords().stream().forEach(resp -> {
                resp.setUserInfo(userMap.get(new UserVo(UserEnums.customer.getCode(), resp.getId())));
            });
        }

        return ResponseData.success(new PageResult<>(page));
    }

    @Override
    public void canCancellation(Long userId) {
        Integer orderCount = baseMapper.canCancellation(userId);
        if (orderCount > 0) {
            throw new ServiceException("您有未完成的订单，不可注销");
        }
    }

    @Override
    public ResponseData editInfo(UserEditReqVo vo, UserVo userVo) {


        LambdaUpdateChainWrapper<Customer> lambdaUpdate = this.lambdaUpdate();
        lambdaUpdate.set(Customer::getId,userVo.getUserId());
        //头像
        if (ObjectUtil.isNotEmpty(vo.getAvatar())) {
            lambdaUpdate.set(Customer::getAvatar, vo.getAvatar());
        }
        //所属区域
        if (ObjectUtil.isNotEmpty(vo.getArea())) {
            lambdaUpdate.set(Customer::getArea, vo.getArea());
        }

        //性别
        if (ObjectUtil.isNotEmpty(vo.getSex())) {
            lambdaUpdate.set(Customer::getSex, vo.getSex());
        }

        //入行时间
        if (ObjectUtil.isNotEmpty(vo.getEnterDate())) {
            lambdaUpdate.set(Customer::getEnterDate, DateUtil.parse(vo.getEnterDate(), "yyyy"));
        }
        //背景图
        if (ObjectUtil.isNotEmpty(vo.getBackgroundImage())) {
            lambdaUpdate.set(Customer::getBackgroundImage, vo.getBackgroundImage());
        }

        //推送是否关闭;1不关闭2  关闭
        if (ObjectUtil.isNotEmpty(vo.getCloseMessage())) {
            lambdaUpdate.set(Customer::getCloseMessage, vo.getCloseMessage());
        }

        //昵称
        if (ObjectUtil.isNotEmpty(vo.getName())) {
            lambdaUpdate.set(Customer::getName, vo.getName());
        }

        //条件
        lambdaUpdate.eq(Customer::getId, userVo.getUserId()).update();

        if (ObjectUtil.isNotEmpty(vo.getName())) {
            Integer count = baseMapper.selectCount(new QueryWrapper<Customer>().lambda().eq(Customer::getDelFlag, PublicCommon.启用)
                    .eq(Customer::getName, vo.getName()));
            Integer count1 = storeMapper.selectCount(new QueryWrapper<Store>().lambda().eq(Store::getDelFlag, PublicCommon.启用)
                    .eq(Store::getName, vo.getName()));
            if (count + count1 > 1) {
                return ResponseData.error("昵称重复");
            }

            //判断敏感词
            businessUtil.checkSensitiveWord(vo.getName());
        }


        return ResponseData.success();
    }

    @Autowired
    private StoreMapper storeMapper;


    @Override
    public void switchEnable(CustomerParam customerParam) {
        if (ObjectUtil.equal(customerParam.getDelFlag(), PublicCommon.删除)) {
            throw new CustomException(CoreExceptionEnum.ERROR_PARAM);
        }
        LambdaUpdateWrapper<Customer> queryWrapper = new LambdaUpdateWrapper<>();
        queryWrapper.eq(Customer::getId, customerParam.getId());
        queryWrapper.set(Customer::getDelFlag, customerParam.getDelFlag());
        update(queryWrapper);
    }

    @Override
    public Customer getCustomerByAccount(String account) {
        return this.getOne(new QueryWrapper<Customer>().lambda()
                .ne(Customer::getDelFlag, PublicCommon.删除)
                .eq(Customer::getAccount, account));
    }


    /**
     * 根据手机号查询用户
     *
     * @param areaCode 区号
     * @param mobile   手机号
     * @return 用户
     */
    @Override
    public Customer getCustomerByMobile(String areaCode, String mobile) {
        return this.getOne(new QueryWrapper<Customer>().lambda()
                .ne(Customer::getDelFlag, PublicCommon.删除)
                .eq(StrUtil.isNotEmpty(areaCode), Customer::getAreaCode, areaCode)
                .eq(Customer::getMobile, mobile));
    }


    @Override
    public void saveIdNo(Long id) {
        baseMapper.saveIdNo(id);
    }
}
