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

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.code.DictConstant;
import com.ruoyi.code.PublicCommon;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.redis.RedisService;
import com.ruoyi.common.exception.CustomException;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.controller.req.RegisterUserReq;
import com.ruoyi.controller.req.UserEditReqVo;
import com.ruoyi.enums.PlatformRecordEnums;
import com.ruoyi.enums.WalletDetailEnums;
import com.ruoyi.enums.message.OrderMessageEnums;
import com.ruoyi.enums.user.UserEnums;
import com.ruoyi.frequency.customer.entity.Customer;
import com.ruoyi.frequency.customer.mapper.CustomerMapper;
import com.ruoyi.frequency.enterprise.entity.Enterprise;
import com.ruoyi.frequency.enterprise.service.EnterpriseService;
import com.ruoyi.frequency.illegaldeductionrecord.service.IllegalDeductionRecordService;
import com.ruoyi.frequency.level.service.LevelService;
import com.ruoyi.frequency.ordermessage.service.OrderMessageUtilService;
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.store.model.result.OrderResult;
import com.ruoyi.frequency.store.model.result.StoreCount;
import com.ruoyi.frequency.store.service.StoreService;
import com.ruoyi.frequency.wallerecord.service.WalletRecordService;
import com.ruoyi.response.ResponseData;
import com.ruoyi.system.service.ISysConfigService;
import com.ruoyi.system.service.ISysRoleService;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.utils.BusinessUtil;
import com.ruoyi.utils.SnowIdUtils;
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.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 商户Service业务层处理
 *
 * @author liwenlong
 * @date 2023-09-22
 */
@Service
public class StoreServiceImpl extends ServiceImpl<StoreMapper, Store> implements StoreService {
    @Autowired
    private StoreMapper storeMapper;

    @Autowired
    private BusinessUtil businessUtil;

    /**
     * 查询商户
     *
     * @param id 商户主键
     * @return 商户
     */
    @Override
    public Store selectStoreById(Long id) {

        Store store = storeMapper.selectStoreById(id);

        if (store != null) {
            //是企业查询企业信息
            if (ObjectUtil.isNotEmpty(store.getBindEnterpriseId())) {
                Enterprise enterprise = enterpriseService.getById(store.getBindEnterpriseId());
                store.setEnterprise(enterprise);
            }

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

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

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

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

            store.setOnlineStatus(onlineStatus);
        }

        return store;
    }

    @Autowired
    private RedisService redisService;

    /**
     * 查询商户列表
     *
     * @param store 商户
     * @return 商户
     */
    @Override
    public List<Store> selectStoreList(Store store) {

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

        List<Store> stores = storeList(store);

        if (stores.size() > 0) {

            stores.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);

                //可提现金额
                if (s.getWithdrawableAmount() == null) {
                    s.setWithdrawableAmount(BigDecimal.ZERO);
                }
                s.setWithdrawableAmount(s.getWithdrawableAmount().compareTo(BigDecimal.ZERO) == 1 ? s.getWithdrawableAmount() : BigDecimal.ZERO);

                //待提现金额
                s.setToBeWithdrawnAmount(s.getBalance().subtract(s.getWithdrawableAmount()));
            });
        }
        return stores;
    }

    private List<Store> storeList(Store store) {
        //从业年限筛选
        if (ObjectUtil.isNotEmpty(store.getYearRange())) {
            String[] split = store.getYearRange().split("-");
            if (split.length == 1) {
                store.setMaxYear(Integer.valueOf(split[0]));
            }
            if (split.length == 2) {
                store.setMinYear(Integer.valueOf(split[0]));
                store.setMaxYear(Integer.valueOf(split[1]));
            }
        }


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

        //在线状态;1:在线,2离线
        if (ObjectUtil.isNotEmpty(store.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 (System.currentTimeMillis() - lastTimes < (6 * 60 * 1000)) {
                        userIds.add(Long.valueOf(key));
                    }
                });

                //userIds为空 直接返回
                if (userIds.size() == 0) {
                    if (ObjectUtil.equal(1, store.getOnlineStatus())) {
                        return new ArrayList<>();
                    } else {
                        store.setOnlineStatus(null);
                    }
                } else {
                    store.setUserIds(userIds);
                }

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


        }


        List<Store> stores = storeMapper.selectStoreList(store);
        return stores;
    }

    @Override
    public StoreCount statistics(Store store) {

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

        List<Store> stores = storeList(store);
        List<Long> storeIdList = stores.stream().map(x -> x.getId()).collect(Collectors.toList());
        storeIdList.add(-1L);

        Date beginOfMonth = DateUtil.beginOfMonth(new Date());

        StoreCount storeCount = baseMapper.statistics(storeIdList, beginOfMonth);

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

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

        if (ObjectUtil.isEmpty(cacheMap)) {
            storeCount.setOnlineNumber(0);
            return storeCount;
        }

        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) {
            store.setOnlineStatus(1);
            store.setUserIds(userIds);
            onlineNumber = storeMapper.onlineNumber(store);
        }
        storeCount.setOnlineNumber(onlineNumber);

        return storeCount;
    }

    /**
     * 新增商户
     *
     * @param store 商户
     * @return 结果
     */
    @Override
    public int insertStore(Store store) {
        store.setCreateTime(DateUtils.getNowDate());
        return storeMapper.insertStore(store);
    }

    /**
     * 修改商户
     *
     * @param store 商户
     * @return 结果
     */
    @Override
    public int updateStore(Store store) {
        store.setUpdateTime(DateUtils.getNowDate());
        return storeMapper.updateStore(store);
    }

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

    /**
     * 删除商户信息
     *
     * @param id 商户主键
     * @return 结果
     */
    @Override
    public int deleteStoreById(Long id) {
        return storeMapper.deleteStoreById(id);
    }

    @Autowired
    private IllegalDeductionRecordService illegalDeductionRecordService;

    @Override
    public int updateViolationDeduction(Store store) {

        if (store.getViolationDeduction() == null) {
            throw new CustomException("金额不能为空");
        }

        if (store.getViolationDeduction().compareTo(BigDecimal.ZERO) == -1) {
            throw new CustomException("扣款金额不能小于0");
        }
        if (store.getOrderId() == null) {
            throw new CustomException("请关联订单");
        }
        //差值
        BigDecimal price = store.getViolationDeduction();

        illegalDeductionRecordService.updateViolationDeduction(store.getId(), null, price, price.compareTo(BigDecimal.ZERO) == 1 ? 1 : 2, store.getOrderId(), store.getDeductionType(), store.getRemark());

        OrderResult orderResult = baseMapper.getOrderInfo(store.getOrderId());

        //添加订单消息
        orderMessageService.addOrderMessage(new UserVo(UserEnums.customer.getCode(), store.getId()), store.getOrderId(),
                "", PublicCommon.Order.订单, OrderMessageEnums.ORDER_ILLEGAL_DEDUCTION, orderResult.getOrderNo(), store.getViolationDeduction() + "", store.getRemark());

        return 1;
    }

    @Autowired
    private OrderMessageUtilService orderMessageService;


    @Autowired
    private EnterpriseService enterpriseService;

    @Autowired
    private ISysUserService userService;

    @Autowired
    private ISysRoleService sysRoleService;

    @Autowired
    private ISysConfigService configService;

    @Override
    public AjaxResult setUpEnterprise(Store store) {

        Enterprise enterprise = store.getEnterprise();

        Store s = this.getById(store.getId());

        if (ObjectUtil.isNotEmpty(s.getBindEnterpriseId())) {
            return AjaxResult.error("该表现师已绑定企业");
        }

        //生成企业后台账号
        SysUser user = new SysUser();
        user.setUserName(ObjectUtil.isEmpty(store.getAccount()) ? s.getAccount() : store.getAccount());
        user.setPhonenumber(s.getAccount());
        String password = configService.selectConfigByKey("sys.user.initPassword");
        user.setPassword(SecurityUtils.encryptPassword(ObjectUtil.isNotEmpty(store.getLoginPwd()) ? store.getLoginPwd() : password));
        user.setNickName(enterprise.getName());
        user.setUserType("01");
        if (UserConstants.NOT_UNIQUE.equals(userService.checkUserNameUnique(user.getUserName()))) {
            return AjaxResult.error("新增用户'" + user.getUserName() + "'失败，登录账号已存在");
        } else if (StringUtils.isNotEmpty(user.getPhonenumber())
                && UserConstants.NOT_UNIQUE.equals(userService.checkPhoneUnique(user))) {
            return AjaxResult.error("新增用户'" + user.getUserName() + "'失败，手机号码已存在");
        }
        SysRole sysRole = new SysRole();
        sysRole.setRoleKey("enterprise");
        List<SysRole> sysRoles = sysRoleService.selectRoleList(sysRole);

        //角色
        user.setRoleIds(new Long[]{sysRoles.get(0).getRoleId()});

        userService.insertUser(user);

        //表现师关联企业
        enterprise.setSysUserId(user.getUserId());
        enterpriseService.save(enterprise);

        this.update().set("bind_enterprise_id", enterprise.getId()).eq("id", store.getId()).update();

        return AjaxResult.success();
    }

    @Autowired
    private WalletRecordService walletRecordService;

    @Autowired
    private PlatformRecordService platformRecordService;

    @Override
    public AjaxResult updateBalance(Store store) {

        BigDecimal price = store.getBalance();

        //修改余额
        if (price.compareTo(BigDecimal.ZERO) > 0) {
            walletRecordService.updateBalance(new UserVo(UserEnums.store.getCode(), store.getId()), WalletDetailEnums.PLAT_ADD, store.getRemark(), store.getId(), price, PublicCommon.Wallet.可提现);

            //平台流水
            platformRecordService.addPlatformRecord(new UserVo(UserEnums.store.getCode(), store.getId()), store.getId(), price.negate(), PlatformRecordEnums.PLAT_ADD);

        } else if (price.compareTo(BigDecimal.ZERO) < 0) {
            walletRecordService.updateBalance(new UserVo(UserEnums.store.getCode(), store.getId()), WalletDetailEnums.PLAT_SUB, store.getRemark(), store.getId(), price, PublicCommon.Wallet.可提现);

            //平台流水
            platformRecordService.addPlatformRecord(new UserVo(UserEnums.store.getCode(), store.getId()), store.getId(), price, PlatformRecordEnums.PLAT_ADD);

        }
        return AjaxResult.success();
    }

    @Autowired
    private LevelService levelService;

    @Override
    public Store assembleStore(RegisterUserReq req, String md5Pwd) {
        Store store = new Store();
        store.setId(SnowIdUtils.uniqueLong());

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

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

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

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

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

        store.setNickname(getNickname(num));

        //默认昵称
        SysDictData bxs_dict = businessUtil.getDict(DictConstant.BXS_name_pre);
        String name = bxs_dict.getDictValue();
        if (ObjectUtil.isNotEmpty(name)) {
            String str = store.getMobile();
            int length = str.length();
            String lastFour = (length > 4) ? str.substring(length - 4) : str;
            name = name.concat(lastFour);
        }
        store.setName(name);

        store.setLoginPwd(md5Pwd);
        store.setCreateTime(new Date());
        store.setUpdateTime(new Date());

        return store;
    }

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

    public static void main(String[] args) {
        String template = "BXS%06d";

        String id = String.format(template, 2);
        System.out.println(id);
    }

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


    @Override
    public ResponseData editInfo(UserEditReqVo vo, UserVo userVo) {
        LambdaUpdateChainWrapper<Store> lambdaUpdate = this.lambdaUpdate();
        lambdaUpdate.set(Store::getId, userVo.getUserId());
        //头像
        if (ObjectUtil.isNotEmpty(vo.getAvatar())) {
            lambdaUpdate.set(Store::getAvatar, vo.getAvatar());
        }
        //所属区域
        if (ObjectUtil.isNotEmpty(vo.getArea())) {
            lambdaUpdate.set(Store::getArea, vo.getArea());
        }
        //性别
        if (ObjectUtil.isNotEmpty(vo.getSex())) {

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

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

        //曾经任职公司
        if (ObjectUtil.isNotEmpty(vo.getOnceWorkCompanys())) {
            lambdaUpdate.set(Store::getOnceWorkCompanys, vo.getOnceWorkCompanys());
        }

        //昵称
        if (ObjectUtil.isNotEmpty(vo.getName())) {

            String key = "store_name_" + DateUtil.format(new Date(), "yyyy-MM_") + userVo.getUserId();

            //获取数据库中名称
            Store store = this.getById(userVo.getUserId());
            //名称每个月只能修改一次
            if (redisTemplate.hasKey(key) && ObjectUtil.notEqual(store.getName(), vo.getName())) {
                return ResponseData.error("昵称每个月只能修改一次");
            }

            if (StringUtils.isNotBlank(vo.getName()) && vo.getName().length() != vo.getName().replace(" ", "").length()) {
                return ResponseData.error("昵称不允许包含空格");
            }

            //不同才修改
            if (ObjectUtil.notEqual(store.getName(), vo.getName())) {
                lambdaUpdate.set(Store::getName, vo.getName());

                redisTemplate.opsForValue().set(key, userVo.getUserId(), 35, TimeUnit.DAYS);
            }
        }

        //擅长领域
        if (ObjectUtil.isNotEmpty(vo.getSpecialityArea())) {
            lambdaUpdate.set(Store::getSpecialityArea, vo.getSpecialityArea());
        }

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

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

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

    @Autowired
    private CustomerMapper customerMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public ResponseData info(UserVo userVo) {

        final Store store = this.selectStoreById(userVo.getUserId());

//        //上次调用此接口的时间
//        String last_time_map_key = "last_time_" + userVo.getUserType();
//
//        //在线状态;1:在线,2离线
//        Integer onlineStatus = 2;
//
//        if (redisTemplate.opsForHash().hasKey(last_time_map_key,store.getId().toString())) {
//            long lastTimes = Long.valueOf(redisTemplate.opsForHash().get(last_time_map_key, store.getId().toString()).toString());
//
//            //判断当前时间和上次时间是否超过6分钟(考虑到网络延时和程序卡顿,多1分钟)
//            if (System.currentTimeMillis() - lastTimes < (6 * 60 * 1000)) {
//                onlineStatus = 1;
//            }
//        }
//
//        store.setOnlineStatus(onlineStatus);

        return ResponseData.success(store);
    }

    @Override
    public int getAuthStore(List<Long> userIds, Integer ifHighend) {
        if (ifHighend == null) {
            return storeMapper.getAuthStore(userIds);
        }
        if (ifHighend == 1) {
            return storeMapper.getCommonAuthStore(userIds);
        }
        if (ifHighend == 2) {
            return storeMapper.getHighAuthStore(userIds);
        }
        if (ifHighend == 3) {
            return storeMapper.getKujialeAuthStore(userIds);
        }
        return 0;
    }

    @Override
    public AjaxResult setUpPlatform(Store store) {
        this.lambdaUpdate().set(Store::getIsPlatform, store.getIsPlatform())
                .eq(Store::getId, store.getId()).update();
        return AjaxResult.success();
    }

    @Override
    public AjaxResult setDDAuth(Store store) {
        this.lambdaUpdate().set(Store::getIsDdAuth, store.getIsDdAuth())
                .eq(Store::getId, store.getId()).update();
        return AjaxResult.success();
    }

    @Override
    public AjaxResult setCommissionRatio(Store store) {

        if (store.getCommissionRatio() != null) {
            if (store.getCommissionRatio().compareTo(BigDecimal.ZERO) == -1) {
                throw new ServiceException("提成比例不可小于0");
            }
            if (store.getCommissionRatio().compareTo(BigDecimal.ONE) == 1) {
                throw new ServiceException("提成比例不可大于1");
            }
        }

        this.lambdaUpdate().set(Store::getCommissionRatio, store.getCommissionRatio())
                .eq(Store::getId, store.getId()).update();
        return AjaxResult.success();
    }

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