package shop.alien.storeplatform.service.impl;

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.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import shop.alien.entity.store.LifeNotice;
import shop.alien.entity.store.LifeUser;
import shop.alien.entity.store.vo.WebSocketVo;
import shop.alien.entity.storePlatform.StoreOperationalActivity;
import shop.alien.entity.storePlatform.StoreOperationalActivitySignup;
import shop.alien.entity.storePlatform.vo.StoreOperationalActivitySignupVO;
import shop.alien.mapper.LifeNoticeMapper;
import shop.alien.util.type.LifeNoticeUtil;
import shop.alien.mapper.LifeUserMapper;
import shop.alien.mapper.storePlantform.StoreOperationalActivityMapper;
import shop.alien.mapper.storePlantform.StoreOperationalActivitySignupMapper;
import shop.alien.storeplatform.feign.AlienStoreFeign;
import shop.alien.storeplatform.service.OperationalActivitySignupService;
import shop.alien.util.common.Constants;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 运营活动报名服务实现类
 *
 * @author system
 * @since 2025-01-XX
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class OperationalActivitySignupServiceImpl implements OperationalActivitySignupService {

    private final StoreOperationalActivitySignupMapper signupMapper;
    private final StoreOperationalActivityMapper activityMapper;
    private final LifeUserMapper lifeUserMapper;
    private final LifeNoticeMapper lifeNoticeMapper;

    private final LifeNoticeUtil lifeNoticeUtil;
    private final AlienStoreFeign alienStoreFeign;

    @Override
    public IPage<StoreOperationalActivitySignupVO> querySignupList(Integer storeId, Integer status, String activityName, Integer pageNum, Integer pageSize) {
        log.info("OperationalActivitySignupServiceImpl.querySignupList: storeId={}, status={}, activityName={}, pageNum={}, pageSize={}", 
                storeId, status, activityName, pageNum, pageSize);

        if (storeId == null || storeId <= 0) {
            throw new IllegalArgumentException("商户ID不能为空");
        }

        // 构建查询条件
        LambdaQueryWrapper<StoreOperationalActivitySignup> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(StoreOperationalActivitySignup::getStoreId, storeId);
        
        if (status != null) {
            wrapper.eq(StoreOperationalActivitySignup::getStatus, status);
        }

        // 如果指定了活动名称，先查询活动ID列表
        if (activityName != null && !activityName.trim().isEmpty()) {
            LambdaQueryWrapper<StoreOperationalActivity> activityWrapper = new LambdaQueryWrapper<>();
            activityWrapper.eq(StoreOperationalActivity::getStoreId, storeId)
                    .like(StoreOperationalActivity::getActivityName, activityName.trim())
                    .eq(StoreOperationalActivity::getDeleteFlag, 0);
            List<StoreOperationalActivity> activities = activityMapper.selectList(activityWrapper);
            if (activities.isEmpty()) {
                // 如果没有匹配的活动，返回空结果
                return new Page<>(pageNum, pageSize);
            }
            List<Integer> activityIds = activities.stream()
                    .map(StoreOperationalActivity::getId)
                    .collect(Collectors.toList());
            wrapper.in(StoreOperationalActivitySignup::getActivityId, activityIds);
        }

        wrapper.orderByDesc(StoreOperationalActivitySignup::getCreatedTime);

        // 分页查询
        IPage<StoreOperationalActivitySignup> page = new Page<>(pageNum, pageSize);
        IPage<StoreOperationalActivitySignup> signupPage = signupMapper.selectAll(page, wrapper);
        // 转换为VO
        IPage<StoreOperationalActivitySignupVO> voPage = new Page<>(pageNum, pageSize);
        voPage.setTotal(signupPage.getTotal());
        voPage.setPages(signupPage.getPages());

        List<StoreOperationalActivitySignupVO> voList = signupPage.getRecords().stream().map(signup -> {
            StoreOperationalActivitySignupVO vo = new StoreOperationalActivitySignupVO();
            BeanUtils.copyProperties(signup, vo);

            // 设置报名人姓名和手机号（signupname 和 signupphone）
            vo.setSignupName(signup.getUserName());
            vo.setSignupPhone(signup.getPhone());

            // 查询活动名称和活动类型
            LambdaQueryWrapper<StoreOperationalActivity> activityWrapper = new LambdaQueryWrapper<>();
            activityWrapper.eq(StoreOperationalActivity::getId, signup.getActivityId())
                    .eq(StoreOperationalActivity::getDeleteFlag, 0);
            StoreOperationalActivity activity = activityMapper.selectOne(activityWrapper);
            if (activity != null) {
                vo.setActivityName(activity.getActivityName());
                vo.setActivityType(activity.getActivityType());
            }

            // 查询用户昵称
            if (signup.getUserId() != null) {
                LifeUser lifeUser = lifeUserMapper.selectById(signup.getUserId());
                if (lifeUser != null && lifeUser.getUserName() != null) {
                    vo.setNickName(lifeUser.getUserName());
                    vo.setUserImage(lifeUser.getUserImage());
                    vo.setUserPhone(lifeUser.getUserPhone());
                    vo.setUserName(lifeUser.getUserName());
                }
            }

            // 设置状态文字
            vo.setStatusText(getStatusText(signup.getStatus()));

            return vo;
        }).collect(Collectors.toList());

        voPage.setRecords(voList);
        return voPage;
    }

    @Override
    public StoreOperationalActivitySignupVO querySignupById(Integer id) {
        log.info("OperationalActivitySignupServiceImpl.querySignupById: id={}", id);

        if (id == null || id <= 0) {
            throw new IllegalArgumentException("报名ID不能为空");
        }

        StoreOperationalActivitySignup signup = signupMapper.selectById(id);
        if (signup == null) {
            return null;
        }

        StoreOperationalActivitySignupVO vo = new StoreOperationalActivitySignupVO();
        BeanUtils.copyProperties(signup, vo);

        // 设置报名人姓名和手机号（signupname 和 signupphone）
        vo.setSignupName(signup.getUserName());
        vo.setSignupPhone(signup.getPhone());

        // 查询活动名称和活动类型
        LambdaQueryWrapper<StoreOperationalActivity> activityWrapper = new LambdaQueryWrapper<>();
        activityWrapper.eq(StoreOperationalActivity::getId, signup.getActivityId())
                .eq(StoreOperationalActivity::getDeleteFlag, 0);
        StoreOperationalActivity activity = activityMapper.selectOne(activityWrapper);
        if (activity != null) {
            vo.setActivityName(activity.getActivityName());
            vo.setActivityType(activity.getActivityType());
            vo.setAuditTime(activity.getAuditTime());
        }

        // 查询用户昵称
        if (signup.getUserId() != null) {
            LifeUser lifeUser = lifeUserMapper.selectById(signup.getUserId());
            if (lifeUser != null && lifeUser.getUserName() != null) {
                vo.setNickName(lifeUser.getUserName());
            }
        }

        // 设置状态文字
        vo.setStatusText(getStatusText(signup.getStatus()));

        return vo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int approveSignup(Integer id) {
        log.info("OperationalActivitySignupServiceImpl.approveSignup: id={}", id);

        if (id == null || id <= 0) {
            throw new IllegalArgumentException("报名ID不能为空");
        }

        StoreOperationalActivitySignup signup = signupMapper.selectById(id);
        if (signup == null) {
            throw new IllegalArgumentException("报名记录不存在");
        }
        if (signup.getStatus() == null || signup.getStatus() != 0) {
            throw new IllegalArgumentException("仅待审核的报名可通过");
        }

        LambdaUpdateWrapper<StoreOperationalActivitySignup> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(StoreOperationalActivitySignup::getId, id)
                .eq(StoreOperationalActivitySignup::getStatus, 0)
                .set(StoreOperationalActivitySignup::getStatus, 2) // 2-通过
                .set(StoreOperationalActivitySignup::getAuditTime, new Date()); // 设置审核时间为当前时间

        int result = signupMapper.update(null, wrapper);

        // 审核成功后同步活动状态并发送通知
        if (result > 0) {
            syncActivitySignupStatus(signup.getActivityId());
            try {
                sendApprovalNotice(id, true);
            } catch (Exception e) {
                log.error("发送审核通过通知失败，signupId={}, error={}", id, e.getMessage(), e);
            }
        }

        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int rejectSignup(Integer id, String rejectReason) {
        log.info("OperationalActivitySignupServiceImpl.rejectSignup: id={}, rejectReason={}", id, rejectReason);

        if (id == null || id <= 0) {
            throw new IllegalArgumentException("报名ID不能为空");
        }

        StoreOperationalActivitySignup signup = signupMapper.selectById(id);
        if (signup == null) {
            throw new IllegalArgumentException("报名记录不存在");
        }
        if (signup.getStatus() == null || signup.getStatus() != 0) {
            throw new IllegalArgumentException("仅待审核的报名可拒绝");
        }

        LambdaUpdateWrapper<StoreOperationalActivitySignup> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(StoreOperationalActivitySignup::getId, id)
                .eq(StoreOperationalActivitySignup::getStatus, 0)
                .set(StoreOperationalActivitySignup::getStatus, 1) // 1-拒绝
                .set(StoreOperationalActivitySignup::getAuditTime, new Date()); // 设置审核时间为当前时间

        // 如果提供了拒绝原因，则保存；否则使用默认值
        if (rejectReason != null && !rejectReason.trim().isEmpty()) {
            wrapper.set(StoreOperationalActivitySignup::getRejectReason, rejectReason.trim());
        } else {
            wrapper.set(StoreOperationalActivitySignup::getRejectReason, "审核未通过");
        }

        int result = signupMapper.update(null, wrapper);

        // 审核拒绝后同步活动人数与状态，并发送通知
        if (result > 0) {
            syncActivitySignupStatus(signup.getActivityId());
            try {
                sendApprovalNotice(id, false);
            } catch (Exception e) {
                log.error("发送审核拒绝通知失败，signupId={}, error={}", id, e.getMessage(), e);
            }
        }

        return result;
    }

    /**
     * 根据有效报名人数同步活动状态：
     * 满员时将未开始/进行中活动置为已售罄(4)；
     * 拒绝后名额释放时将已售罄(4)恢复为未开始(2)/进行中(5)。
     */
    private void syncActivitySignupStatus(Integer activityId) {
        if (activityId == null) {
            return;
        }
        StoreOperationalActivity activity = activityMapper.selectById(activityId);
        if (activity == null) {
            return;
        }

        Integer limitPeople = activity.getActivityLimitPeople();
        if (limitPeople == null || limitPeople <= 0) {
            return;
        }

        Integer signupCount = signupMapper.countSignupByActivityId(activityId);
        int currentCount = signupCount != null ? signupCount : 0;
        Integer currentStatus = activity.getStatus();
        Integer targetStatus = null;

        if (currentCount >= limitPeople) {
            if (currentStatus != null && (currentStatus == 2 || currentStatus == 5)) {
                targetStatus = 4;
            }
        } else if (currentStatus != null && currentStatus == 4) {
            targetStatus = resolveTimelineStatus(activity);
            if (targetStatus != 2 && targetStatus != 5) {
                targetStatus = null;
            }
        }

        if (targetStatus != null && !targetStatus.equals(currentStatus)) {
            LambdaUpdateWrapper<StoreOperationalActivity> activityWrapper = new LambdaUpdateWrapper<>();
            activityWrapper.eq(StoreOperationalActivity::getId, activityId)
                    .set(StoreOperationalActivity::getStatus, targetStatus);
            activityMapper.update(null, activityWrapper);
            log.info("同步活动报名状态，activityId={}, signupCount={}, limitPeople={}, status: {} -> {}",
                    activityId, currentCount, limitPeople, currentStatus, targetStatus);
        }
    }

    /**
     * 按活动时间轴计算未开始/进行中/已结束状态。
     */
    private int resolveTimelineStatus(StoreOperationalActivity activity) {
        Date now = new Date();
        if (activity.getStartTime() == null || activity.getEndTime() == null) {
            return 2;
        }
        if (now.before(activity.getStartTime())) {
            return 2;
        }
        if (!now.after(activity.getEndTime())) {
            return 5;
        }
        return 7;
    }

    /**
     * 获取状态文字
     *
     * @param status 状态值
     * @return 状态文字
     */
    private String getStatusText(Integer status) {
        if (status == null) {
            return "未知";
        }
        switch (status) {
            case 0:
                return "待审核";
            case 1:
                return "拒绝";
            case 2:
                return "通过";
            default:
                return "未知";
        }
    }

    /**
     * 发送审核通知
     *
     * @param signupId 报名ID
     * @param approved 是否通过：true-通过，false-拒绝
     */
    private void sendApprovalNotice(Integer signupId, boolean approved) {
        log.info("OperationalActivitySignupServiceImpl.sendApprovalNotice: signupId={}, approved={}", signupId, approved);

        // 查询报名信息
        StoreOperationalActivitySignup signup = signupMapper.selectById(signupId);
        if (signup == null) {
            log.warn("报名记录不存在，无法发送通知，signupId={}", signupId);
            return;
        }

        // 获取用户信息
        if (signup.getUserId() == null) {
            log.warn("报名记录中用户ID为空，无法发送通知，signupId={}", signupId);
            return;
        }

        LifeUser lifeUser = lifeUserMapper.selectById(signup.getUserId());
        if (lifeUser == null || lifeUser.getUserPhone() == null) {
            log.warn("用户信息不存在或手机号为空，无法发送通知，signupId={}, userId={}", signupId, signup.getUserId());
            return;
        }

        String phone = lifeUser.getUserPhone();
        String receiverId = "user_" + phone;

        // 构建通知内容
        String message;
        if (approved) {
            // 审核通过
            message = "您报名参与的活动已通过商家报名条件，请耐心等待活动开始。";
        } else {
            // 审核拒绝
            message = "您报名参与的活动未通过商家报名条件，如想继续参与请重新报名。";
        }

        // 创建通知对象
        JSONObject contextJson = new JSONObject();
        contextJson.put("signupId", signupId);
        contextJson.put("activityId", signup.getActivityId());
        contextJson.put("status", approved ? "通过" : "拒绝");
        contextJson.put("message", message);

        LifeNotice lifeNotice = new LifeNotice();
        lifeNotice.setSenderId("system");
        lifeNotice.setReceiverId(receiverId);
        lifeNotice.setBusinessId(signupId);
        lifeNotice.setTitle("活动通知");
        lifeNotice.setContext(contextJson.toJSONString());
        lifeNotice.setNoticeType(Constants.Notice.SYSTEM_NOTICE); // 系统通知
        lifeNotice.setIsRead(0);

        // 保存通知到数据库
        lifeNoticeUtil.fillUserTypeAndRefId(lifeNotice);
        lifeNoticeMapper.insert(lifeNotice);

        // 通过WebSocket发送实时通知
        try {
            WebSocketVo webSocketVo = new WebSocketVo();
            webSocketVo.setSenderId("system");
            webSocketVo.setReceiverId(receiverId);
            webSocketVo.setCategory("notice");
            webSocketVo.setNoticeType("1");
            webSocketVo.setIsRead(0);
            webSocketVo.setText(JSONObject.toJSONString(lifeNotice));
            
            alienStoreFeign.sendMsgToClientByPhoneId(receiverId, JSONObject.toJSONString(webSocketVo));
            log.info("活动审核通知发送成功，signupId={}, receiverId={}, approved={}", signupId, receiverId, approved);
        } catch (Exception e) {
            log.error("发送WebSocket通知失败，signupId={}, receiverId={}, error={}", signupId, receiverId, e.getMessage(), e);
        }
    }
}

