package shop.alien.store.service.impl;

import cn.hutool.core.date.DateTime;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.tuple.Triple;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import shop.alien.entity.result.R;
import shop.alien.entity.store.*;
import shop.alien.entity.store.excelVo.StoreUserExcelVo;
import shop.alien.entity.store.excelVo.util.ExcelGenerator;
import shop.alien.entity.store.vo.StoreUserVo;
import shop.alien.mapper.*;
import shop.alien.store.config.BaseRedisService;
import shop.alien.store.service.NearMeService;
import shop.alien.store.service.StoreUserService;
import shop.alien.store.util.FunctionMagic;
import shop.alien.util.ali.AliOSSUtil;
import shop.alien.util.common.DateUtils;
import shop.alien.util.common.JwtUtil;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * 二期-门店用户 服务实现类
 *
 * @author ssk
 * @since 2024-12-11
 */
@Slf4j
@Transactional
@Service
@RequiredArgsConstructor
public class StoreUserServiceImpl extends ServiceImpl<StoreUserMapper, StoreUser> implements StoreUserService {

    private final StoreUserMapper storeUserMapper;

    private final StoreInfoMapper storeInfoMapper;

    private final BaseRedisService baseRedisService;

    private final LifeUserDynamicsMapper lifeUserDynamicsMapper;

    private final LifeFansMapper lifeFansMapper;

    private final LifeNoticeMapper lifeNoticeMapper;

    private final LifeMessageMapper lifeMessageMapper;

    private final NearMeService nearMeService;

    private final AliOSSUtil aliOSSUtil;

    @Value("${spring.web.resources.excel-path}")
    private String excelPath;

    @Value("${spring.web.resources.excel-generate-path}")
    private String excelGeneratePath;

    @Value("${jwt.expiration-time}")
    private String effectiveTime;

    /**
     * 设定初始化默认密码
     */
    private static final String DEFAULT_PASSWORD = "123456";

    /**
     * 手机号获取
     *
     * @param phone 手机号
     * @return StoreUser
     */
    @Override
    public StoreUserVo getUserByPhone(String phone) {
        LambdaQueryWrapper<StoreUser> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(StoreUser::getPhone, phone);
        StoreUser user = this.getOne(lambdaQueryWrapper);
        StoreUserVo storeUserVo = new StoreUserVo();
        if (user.getStatus() == -1) {
            LocalDateTime localDateTime = user.getLogoutTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
            LocalDateTime future = localDateTime.plusDays(7);
            LocalDateTime now = LocalDateTime.now();
            Duration duration = Duration.between(now, future);
            long correct = duration.toMillis();
            storeUserVo.setCountdown(correct);
        }

        if (null == user) return new StoreUserVo();
        BeanUtils.copyProperties(user, storeUserVo);
        return storeUserVo;
    }


    /**
     * token
     *
     * @param storeUser
     * @return
     */
    @Override
    public R<StoreUserVo> createToKen(StoreUser storeUser) {
        int effectiveTimeInt = Integer.parseInt(effectiveTime.substring(0, effectiveTime.length() - 1));
        String effectiveTimeUnit = effectiveTime.substring(effectiveTime.length() - 1);
        long effectiveTimeIntLong = 0L;
        switch (effectiveTimeUnit) {
            case "s": {
                effectiveTimeIntLong = effectiveTimeInt * 1000L;
                break;
            }
            case "m": {
                effectiveTimeIntLong = effectiveTimeInt * 60L * 1000L;
                break;
            }
            case "h": {
                effectiveTimeIntLong = effectiveTimeInt * 60L * 60L * 1000L;
                break;
            }
            case "d": {
                effectiveTimeIntLong = effectiveTimeInt * 24L * 60L * 60L * 1000L;
                break;
            }
        }

        StoreUserVo storeUserVo = new StoreUserVo();
        BeanUtils.copyProperties(storeUser, storeUserVo);
        Map<String, String> tokenMap = new HashMap<>();
        tokenMap.put("phone", storeUser.getPhone());
        tokenMap.put("userName", storeUser.getName());
        tokenMap.put("userId", storeUser.getId().toString());
        tokenMap.put("userType", "store");
        storeUserVo.setToken(JwtUtil.createJWT("store_" + storeUser.getPhone(), storeUser.getName(), JSONObject.toJSONString(tokenMap), effectiveTimeIntLong));
        baseRedisService.setString("store_" + storeUser.getPhone(), storeUserVo.getToken());
        StoreInfo storeInfo = storeInfoMapper.selectById(storeUser.getStoreId());
        if (storeInfo != null) {
            storeUserVo.setBusinessSection(storeInfo.getBusinessSection());
            storeUserVo.setBusinessTypesName(storeInfo.getBusinessTypesName());
        }
        return R.data(storeUserVo);
    }

    /**
     * 修改用户状态
     *
     * @param phone 手机号
     * @param type  修改类型 (pass:密码状态改为1, face:人脸状态改为2)
     * @return StoreUser
     */
    @Override
    public boolean updateUserStatus(String phone, String type) {
        LambdaQueryWrapper<StoreUser> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(StoreUser::getPhone, phone);
        StoreUser one = this.getOne(lambdaQueryWrapper);
        if ("face".equals(type)) {
            one.setPassType(2);
        }
        if ("pass".equals(type)) {
            one.setPassType(2);
        }
        return this.updateById(one);
    }

    /**
     * 修改密码
     *
     * @param id       主键
     * @param password 密码
     * @return boolean
     */
    @Override
    public boolean updatePassword(Integer id, String password) {
        StoreUser storeUser = new StoreUser();
        storeUser.setId(id);
        storeUser.setPassword(password);
        return this.updateById(storeUser);
    }

    @Override
    public R<String> forgetOrModifyPassword(String phone, String newPhone, String oldPassword, String newPassword, String confirmNewPassword, String verificationCode, Integer type) {
        boolean flag = false;
        try {
            //类型为0 忘记密码
            if (type == 0) {
                return forgetPassword(phone, newPassword, verificationCode);
            }
            //修改密码
            else if (type == 1) {
                //效验新密码规则
                passwordVerification(phone, oldPassword, newPassword, confirmNewPassword);
                LambdaUpdateWrapper<StoreUser> updateWrapper = new LambdaUpdateWrapper<>();
                updateWrapper.eq(StoreUser::getPhone, phone);
                updateWrapper.set(StoreUser::getPassword, newPassword);
                flag = this.update(updateWrapper);

                //修改成功后同步删除redis缓存token
                if (flag) {
                    String token = "store_" + phone;
                    String toKenStr = baseRedisService.getString(token);
                    if (toKenStr != null) {
                        baseRedisService.delete(token);
                    }
                    return R.success("密码修改成");
                } else {
                    log.error("密码修改失败");
                    return R.fail("密码修改失败");
                }
            }
            //更换绑定手机号
            else if (type == 2) {
                return ChangeBoundPhone(phone, newPhone, verificationCode);
            }
            return R.success("密码修改成功");
        } catch (Exception e) {
            return R.fail(e.getMessage());
        }
    }

    @Override
    public Map<String, String> changePhoneVerification(String phone, String oldPassword, String verificationCode) {
        Map<String, String> changePhoneMap = new HashMap<>();

        if (oldPassword != null && !oldPassword.equals("")) {
            LambdaUpdateWrapper<StoreUser> userLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
            userLambdaUpdateWrapper.eq(StoreUser::getPhone, phone);
            StoreUser storeUser = this.getOne(userLambdaUpdateWrapper);
            if (storeUser.getPassword().equals(oldPassword)) {
                changePhoneMap.put("passwordStatus", "1");
                return changePhoneMap;
            } else {
                changePhoneMap.put("passwordStatus", "0");
                return changePhoneMap;
            }
        } else {
            String oldPhoneVerification = "verification_" + phone;
            //获取新手机号验证码
            String redisVerificationCode = baseRedisService.getString(oldPhoneVerification);
            if (redisVerificationCode.equals(verificationCode)) {
                changePhoneMap.put("verificationStatus", "1");
                return changePhoneMap;
            } else {
                changePhoneMap.put("verificationStatus", "0");
                return changePhoneMap;
            }
        }
    }

    private void passwordVerification(String phone, String password, String newPassword, String confirmNewPassword) {
        LambdaUpdateWrapper<StoreUser> wrapperFans = new LambdaUpdateWrapper<>();
        wrapperFans.eq(StoreUser::getPhone, phone);
        StoreUser storeUser = this.getOne(wrapperFans);
        if (!newPassword.equals(confirmNewPassword)) {
            log.info("两次新密码输入不一致 请重新输入");
            throw new RuntimeException("两次新密码输入不一致 请重新输入");
        }
        if (storeUser == null || storeUser.equals("")) {
            log.info("该手机号没有注册过账户");
            throw new RuntimeException("该手机号没有注册过账户");
        } else {
            wrapperFans.eq(StoreUser::getPassword, password);
            StoreUser storeUserPw = this.getOne(wrapperFans);
            if (storeUserPw == null || storeUserPw.getPassword().equals("")) {
                log.info("密码输入错误 请重新输入");
                throw new RuntimeException("密码输入错误 请重新输入");
            }
        }
    }

    private R<String> forgetPassword(String phone, String newPassword, String verificationCode) {
        boolean flag = false;
        String key = "verification_" + phone;
        String redisVerificationCode = baseRedisService.getString(key);
        if (!StringUtils.isEmpty(redisVerificationCode) && redisVerificationCode.equals(verificationCode)) {
            LambdaUpdateWrapper<StoreUser> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(StoreUser::getPhone, phone);
            updateWrapper.set(StoreUser::getPassword, newPassword);
            flag = this.update(updateWrapper);
            if (flag) {
                log.info("密码修改成功");
                String token = "store_" + phone;
                String tokenStr = baseRedisService.getString(token);
                if (tokenStr != null) {
                    baseRedisService.delete(token);
                }
            }
            if (!flag) {
                log.error("密码修改失败");
                throw new RuntimeException("密码修改失败");
            }
            return R.success("密码修改成功");
        } else {
            throw new RuntimeException("验证码错误");
        }
    }

    private R<String> ChangeBoundPhone(String phone, String newPhone, String verificationCode) {
        boolean flag = false;
        String newPhoneVerification = "verification_" + newPhone;
        //获取新手机号验证码
        String redisVerificationCode = baseRedisService.getString(newPhoneVerification);
        if (!StringUtils.isEmpty(redisVerificationCode) && redisVerificationCode.equals(verificationCode)) {
            LambdaUpdateWrapper<StoreUser> newUpdateWrapper = new LambdaUpdateWrapper<>();
            newUpdateWrapper.eq(StoreUser::getPhone, newPhone);
            StoreUser newStoreUser = this.getOne(newUpdateWrapper);
            if (newStoreUser != null) {
                if (newStoreUser.getPhone().equals(newPhone)) {
                    throw new RuntimeException("该手机号已注册过商户");
                }
            } else {
                LambdaUpdateWrapper<StoreUser> updateWrapper = new LambdaUpdateWrapper<>();
                updateWrapper.eq(StoreUser::getPhone, phone);
                StoreUser storeUser = this.getOne(updateWrapper);
                storeUser.setPhone(newPhone);
                flag = this.updateById(storeUser);
                if (flag) {
                    String token = "store_" + phone;
                    String tokenStr = baseRedisService.getString(token);
                    if (tokenStr != null) {
                        baseRedisService.delete(token);
                    }
                }
            }
        } else {
            throw new RuntimeException("验证码错误");
        }
        return R.success("新手机号绑定成功");
    }

    /**
     * 设置用户信息
     *
     * @return boolean
     */
    @Override
    public boolean setUserInfo(StoreUser storeUserParam) {
        StoreUser storeUser = new StoreUser();
        storeUser.setId(storeUserParam.getId());
        //昵称
        if (StringUtils.isNotEmpty(storeUserParam.getNickName())) {
            storeUser.setNickName(storeUserParam.getNickName());
        }
        //身份证号
        if (StringUtils.isNotEmpty(storeUserParam.getIdCard())) {
            storeUser.setIdCard(storeUserParam.getIdCard());
        }
        //姓名
        if (StringUtils.isNotEmpty(storeUserParam.getName())) {
            storeUser.setName(storeUserParam.getName());
        }
        //账号简介
        if (StringUtils.isNotEmpty(storeUserParam.getAccountBlurb())) {
            storeUser.setAccountBlurb(storeUserParam.getAccountBlurb());
        }
        //头像
        if (StringUtils.isNotEmpty(storeUserParam.getHeadImg())) {
            storeUser.setHeadImg(storeUserParam.getHeadImg());
        }
        return this.updateById(storeUser);
    }

    /**
     * 修改支付密码
     *
     * @param id          主键
     * @param payPassword 支付密码
     * @return boolean
     */
    @Override
    public boolean setPayPassword(Integer id, String payPassword) {
        StoreUser storeUser = new StoreUser();
        storeUser.setId(id);
        storeUser.setPayPassword(payPassword);
        return this.updateById(storeUser);
    }

    @Override
    public R<StoreUserVo> addStoreUser(StoreUserVo storeUserVo) {
        //判断当前手机号是否存在
        StoreUser phoneHave = storeUserMapper.selectOne(new LambdaQueryWrapper<StoreUser>().eq(StoreUser::getPhone, storeUserVo.getPhone()));
        if (phoneHave != null) {
            throw new RuntimeException("手机号已存在！！");
        }
        StoreUserVo vo = new StoreUserVo();
        StoreUser storeUser = new StoreUser();
        BeanUtils.copyProperties(storeUserVo, storeUser);
        //存入密码类型为已修改  2025-4-22 业务修改
        storeUser.setPassType(2);
        int insert = storeUserMapper.insert(storeUser);
        BeanUtils.copyProperties(storeUser, vo);
        return R.data(vo);
    }

    @Override
    public R<IPage<StoreUserVo>> getStoreUserList(int pageNum, int pageSize, String id, String phone, Integer status) {
        IPage<StoreUser> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<StoreUser> storeUserLambdaQueryWrapper = new LambdaQueryWrapper<>();
        storeUserLambdaQueryWrapper.like(!StringUtils.isEmpty(id), StoreUser::getId, id);
        storeUserLambdaQueryWrapper.like(!StringUtils.isEmpty(phone), StoreUser::getPhone, phone);
        storeUserLambdaQueryWrapper.eq(status != null, StoreUser::getStatus, status);
        storeUserLambdaQueryWrapper.orderByDesc(StoreUser::getCreatedTime);
        IPage<StoreUser> storeUsers = storeUserMapper.selectPage(page, storeUserLambdaQueryWrapper);
        IPage<StoreUserVo> storeUserVoIPage = new Page<>();
        BeanUtils.copyProperties(storeUsers, storeUserVoIPage);
        for (StoreUser storeUser : storeUserVoIPage.getRecords()) {
            //不返回密码
            storeUser.setPassword(null);
            storeUser.setPayPassword(null);
        }
        return R.data(storeUserVoIPage);
    }

    @Override
    public R<StoreUserVo> editStoreUser(StoreUser storeUser) {
        storeUserMapper.updateById(storeUser);
        StoreUserVo storeUserVo = new StoreUserVo();
        BeanUtils.copyProperties(storeUser, storeUserVo);
        return R.data(storeUserVo);
    }

    @Override
    public void resetStoreUserPassword(StoreUser storeUser) {
        StoreUser storeUserById = storeUserMapper.selectById(storeUser.getId());
        //初始化密码赋值
        storeUserById.setPassword(DEFAULT_PASSWORD);
        storeUserById.setPayPassword(DEFAULT_PASSWORD);
        storeUserMapper.updateById(storeUserById);
    }

    @Override
    public R<StoreUserVo> deleteStoreUser(String id) {
        StoreUser storeUser = storeUserMapper.selectById(id);
        String phone = storeUser.getPhone();
        Integer storeId = storeUser.getStoreId();

        // 判断该账号是否关联店铺
        if (ObjectUtils.isNotEmpty(storeId)) {
            List<StoreInfo> storeInfos = storeInfoMapper.selectList(new LambdaQueryWrapper<StoreInfo>().eq(StoreInfo::getId, storeId).eq(StoreInfo::getDeleteFlag, 0).eq(StoreInfo::getLogoutFlag, 0));
            if (ObjectUtils.isNotEmpty(storeInfos)) {
                return R.fail("请删除店铺后再删除账号");
            }
        }

        storeUserMapper.deleteById(id);
        //删除用户redis中的token
        baseRedisService.delete("store_" + storeUser.getPhone());
        //删除该账号的店铺
        storeInfoMapper.delete(new LambdaQueryWrapper<StoreInfo>().eq(StoreInfo::getId, storeId));
        //删除该账号的动态
        lifeUserDynamicsMapper.delete(new LambdaQueryWrapper<LifeUserDynamics>().eq(LifeUserDynamics::getPhoneId, "store_" + phone));
        //删除该账号关注的信息
        lifeFansMapper.delete(new LambdaQueryWrapper<LifeFans>().eq(LifeFans::getFansId, "store_" + phone));
        //删除关注该账号的信息
        lifeFansMapper.delete(new LambdaQueryWrapper<LifeFans>().eq(LifeFans::getFollowedId, "store_" + phone));
        //删除该账号的通知信息
        lifeNoticeMapper.delete(new LambdaQueryWrapper<LifeNotice>().eq(LifeNotice::getReceiverId, "store_" + phone));
        //删除该账号的发送消息信息
        lifeMessageMapper.delete(new LambdaQueryWrapper<LifeMessage>().eq(LifeMessage::getSenderId, "store_" + phone));
        //删除该账号的接受消息信息
        lifeMessageMapper.delete(new LambdaQueryWrapper<LifeMessage>().eq(LifeMessage::getReceiverId, "store_" + phone));

        return R.success("删除成功");
    }

    @Override
    public void switchingStates(StoreUser storeUserParam) {
        StoreUser storeUser = storeUserMapper.selectById(storeUserParam.getId());
        //如果当前为启用，则删除token
        if (storeUser.getStatus() == 0) {
            //删除用户redis中的token
            baseRedisService.delete("store_" + storeUser.getPhone());
        }
        //根据当前状态切另一个状态
        storeUser.setStatus(storeUser.getStatus() == 0 ? 1 : 0);
        storeUserMapper.updateById(storeUser);
    }

    @Override
    public String exportExcel(String id, String phone, String status) throws IOException {
        // 定义格式化模式
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        // 先将 Date 转换为 Instant
        List<StoreUser> storeUsers = storeUserMapper.selectList(
                new LambdaQueryWrapper<StoreUser>()
                        .like(StringUtils.isNotEmpty(id), StoreUser::getId, id)
                        .like(StringUtils.isNotEmpty(phone), StoreUser::getPhone, phone)
                        .eq(StringUtils.isNotEmpty(status), StoreUser::getStatus, status)
        );
        List<StoreUserExcelVo> storeUserExcelVoList = new ArrayList<>();
        int serialNumber = 0;
        for (StoreUser storeUser : storeUsers) {
            StoreUserExcelVo storeUserExcelVo = new StoreUserExcelVo();
            storeUserExcelVo.setSerialNumber(++serialNumber);
            BeanUtils.copyProperties(storeUser, storeUserExcelVo);
            Instant instant = storeUser.getCreatedTime().toInstant();
            // 格式化时间
            String formattedTime = instant.atZone(ZoneId.systemDefault()).toLocalDateTime().format(formatter);
            storeUserExcelVo.setCreatedTime(formattedTime);
            //格式化状态
            storeUserExcelVo.setStatus(storeUser.getStatus() == 0 ? "启用" : "禁用");
            storeUserExcelVoList.add(storeUserExcelVo);
        }
        String fileName = UUID.randomUUID().toString().replace("-", "");
        String filePath = ExcelGenerator.generateExcel(excelPath + excelGeneratePath + fileName + ".xlsx", storeUserExcelVoList, StoreUserExcelVo.class);
        return aliOSSUtil.uploadFile(new File(filePath), "excel/" + fileName + ".xlsx");
    }

    /**
     * 注册校验
     *
     * @param phone
     * @return
     */
    public boolean checkRegister(String phone) {
        LambdaQueryWrapper<StoreUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StoreUser::getPhone, phone);
        queryWrapper.in(StoreUser::getStatus, 0, 1);
        List<StoreUser> storeUsers = storeUserMapper.selectList(queryWrapper);
        return CollectionUtils.isEmpty(storeUsers) ? Boolean.TRUE : Boolean.FALSE;
    }

    /**
     * 注册
     *
     * @param phone
     * @param password
     * @return
     */
    @Override
    public R<Boolean> register(String phone, String password) {

        LambdaQueryWrapper<StoreUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StoreUser::getPhone, phone)
                .orderByDesc(StoreUser::getCreatedTime).last("LIMIT 1");
        StoreUser storeUser = storeUserMapper.selectOne(queryWrapper);

        List<Integer> noRegister = Arrays.asList(0, 1);

        if (Objects.isNull((storeUser))) {
            // 没有数据
            saveNewUser(phone, password);
            return R.success("操作成功");

        } else if (noRegister.contains(storeUser.getStatus())) {
            return R.fail("手机号已经注册过");
        }

        int daysSinceDeletion = DateUtils.subtraction(storeUser.getCreatedTime(), new Date());
        if (daysSinceDeletion < 30) return R.fail(String.format("请于%d天后重新申请注册", 30 - daysSinceDeletion));
        saveNewUser(phone, password);
        return R.success("操作成功");

    }

    @Override
    public Map<String, String> storeCancelAccountVerification(StoreUserVo storeUserVo) {
        // 通过id获取当前商家账号信息
        LambdaQueryWrapper<StoreUser> storeUserLambdaQueryWrapper = new LambdaQueryWrapper<>();
        storeUserLambdaQueryWrapper.eq(StoreUser::getId, storeUserVo.getId());
        StoreUser storeUser = storeUserMapper.selectOne(storeUserLambdaQueryWrapper);
        Map<String, String> storeMap = new HashMap<>();
        if (storeUser != null) {
            storeMap.put("status", storeUser.getStatus().toString());
            if (null != storeUser.getStoreId()) {
                StoreInfo storeInfo = storeInfoMapper.selectById(storeUser.getStoreId());
                //vaule为0代表有商铺未注销
                storeMap.put("accountStore", "0");
            } else {
                //vaule为1代表绑定店铺已注销
                storeMap.put("accountStore", "1");
            }
            //钱包功能暂未完成此效验默认状态都是1通过
            if (storeUser.getMoney() != null && storeUser.getMoney() > 0) {
                //vaule为0代表有未体现的现金
                storeMap.put("accountMoney", "0");
            } else {
                //vaule为1代表没有未体现的现金
                storeMap.put("accountMoney", "1");
            }
        }
        return storeMap;
    }


    /**
     * @param phone
     * @return
     */
    @Override
    public R<Boolean> checkLogin(String phone) {
        LambdaQueryWrapper<StoreUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StoreUser::getPhone, phone)
                .orderByDesc(StoreUser::getCreatedTime).last("LIMIT 1");
        StoreUser storeUser = storeUserMapper.selectOne(queryWrapper);
        // 用户状态 0：启用，1：禁用，2:已注销
        if (Objects.isNull(storeUser)) {
            return R.success("用户不存在，快去注册吧！");
        } else if (storeUser.getStatus() == 1) {
            return R.success("账号已被禁用");
        } else if (storeUser.getStatus() == 2) {
            return R.success("账号已注销");
        }
        return R.success("success");
    }


    /**
     * save User
     *
     * @param phone
     * @param password
     */
    private void saveNewUser(String phone, String password) {
        StoreUser registerStoreUser = new StoreUser();
        registerStoreUser.setPhone(phone);
        registerStoreUser.setPassword(password);
        registerStoreUser.setPassType(2);
        registerStoreUser.setMoney(0);
        registerStoreUser.setDeleteFlag(0);
        registerStoreUser.setStatus(0);
        registerStoreUser.setIdCard("test");
        registerStoreUser.setPassType(2);
        registerStoreUser.setCreatedTime(new Date());
        registerStoreUser.setLogoutFlag(0);
        registerStoreUser.setNickName(phone);
        storeUserMapper.insert(registerStoreUser);
    }

    @Override
    public void storeCancelAccount(StoreUserVo storeUserVo) {
        // 通过id获取当前商家账号信息
        LambdaQueryWrapper<StoreUser> storeUserLambdaQueryWrapper = new LambdaQueryWrapper<>();
        storeUserLambdaQueryWrapper.eq(StoreUser::getId, storeUserVo.getId());
        StoreUser storeUser = storeUserMapper.selectOne(storeUserLambdaQueryWrapper);
        String key = "verification_" + storeUser.getPhone();
        String redisVerificationCode = baseRedisService.getString(key);
        if (redisVerificationCode != null) {
            if (redisVerificationCode.equals(storeUserVo.getVerificationCode())) {
                if (storeUser != null) {
                    // 添加注销原因
                    storeUser.setLogoutReason(storeUserVo.getLogoutReason());
                    // 添加注销code
                    storeUser.setLogoutCode(storeUserVo.getLogoutCode());
                    // 注销中状态
                    storeUser.setStatus(-1);
                    // 添加注销申请时间
                    storeUser.setLogoutTime(new Date());
                    // 更新logout_flag状态为1
                    storeUser.setLogoutFlag(1);
                    int num = storeUserMapper.updateById(storeUser);
                    if (num > 0) {
                        // 发送通知
                        LifeNotice lifeMessage = new LifeNotice();
                        lifeMessage.setReceiverId("store_" + new DateTime());
                        String text = "您提交的账号注销申请已成功提交, 系统将按流程进行处理. 注销申请提交后, 将进入7天的冷静期. 期间您可以随时在" +
                                "[账号信息]撤回申请. 冷静期结束后, 系统将正式开始注销操作. 账号内所有数据(包括但不限于个人信息、 资产等) 将被永久清除, 且无法恢复." +
                                "如有疑问, 可联系【客服】咨询. 感谢您使用我们的服务.";
                        lifeMessage.setContext(text);
                        lifeMessage.setTitle("注销商家账号通知");
                        lifeMessage.setSenderId("system");
                        lifeMessage.setIsRead(0);
                        lifeMessage.setNoticeType(1);
                        lifeNoticeMapper.insert(lifeMessage);
                    }
                }
            } else {
                throw new RuntimeException("验证码错误");
            }
        } else {
            throw new RuntimeException("验证码错误");
        }
    }

    @Override
    public void storeCancelAccountUn(StoreUserVo storeUserVo) {
        // 通过id获取当前商家账号信息
        LambdaQueryWrapper<StoreUser> storeUserLambdaQueryWrapper = new LambdaQueryWrapper<>();
        storeUserLambdaQueryWrapper.eq(StoreUser::getId, storeUserVo.getId());
        StoreUser storeUser = storeUserMapper.selectOne(storeUserLambdaQueryWrapper);
        // 修改注销标记为0
        storeUser.setLogoutFlag(0);
        // 注销状态变为可用
        storeUser.setStatus(0);
        // 清空注销原因
        storeUser.setLogoutReason("");
        // 清空注销code
        storeUser.setLogoutCode("");
        // 清空注销申请时间
        storeUser.setLogoutTime(null);
        // 更新logout_flag状态为0
        storeUser.setLogoutFlag(0);
        int num = storeUserMapper.updateById(storeUser);
        if (num > 0) {
            // 发送通知
            LifeNotice lifeMessage = new LifeNotice();
            lifeMessage.setReceiverId("store_" + storeUser.getPhone());
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String storeDate = simpleDateFormat.format(storeUser.getCreatedTime());
            String text = "处理结果：已撤回注销申请" +
                    "处理时间：" + storeDate +
                    "当前账号状态已恢复正常. 您可以继续使用该账号登录并享受各项服务, 所有个人数据及账户信息" +
                    "均已妥善保留. 若您后续仍有注销需求, 可随时通过账号信息页面重新提交申请. 感谢您的理解与支持!";
            lifeMessage.setContext(text);
            lifeMessage.setTitle("撤销商家账号注销通知");
            lifeMessage.setSenderId("system");
            lifeMessage.setIsRead(0);
            lifeMessage.setNoticeType(1);
            lifeNoticeMapper.insert(lifeMessage);
        }
    }

    @Override
    public void deleteStoreAccountInfo(StoreUserVo storeUserVo) {
        LambdaQueryWrapper<StoreUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StoreUser::getId, storeUserVo.getId());
        queryWrapper.eq(StoreUser::getDeleteFlag, 0);
        StoreUser storeUser = storeUserMapper.selectOne(queryWrapper);
        // 删除已过注销时间的商家
        if (storeUser != null) {
            storeUserMapper.deleteById(storeUserVo.getId());
            nearMeService.removeGeolocation(Boolean.TRUE, storeUser.getId().toString());
            String storePhone = "store_" + storeUserVo.getPhone();
            String key = baseRedisService.getString(storePhone);
            if (key != null) {
                //删除用户redis中的token
                baseRedisService.delete(key);
            }
            LambdaQueryWrapper<LifeFans> lifeFansLambdaQueryWrapper = new LambdaQueryWrapper<LifeFans>().eq(LifeFans::getFollowedId, "store_" + storeUser.getPhone())
                    .or().eq(LifeFans::getFansId, "store_" + storeUser.getPhone());
            lifeFansMapper.delete(lifeFansLambdaQueryWrapper);
            if (storeUser.getStoreId() != null) {
                storeInfoMapper.deleteById(storeUser.getStoreId());
            }
        }
    }

    @Override
    public List<String> getIds(String name, String phone) {
        if (Objects.isNull(name) && Objects.isNull(phone)) return Collections.singletonList("");
        LambdaQueryWrapper<StoreUser> wrapper = new LambdaQueryWrapper<>();
        List<Triple<Boolean, SFunction<StoreUser, ?>, Object>> conditions = new ArrayList<>();
        conditions.add(Triple.of(StringUtils.isNotEmpty(name), StoreUser::getName, name));
        conditions.add(Triple.of(StringUtils.isNotEmpty(phone), StoreUser::getPhone, phone));
        FunctionMagic.buildLikeConditions(wrapper, conditions);
        List<String> res = FunctionMagic.convertToIds(storeUserMapper.selectList(wrapper), StoreUser::getId);
        return CollectionUtils.isEmpty(res) ? Collections.singletonList("") : res;
    }

    @Override
    public R havePayPassword(String storeUserId,String password) {
        StoreUser storeUser = storeUserMapper.selectById(storeUserId);
        HashMap<Object, Object> returnMap = new HashMap<>();
        returnMap.put("code",200);
        if (null == storeUser) {
            returnMap.put("message","未查询到用户");
            returnMap.put("data","false");
            return R.data(returnMap);
        }
        if( null == storeUser.getPayPassword()){
            returnMap.put("message","用户未设置支付密码");
            returnMap.put("data","false");
            return R.data(returnMap);
        } else if(null != password){
            if( !password.equals(storeUser.getPayPassword())){
                returnMap.put("message","密码错误");
                returnMap.put("data","false");
                return R.data(returnMap);
            }
        }
        returnMap.put("data","true");
        returnMap.put("message","用户已设置支付密码");
        return R.data(returnMap);
    }

}
