package shop.alien.store.service;

import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
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 org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Triple;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import shop.alien.config.properties.RiskControlProperties;
import shop.alien.entity.second.LifeUserLog;
import shop.alien.entity.second.SecondRiskControlRecord;
import shop.alien.entity.store.LifeFans;
import shop.alien.entity.store.LifeNotice;
import shop.alien.entity.store.LifeUser;
import shop.alien.entity.store.vo.LifeMessageVo;
import shop.alien.entity.store.vo.LifeUserVo;
import shop.alien.entity.store.vo.WebSocketVo;
import shop.alien.mapper.LifeFansMapper;
import shop.alien.mapper.LifeMessageMapper;
import shop.alien.mapper.LifeNoticeMapper;
import shop.alien.mapper.LifeUserMapper;
import shop.alien.mapper.second.LifeUserLogMapper;
import shop.alien.mapper.second.SecondRiskControlRecordMapper;
import shop.alien.mapper.second.SecondUserCreditMapper;
import shop.alien.store.config.BaseRedisService;
import shop.alien.store.config.WebSocketProcess;
import shop.alien.store.feign.SecondServiceFeign;
import shop.alien.store.util.FunctionMagic;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 用户
 */
@Service
@RequiredArgsConstructor
public class LifeUserService extends ServiceImpl<LifeUserMapper, LifeUser> {

    private final LifeUserMapper lifeUserMapper;

    private final LifeFansMapper lifeFansMapper;

    private final BaseRedisService baseRedisService;

    private final LifeNoticeMapper lifeNoticeMapper;

    private final LifeMessageMapper messageMapper;

    private final WebSocketProcess webSocketProcess;

    private final ActivityInviteConfigService activityInviteConfigService;

    private final LifeUserLogMapper lifeUserLogMapper;

    private final SecondServiceFeign alienSecondFeign;

    private final SecondUserCreditMapper secondUserCreditMapper;

    private final SecondRiskControlRecordMapper secondRiskControlRecordMapper;

    @Autowired
    private RiskControlProperties riskControlProperties;

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

    public IPage<LifeUser> getStoresPage(int page, int size, String realName, String userPhone) {
        IPage<LifeUser> storePage = new Page<>(page, size);
        QueryWrapper<LifeUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.like(!realName.isEmpty(), "real_name", realName);
        queryWrapper.like(!userPhone.isEmpty(), "user_phone", userPhone);
        queryWrapper.orderByDesc("created_time");
        return lifeUserMapper.selectPage(storePage, queryWrapper);
    }

    public int modifyUser(LifeUser user) {
        return lifeUserMapper.updateById(user);
    }

    public int addOrUpdateUser(LifeUser user) {
        user.setCreatedTime(new Date());
        return lifeUserMapper.insert(user);
    }

    public LifeUser getUserById(String id) {
        return lifeUserMapper.selectById(id);
    }

    public int addFans(LifeFans fans) {
        fans.setCreatedTime(new Date());
        int num = lifeFansMapper.insert(fans);

        if (num == 1) {
            LifeNotice notice = new LifeNotice();
            notice.setTitle("关注通知");
            notice.setContext("关注了你");
            notice.setNoticeType(0);
            notice.setReceiverId(fans.getFollowedId());
            notice.setSenderId(fans.getFansId());

            // 根据手机号查询发送人信息
            String storePhones = "''";
            String userPhones = "''";
            if (fans.getFansId().split("_")[0].equals("store")) {
                storePhones = "'" + fans.getFansId().split("_")[1] + "'";
            } else {
                userPhones = "'" + fans.getFansId().split("_")[1] + "'";
            }
            List<LifeMessageVo> userList = messageMapper.getLifeUserAndStoreUserByPhone(storePhones, userPhones);
            if (!CollectionUtils.isEmpty(userList)) {
                notice.setBusinessId(userList.get(0).getId());
            }
            lifeNoticeMapper.insert(notice);
        }

        return num;
    }

    public int cancelFans(LifeFans fans) {
        LambdaUpdateWrapper<LifeFans> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(LifeFans::getFansId, fans.getFansId());
        wrapper.eq(LifeFans::getFollowedId, fans.getFollowedId());
        return lifeFansMapper.delete(wrapper);
    }

    public IPage<LifeUserVo> getStoreAndUserByName(LifeUserVo vo) {
        QueryWrapper<LifeUserVo> queryWrapper = new QueryWrapper<>();
        queryWrapper.like(StringUtils.isNotEmpty(vo.getSearchName()), "a.storeUserName", vo.getSearchName());
        IPage<LifeUserVo> voList = lifeUserMapper.getStoreAndUserByName(new Page<>(vo.getPage(), vo.getSize()), queryWrapper);

        // 查询我的关注
        LambdaQueryWrapper<LifeFans> lifeFansWrapper = new LambdaQueryWrapper<>();
        lifeFansWrapper.eq(LifeFans::getFansId, vo.getPhoneId());
        List<LifeFans> lifeFansList = lifeFansMapper.selectList(lifeFansWrapper);
        List<String> followList = lifeFansList.stream().map(LifeFans::getFollowedId).collect(Collectors.toList());

        voList.getRecords().forEach(item -> {
            if (followList.contains(item.getPhoneId())) {
                item.setIsFollowThis("1");
            } else {
                item.setIsFollowThis("0");
            }
        });
        return voList;
    }

    public LifeUser getUserByPhone(String phoneNum) {
        LambdaQueryWrapper<LifeUser> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(LifeUser::getUserPhone, phoneNum);
        return this.getOne(lambdaQueryWrapper);
    }

    public void liftCancelAccount(LifeUser user) {
        // 通过id获取当前用户账号信息
        LambdaQueryWrapper<LifeUser> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(LifeUser::getId, user.getId());
        LifeUser lifeUser = lifeUserMapper.selectOne(lambdaQueryWrapper);
        // 修改注销标记为1
        lifeUser.setLogoutFlag(1);
        // 添加注销原因
        lifeUser.setLogoutReason(user.getLogoutReason());
        // 添加注销申请时间
        lifeUser.setLogoutTime(new Date());
        lifeUserMapper.updateById(lifeUser);
    }

    public void liftCancelAccountUn(Integer id) {
        LambdaQueryWrapper<LifeUser> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(LifeUser::getId, id);
        LifeUser lifeUser = lifeUserMapper.selectOne(lambdaQueryWrapper);
        // 修改注销标记为0
        lifeUser.setLogoutFlag(0);
        // 清空注销原因
        lifeUser.setLogoutReason(null);
        // 清空注销申请时间
        lifeUser.setLogoutTime(null);
        lifeUserMapper.updateById(lifeUser);
    }

    public List<String> getIds(String name, String phone) {
        if (Objects.isNull(name) && Objects.isNull(phone)) return Arrays.asList("");
        LambdaQueryWrapper<LifeUser> wrapper = new LambdaQueryWrapper<>();
        List<Triple<Boolean, SFunction<LifeUser, ?>, Object>> conditions = new ArrayList<>();
        conditions.add(Triple.of(StringUtils.isNotEmpty(name), LifeUser::getUserName, name));
        conditions.add(Triple.of(StringUtils.isNotEmpty(phone), LifeUser::getUserPhone, phone));
        FunctionMagic.buildLikeConditions(wrapper, conditions);
        List<String> res = FunctionMagic.convertToIds(lifeUserMapper.selectList(wrapper), LifeUser::getId);
        return CollectionUtils.isEmpty(res) ? Arrays.asList("") : res;
    }

    public boolean checkRealInfo(LifeUser user) {
        LifeUser lifeUser = lifeUserMapper.selectById(user.getId());
        if (lifeUser != null) {
            String realName = user.getRealName();
            String idCard = user.getIdCard();
            if ((realName == null && lifeUser.getRealName() == null) || (idCard == null && lifeUser.getIdCard() == null)) {
                return false;
            }
            return (StringUtils.isNotEmpty(realName) && !realName.equals(lifeUser.getRealName())) || (StringUtils.isNotEmpty(idCard) && !idCard.equals(lifeUser.getIdCard()));
        }
        return false;
    }

    public void sendNotice(LifeUser user) {
        String receiverId = "user_" + user.getUserPhone();
        LifeNotice lifeNotice = new LifeNotice();
        lifeNotice.setReceiverId(receiverId);
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String storeDate = simpleDateFormat.format(new Date());
        String text = "您在" + storeDate + "实名认证成功。";
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("message", text);
        lifeNotice.setContext(jsonObject.toJSONString());
        lifeNotice.setTitle("实名认证通知");
        lifeNotice.setSenderId("system");
        lifeNotice.setIsRead(0);
        lifeNotice.setNoticeType(1);
        lifeNoticeMapper.insert(lifeNotice);

        WebSocketVo websocketVo = new WebSocketVo();
        websocketVo.setSenderId("system");
        websocketVo.setReceiverId(receiverId);
        websocketVo.setCategory("notice");
        websocketVo.setNoticeType("1");
        websocketVo.setIsRead(0);
        websocketVo.setText(JSONObject.from(lifeNotice).toJSONString());
        try {
            webSocketProcess.sendMessage(receiverId, JSONObject.from(websocketVo).toJSONString());
        } catch (Exception e) {
            log.error("LifeUserService webSocketProcess Stack={}", e);
        }
    }

    @Transactional
    public void addLifeUserLogInfo(LifeUser user, String macIp) {
        try {
            LifeUserLog lifeUserLog = new LifeUserLog();
            lifeUserLog.setUserId(user.getId());
            lifeUserLog.setUserName(user.getUserName());
            lifeUserLog.setMacIp(macIp);
            lifeUserLog.setCreatedTime(new Date());
            int count = lifeUserLogMapper.insert(lifeUserLog);
            if (count > 0) {
                String startDate = LocalDateTime.now().minusHours(24L).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
                String endDate = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
                // 使用一个新的事务来查询，确保能看到刚才插入的数据
                List<LifeUserLog> lsit = getLifeUserLogByDateInNewTransaction(startDate, endDate, macIp);

                if (lsit.size() > riskControlProperties.getAccountAbnormal().getRegCount24h() && !isViolation(startDate, endDate, macIp, user.getId())) {
                    String detailInfo = lsit.stream()
                            .map(row -> row.getUserId().toString())
                            .collect(Collectors.joining(","));
                    alienSecondFeign.recordRiskControlData(user.getId(), 2, "账号异常", macIp, detailInfo);
                }
            }
            // 第一次登录，添加用户基础积分
            alienSecondFeign.createPointsRecord(user.getId(), 300, 1);
        } catch (Exception e) {
            log.error("用户登录log存放异常：{}", e);
        }
    }

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public List<LifeUserLog> getLifeUserLogByDateInNewTransaction(String startDate, String endDate, String macIp) {
        return lifeUserLogMapper.getLifeUserLogByDate(startDate, endDate, macIp);
    }

    public boolean isViolation(String startDate, String endDate, String macIp, Integer userId) {
        List<SecondRiskControlRecord> list = secondRiskControlRecordMapper.selectByBusinessId(startDate, endDate, macIp);
        for (SecondRiskControlRecord record : list) {
            // 将数组转换为包含整数的列表
            List<Integer> userIdList = Arrays.stream(record.getDetailInfo().split(","))
                    .map(Integer::parseInt)
                    .collect(Collectors.toList());
            if (userIdList.contains(userId)) {
                return true;
            }
        }
        return false;
    }
}
