package com.hotwj.platform.noticeManagerment.complaintAdvice.service.impl;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hotwj.platform.noticeManagerment.complaintAdvice.domain.HotComplaintAdvice;
import com.hotwj.platform.noticeManagerment.complaintAdvice.domain.bo.HotComplaintAdviceBo;
import com.hotwj.platform.noticeManagerment.complaintAdvice.domain.vo.HotComplaintAdviceVo;
import com.hotwj.platform.noticeManagerment.complaintAdvice.mapper.HotComplaintAdviceMapper;
import com.hotwj.platform.noticeManagerment.complaintAdvice.service.IHotComplaintAdviceService;
import com.hotwj.platform.noticeManagerment.systemNotification.domain.bo.HotSystemNotificationGroupBo;
import com.hotwj.platform.noticeManagerment.systemNotification.service.IHotSystemNotificationService;
import com.hotwj.platform.resourceManagement.companySafetyManager.domain.HotCompanySafetyManager;
import com.hotwj.platform.resourceManagement.companySafetyManager.mapper.HotCompanySafetyManagerMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.springframework.stereotype.Service;

import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 投诉建议Service业务层处理
 *
 * @author shihongwei
 * @date 2026-01-23
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class HotComplaintAdviceServiceImpl implements IHotComplaintAdviceService {

    private final HotComplaintAdviceMapper baseMapper;
    private final HotCompanySafetyManagerMapper managerMapper;
    private final IHotSystemNotificationService notificationService;
    /**
     * 查询投诉建议
     *
     * @param id 主键
     * @return 投诉建议
     */
    @Override
    public HotComplaintAdviceVo queryById(Long id) {
        return baseMapper.selectVoById(id);
    }

    /**
     * 分页查询投诉建议列表
     *
     * @param bo        查询条件
     * @param pageQuery 分页参数
     * @return 投诉建议分页列表
     */
    @Override
    public TableDataInfo<HotComplaintAdviceVo> queryPageList(HotComplaintAdviceBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<HotComplaintAdvice> lqw = buildQueryWrapper(bo);
        Page<HotComplaintAdviceVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询符合条件的投诉建议列表
     *
     * @param bo 查询条件
     * @return 投诉建议列表
     */
    @Override
    public List<HotComplaintAdviceVo> queryList(HotComplaintAdviceBo bo) {
        LambdaQueryWrapper<HotComplaintAdvice> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<HotComplaintAdvice> buildQueryWrapper(HotComplaintAdviceBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<HotComplaintAdvice> lqw = Wrappers.lambdaQuery();
        lqw.orderByDesc(HotComplaintAdvice::getCreateTime, HotComplaintAdvice::getId);
        String beginTime = params == null ? null : String.valueOf(params.get("beginTime"));
        String endTime = params == null ? null : String.valueOf(params.get("endTime"));
        Date beginDate = StringUtils.isNotBlank(beginTime) && !"null".equalsIgnoreCase(beginTime)
                ? DateUtil.beginOfDay(DateUtil.parse(beginTime))
                : null;
        Date endDate = StringUtils.isNotBlank(endTime) && !"null".equalsIgnoreCase(endTime)
                ? DateUtil.endOfDay(DateUtil.parse(endTime))
                : null;
        lqw.ge(beginDate != null, HotComplaintAdvice::getCreateTime, beginDate);
        lqw.le(endDate != null, HotComplaintAdvice::getCreateTime, endDate);
        lqw.eq(bo.getId() != null, HotComplaintAdvice::getId, bo.getId());
        lqw.eq(StringUtils.isNotBlank(bo.getQuestion()), HotComplaintAdvice::getQuestion, bo.getQuestion());
        lqw.eq(bo.getCompanyId() != null, HotComplaintAdvice::getCompanyId, bo.getCompanyId());
        lqw.like(StringUtils.isNotBlank(bo.getCompanyName()), HotComplaintAdvice::getCompanyName, bo.getCompanyName());
        lqw.eq(StringUtils.isNotBlank(bo.getComplainantId()), HotComplaintAdvice::getComplainantId, bo.getComplainantId());
        lqw.like(StringUtils.isNotBlank(bo.getComplainantName()), HotComplaintAdvice::getComplainantName, bo.getComplainantName());
        lqw.eq(StringUtils.isNotBlank(bo.getContactPhone()), HotComplaintAdvice::getContactPhone, bo.getContactPhone());
        lqw.eq(StringUtils.isNotBlank(bo.getStaffType()), HotComplaintAdvice::getStaffType, bo.getStaffType());
        lqw.eq(StringUtils.isNotBlank(bo.getComplainContent()), HotComplaintAdvice::getComplainContent, bo.getComplainContent());
        lqw.eq(bo.getIsReplied() != null, HotComplaintAdvice::getIsReplied, bo.getIsReplied());
        lqw.eq(StringUtils.isNotBlank(bo.getReplyContent()), HotComplaintAdvice::getReplyContent, bo.getReplyContent());
        lqw.eq(bo.getReplyTime() != null, HotComplaintAdvice::getReplyTime, bo.getReplyTime());
        lqw.eq(bo.getCreateTime() != null, HotComplaintAdvice::getCreateTime, bo.getCreateTime());
        lqw.eq(bo.getIsDeleted() != null, HotComplaintAdvice::getIsDeleted, bo.getIsDeleted());
        return lqw;
    }

    /**
     * 新增投诉建议
     *
     * @param bo 投诉建议
     * @return 是否新增成功
     */
    @Override
    public Boolean insertByBo(HotComplaintAdviceBo bo) {
        HotComplaintAdvice add = MapstructUtils.convert(bo, HotComplaintAdvice.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
            if (add.getCompanyId() != null) {
                List<HotCompanySafetyManager> managers = managerMapper.selectList(
                        com.baomidou.mybatisplus.core.toolkit.Wrappers.<HotCompanySafetyManager>lambdaQuery()
                                .eq(HotCompanySafetyManager::getCompanyId, add.getCompanyId())
                                .eq(HotCompanySafetyManager::getIsDeleted, 0L)
                                .eq(HotCompanySafetyManager::getIsResigned, 0L)
                                .eq(HotCompanySafetyManager::getStatus, 1L)
                );
                if (managers != null && !managers.isEmpty()) {
                    List<String> receiverIds = managers.stream().map(m -> String.valueOf(m.getId())).toList();
                    String title = StringUtils.blankToDefault(add.getQuestion(), "投诉建议");
                    String content = "收到新的投诉/建议：【" + title + "】，请及时处理。";
                    HotSystemNotificationGroupBo bos = new HotSystemNotificationGroupBo();
                    bos.setLevel("普通");
                    bos.setContent(content);
                    bos.setSourceType("投诉建议");
                    bos.setSenderType("SYSTEM");
                    bos.setReceiverType("管理员");
                    bos.setReceiverIds(receiverIds);
                    bos.setIsDeleted(0L);
                    try {
                        notificationService.insertByBo(bos);
                    } catch (Exception e) {
                        log.warn("发送投诉建议新增通知失败 companyId={} adviceId={}", add.getCompanyId(), add.getId(), e);
                    }
                }
            }
        }
        return flag;
    }

    /**
     * 修改投诉建议
     *
     * @param bo 投诉建议
     * @return 是否修改成功
     */
    @Override
    public Boolean updateByBo(HotComplaintAdviceBo bo) {
        HotComplaintAdvice old = null;
        if (bo.getId() != null) {
            old = baseMapper.selectById(bo.getId());
        }
        HotComplaintAdvice update = MapstructUtils.convert(bo, HotComplaintAdvice.class);
        validEntityBeforeSave(update);
        boolean updated = baseMapper.updateById(update) > 0;
        if (updated) {
            sendReplyNotificationIfNeeded(old, bo);
        }
        return updated;
    }

    private void sendReplyNotificationIfNeeded(HotComplaintAdvice old, HotComplaintAdviceBo bo) {
        if (bo == null || bo.getId() == null) {
            return;
        }
        Long newIsReplied = bo.getIsReplied();
        Long oldIsReplied = old == null ? null : old.getIsReplied();
        if (!Long.valueOf(1L).equals(newIsReplied) || Long.valueOf(1L).equals(oldIsReplied)) {
            return;
        }

        String receiverId = StringUtils.isNotBlank(bo.getComplainantId())
                ? bo.getComplainantId()
                : (old == null ? null : old.getComplainantId());
        if (StringUtils.isBlank(receiverId)) {
            log.warn("投诉建议回复通知发送失败，缺少投诉人ID complaintId={}", bo.getId());
            return;
        }

        String staffType = StringUtils.isNotBlank(bo.getStaffType())
                ? bo.getStaffType()
                : (old == null ? null : old.getStaffType());
        String receiverType = "0".equals(staffType) ? "管理员" : "驾驶员";

        String question = StringUtils.isNotBlank(bo.getQuestion())
                ? bo.getQuestion()
                : (old == null ? null : old.getQuestion());
        String title = StringUtils.blankToDefault(question, "投诉建议");
        String content = "您提交的投诉建议【" + title + "】已收到回复，请前往“投诉建议”查看。";

        HotSystemNotificationGroupBo notifyBo = new HotSystemNotificationGroupBo();
        notifyBo.setLevel("普通");
        notifyBo.setContent(content);
        notifyBo.setSourceType("投诉建议");
        notifyBo.setSenderType("SYSTEM");
        notifyBo.setReceiverType(receiverType);
        notifyBo.setReceiverId(receiverId);
        notifyBo.setIsDeleted(0L);
        try {
            notificationService.insertByBo(notifyBo);
        } catch (Exception e) {
            log.warn("投诉建议回复通知发送异常 complaintId={} receiverType={} receiverId={}",
                    bo.getId(), receiverType, receiverId, e);
        }
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(HotComplaintAdvice entity) {
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 校验并批量删除投诉建议信息
     *
     * @param ids     待删除的主键集合
     * @param isValid 是否进行有效性校验
     * @return 是否删除成功
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteByIds(ids) > 0;
    }
}
