package shop.alien.store.service.impl;

import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
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 org.springframework.util.CollectionUtils;
import shop.alien.entity.result.R;
import shop.alien.entity.store.*;
import shop.alien.entity.store.dto.*;
import shop.alien.entity.store.vo.*;
import shop.alien.mapper.*;
import shop.alien.store.config.WebSocketProcess;
import shop.alien.store.service.LifeFeedbackReplyService;
import shop.alien.store.service.LifeFeedbackService;
import shop.alien.store.service.LifeImgService;
import shop.alien.store.util.ai.AiFeedbackAssignUtils;
import shop.alien.util.type.LifeNoticeUtil;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 意见反馈 Service实现类
 */
@Slf4j
@Service
@RequiredArgsConstructor
@Transactional(rollbackFor = Exception.class)
public class LifeFeedbackServiceImpl extends ServiceImpl<LifeFeedbackMapper, LifeFeedback> implements LifeFeedbackService {

    private final LifeFeedbackMapper lifeFeedbackMapper;
    private final LifeImgService lifeImgService;
    private final LifeLogMapper lifeLogMapper;
    private final LifeFeedbackReplyService lifeFeedbackReplyService;
    private final LifeNoticeMapper lifeNoticeMapper;

    private final LifeNoticeUtil lifeNoticeUtil;
    private final StoreUserMapper storeUserMapper;
    private final WebSocketProcess webSocketProcess;
    private final AiFeedbackAssignUtils aiFeedbackAssignUtils;
    private final LifeSysMapper lifeSysMapper;
    private final LifeUserMapper lifeUserMapper;

    @Override
    public R<String> submitFeedback(LifeFeedbackDto dto) {
        try {
            // 1. 参数校验
            if (dto.getUserId() == null) {
                return R.fail("用户ID不能为空");
            }
            if (dto.getFeedbackSource() == null) {
                return R.fail("反馈来源不能为空");
            }
            if (dto.getFeedbackType() == null) {
                return R.fail("反馈类型不能为空");
            }
            if (dto.getContent() == null || dto.getContent().trim().isEmpty()) {
                return R.fail("反馈内容不能为空");
            }

            // 2. 创建反馈记录(使用MyBatis Plus的save方法)
            LifeFeedback feedback = new LifeFeedback();
            BeanUtils.copyProperties(dto, feedback);
            // 如果feedbackWay为空，默认为用户主动反馈(0)
            if (feedback.getFeedbackWay() == null) {
                feedback.setFeedbackWay(0);
            }
            feedback.setFeedbackTime(new Date());
            feedback.setHandleStatus(0); // 处理中
            feedback.setCreateTime(new Date());

            boolean saveResult = this.save(feedback);
            if (!saveResult) {
                return R.fail("提交反馈失败");
            }

            // 3. 保存附件（图片和视频）
            List<LifeImg> fileList = new ArrayList<>();
            // 收集所有视频的截图URL，避免重复保存为普通图片
            List<String> videoThumbnailUrls = new ArrayList<>();

            if (!CollectionUtils.isEmpty(dto.getFileUrlList())) {
                // 先处理视频，找到所有视频及其封面图
                List<String> videoUrls = new ArrayList<>();
                List<String> imageUrls = new ArrayList<>();

                // 分类：区分视频和图片
                for (String fileUrl : dto.getFileUrlList()) {
                    if (isVideoUrl(fileUrl)) {
                        videoUrls.add(fileUrl);
                    } else if (isImageUrl(fileUrl)) {
                        imageUrls.add(fileUrl);
                    }
                }

                // 处理视频：自动匹配封面图
                for (String videoUrl : videoUrls) {
                    LifeImg video = new LifeImg();
                    video.setFeedbackId(feedback.getId());
                    video.setImgUrl(videoUrl);
                    video.setFileType(2); // 2-视频
                    video.setUploadTime(new Date());

                    // 从fileUrlList中查找对应的封面图URL（通过文件名匹配）
                    // 视频URL格式: .../video/xxx123456.mp4
                    // 封面图URL格式: .../video/xxx123456.jpg 或 .../image/xxx123456.jpg
                    String videoFileName = videoUrl.substring(videoUrl.lastIndexOf('/') + 1);
                    String videoNameWithoutExt = videoFileName.substring(0, videoFileName.lastIndexOf('.'));

                    // 在图片列表中查找匹配的封面图
                    for (String imgUrl : imageUrls) {
                        String imgFileName = imgUrl.substring(imgUrl.lastIndexOf('/') + 1);
                        if (imgFileName.contains(".")) {
                            String imgNameWithoutExt = imgFileName.substring(0, imgFileName.lastIndexOf('.'));
                            // 如果文件名（不含扩展名）相同，且是图片格式，则认为是该视频的封面图
                            if (videoNameWithoutExt.equals(imgNameWithoutExt) && isImageUrl(imgUrl)) {
                                video.setThumbnailUrl(imgUrl);
                                videoThumbnailUrls.add(imgUrl); // 记录已使用的封面图URL
                                break;
                            }
                        }
                    }

                    fileList.add(video);
                }

                // 处理图片（排除已作为视频封面的URL）
                for (String imgUrl : imageUrls) {
                    // 如果该URL已被用作视频封面，则跳过，不重复保存
                    if (!videoThumbnailUrls.contains(imgUrl)) {
                        LifeImg img = new LifeImg();
                        img.setFeedbackId(feedback.getId());
                        img.setImgUrl(imgUrl);
                        img.setFileType(1); // 1-图片
                        img.setUploadTime(new Date());
                        fileList.add(img);
                    }
                }
            }

            if (!fileList.isEmpty()) {
                lifeImgService.batchSave(fileList);
            }

            // 4. 记录日志（只记录详细内容）
            saveLog(feedback.getId(), feedback.getContent(), "0");

            // 5. 调用AI分配跟踪人员
            // 根据AI接口文档：用户端和商户端反馈都需要分配跟踪人员
            // AI返回的 staff_id 对应 life_sys 表的 id
            Integer assignedStaffId = assignStaffByAI(feedback);
            if (assignedStaffId != null) {
                // 更新反馈记录的跟踪人员（虽然AI接口会自动更新，但本地也需要同步更新）
                feedback.setStaffId(assignedStaffId);
                this.updateById(feedback);

                // 记录分配跟踪人员日志
                saveLog(feedback.getId(), "已分配跟踪人员，ID: " + assignedStaffId + " (life_sys)", "1");

                // 发送分配跟踪人员通知给中台（平台端跟踪人员）
                sendStaffAssignmentNotice(feedback, assignedStaffId);
            }

            // 6. 发送提交反馈工单通知到中台（需要已分配跟踪人员）
            if (feedback.getStaffId() != null) {
                sendFeedbackSubmittedNoticeToPlatform(feedback);
            }

            return R.success("提交成功");
        } catch (Exception e) {
            log.error("提交反馈失败", e);
            return R.fail("提交反馈失败:" + e.getMessage());
        }
    }

    @Override
    public IPage<LifeFeedbackVo> getFeedbackList(Integer userId, Integer feedbackSource, int page, int size) {
        try {
            // 使用自定义SQL查询(已包含工作人员名称)
            // 查询用户反馈(feedbackWay=0)和AI识别(feedbackWay=1)的记录
            Page<LifeFeedbackVo> pageParam = new Page<>(page, size);
            IPage<LifeFeedbackVo> voPage = lifeFeedbackMapper.selectFeedbackListWithStaff(
                    pageParam, userId, feedbackSource, null, null
            );

            // 为每条记录查询附件（图片和视频）并设置反馈类型名称
            voPage.getRecords().forEach(vo -> {
                List<String> imgUrls = lifeImgService.getImgUrlsByFeedbackId(vo.getId());
                vo.setImgUrlList(imgUrls);
                List<String> videoUrls = lifeImgService.getVideoUrlsByFeedbackId(vo.getId());
                vo.setVideoUrlList(videoUrls);
                // 设置反馈类型名称
                vo.setFeedbackTypeName(getFeedbackTypeName(vo.getFeedbackType()));
            });

            return voPage;
        } catch (Exception e) {
            log.error("查询反馈列表失败", e);
            return new Page<>(page, size);
        }
    }

    @Override
    public R<LifeFeedbackVo> getFeedbackDetail(Integer feedbackId) {
        try {
            // 1. 使用自定义SQL查询反馈详情(已包含工作人员名称)
            LifeFeedbackVo vo = lifeFeedbackMapper.selectFeedbackDetail(feedbackId);
            if (vo == null) {
                return R.fail("反馈记录不存在");
            }

            // 2. 查询附件（图片和视频）
            // 查询所有附件，然后过滤出原始反馈的附件（排除回复附件）
            List<LifeImg> allImgs = lifeImgService.getByFeedbackId(feedbackId);
            List<String> imgUrls = new ArrayList<>();
            List<String> videoUrls = new ArrayList<>();
            Date feedbackTime = vo.getFeedbackTime();
            if (feedbackTime != null) {
                long feedbackTimeMs = feedbackTime.getTime();
                for (LifeImg img : allImgs) {
                    if (img.getUploadTime() != null) {
                        long imgTimeMs = img.getUploadTime().getTime();
                        // 判断附件是否属于原始反馈（时间差在5分钟内，且早于最早的回复）
                        // 简化处理：如果是反馈后5分钟内的附件，认为是原始反馈的附件
                        List<LifeFeedbackReply> replyList = lifeFeedbackReplyService.getByFeedbackId(feedbackId);
                        boolean isOriginalFeedback = true;
                        if (!replyList.isEmpty()) {
                            Date firstReplyTime = replyList.get(0).getCreateTime();
                            // 如果附件时间在最早回复时间之后，则不属于原始反馈
                            if (img.getUploadTime().after(firstReplyTime)) {
                                isOriginalFeedback = false;
                            } else {
                                long timeDiff = Math.abs(imgTimeMs - feedbackTimeMs);
                                if (timeDiff > 5 * 60 * 1000) { // 超过5分钟
                                    isOriginalFeedback = false;
                                }
                            }
                        } else {
                            long timeDiff = Math.abs(imgTimeMs - feedbackTimeMs);
                            if (timeDiff > 5 * 60 * 1000) { // 超过5分钟
                                isOriginalFeedback = false;
                            }
                        }

                        if (isOriginalFeedback) {
                            if (img.getFileType() == 1) {
                                imgUrls.add(img.getImgUrl());
                            } else if (img.getFileType() == 2) {
                                videoUrls.add(img.getImgUrl());
                            }
                        }
                    }
                }
            } else {
                // 如果没有反馈时间，使用简单方式：只查询图片和视频
                for (LifeImg img : allImgs) {
                    if (img.getFileType() == 1) {
                        imgUrls.add(img.getImgUrl());
                    } else if (img.getFileType() == 2) {
                        videoUrls.add(img.getImgUrl());
                    }
                }
            }
            vo.setImgUrlList(imgUrls);
            vo.setVideoUrlList(videoUrls);
            // 设置反馈类型名称
            vo.setFeedbackTypeName(getFeedbackTypeName(vo.getFeedbackType()));

            // 3. 查询回复列表（从life_feedback_reply表）
            List<LifeFeedbackReply> replyList = lifeFeedbackReplyService.getByFeedbackId(feedbackId);
            // 转换为VO格式（使用之前查询的allImgs）
            List<LifeFeedbackVo> replyVoList = new ArrayList<>();
            for (LifeFeedbackReply reply : replyList) {
                LifeFeedbackVo replyVo = new LifeFeedbackVo();
                replyVo.setId(reply.getId());
                replyVo.setContent(reply.getReplyContent());
                replyVo.setFeedbackTime(reply.getCreateTime());
                // reply_type: 0-平台回复, 1-我的回复
                replyVo.setStaffId(reply.getReplyType() == 0 ? 1 : null); // 平台回复有staffId，用户回复为null
                // 查询回复的附件（通过时间判断：上传时间在回复创建时间前后5分钟内）
                List<String> replyImgUrls = new ArrayList<>();
                List<String> replyVideoUrls = new ArrayList<>();
                Date replyTime = reply.getCreateTime();
                long replyTimeMs = replyTime.getTime();
                for (LifeImg img : allImgs) {
                    if (img.getUploadTime() != null) {
                        long imgTimeMs = img.getUploadTime().getTime();
                        // 判断附件是否属于该回复（时间差在5分钟内）
                        long timeDiff = Math.abs(imgTimeMs - replyTimeMs);
                        if (timeDiff <= 5 * 60 * 1000) { // 5分钟
                            if (img.getFileType() == 1) {
                                replyImgUrls.add(img.getImgUrl());
                            } else if (img.getFileType() == 2) {
                                replyVideoUrls.add(img.getImgUrl());
                            }
                        }
                    }
                }
                replyVo.setImgUrlList(replyImgUrls);
                replyVo.setVideoUrlList(replyVideoUrls);
                replyVoList.add(replyVo);
            }

            // 4. 按时间升序排序回复
            replyVoList.sort((a, b) -> a.getFeedbackTime().compareTo(b.getFeedbackTime()));
            vo.setPlatformReplies(replyVoList);

            return R.data(vo);
        } catch (Exception e) {
            log.error("查询反馈详情失败", e);
            return R.fail("查询反馈详情失败:" + e.getMessage());
        }
    }

    @Override
    public R<String> userReply(UserReplyDto dto) {
        try {
            // 1. 参数校验
            if (dto.getUserId() == null) {
                return R.fail("用户ID不能为空");
            }
            if (dto.getFeedbackSource() == null) {
                return R.fail("反馈来源不能为空");
            }
            if (dto.getFeedbackId() == null) {
                return R.fail("反馈ID不能为空");
            }
            if (dto.getContent() == null || dto.getContent().trim().isEmpty()) {
                return R.fail("回复内容不能为空");
            }

            // 2. 查询原始反馈（用于验证反馈是否存在）
            LifeFeedback originalFeedback = lifeFeedbackMapper.selectById(dto.getFeedbackId());
            if (originalFeedback == null) {
                return R.fail("反馈记录不存在");
            }

            // 3. 创建用户回复记录（保存到life_feedback_reply表）
            LifeFeedbackReply userReply = new LifeFeedbackReply();
            userReply.setFeedbackId(dto.getFeedbackId());
            userReply.setReplyType(1); // 1-我的回复（用户回复）
            userReply.setReplyContent(dto.getContent());
            userReply.setCreateTime(new Date());
            userReply.setUpdateTime(new Date());

            boolean saveResult = lifeFeedbackReplyService.save(userReply);
            if (!saveResult) {
                return R.fail("回复失败");
            }

            // 4. 记录日志（只记录内容）
            saveLog(dto.getFeedbackId(), dto.getContent(), "2");

            // 5. 发送用户回复通知给平台端（跟踪人员）
            sendUserReplyNoticeToPlatform(originalFeedback, dto.getContent());

            return R.success("回复成功");
        } catch (Exception e) {
            log.error("用户回复失败", e);
            return R.fail("用户回复失败:" + e.getMessage());
        }
    }

    /**
     * 保存操作日志
     * @param feedbackId 反馈ID
     * @param context 日志内容
     * @param type 操作类型：0-创建反馈工单,1-分配跟踪人员,2-回复用户,3-问题解决状态
     */
    private void saveLog(Integer feedbackId, String context, String type) {
        try {
            LifeLog lifeLog = new LifeLog();
            lifeLog.setFeedbackId(feedbackId);
            lifeLog.setContext(context);
            lifeLog.setType(type);
            lifeLog.setCreatedTime(new Date());
            lifeLogMapper.insert(lifeLog);
        } catch (Exception e) {
            log.error("保存日志失败", e);
        }
    }

    /**
     * 获取反馈类型名称
     * @param feedbackType 反馈类型:0-bug反馈,1-优化反馈,2-新增功能反馈
     * @return 反馈类型名称
     */
    private String getFeedbackTypeName(Integer feedbackType) {
        if (feedbackType == null) {
            return "";
        }
        switch (feedbackType) {
            case 0:
                return "bug反馈";
            case 1:
                return "优化反馈";
            case 2:
                return "功能反馈";
            default:
                return "";
        }
    }

    /**
     * 判断URL是否为视频
     * @param url 文件URL
     * @return true-视频，false-非视频
     */
    private boolean isVideoUrl(String url) {
        if (url == null || url.isEmpty()) {
            return false;
        }
        String lowerUrl = url.toLowerCase();
        return lowerUrl.endsWith(".mp4") ||
               lowerUrl.endsWith(".avi") ||
               lowerUrl.endsWith(".flv") ||
               lowerUrl.endsWith(".mkv") ||
               lowerUrl.endsWith(".rmvb") ||
               lowerUrl.endsWith(".wmv") ||
               lowerUrl.endsWith(".3gp") ||
               lowerUrl.endsWith(".mov");
    }

    /**
     * 判断URL是否为图片
     * @param url 文件URL
     * @return true-图片，false-非图片
     */
    private boolean isImageUrl(String url) {
        if (url == null || url.isEmpty()) {
            return false;
        }
        String lowerUrl = url.toLowerCase();
        return lowerUrl.endsWith(".jpg") ||
               lowerUrl.endsWith(".jpeg") ||
               lowerUrl.endsWith(".png") ||
               lowerUrl.endsWith(".bmp") ||
               lowerUrl.endsWith(".webp") ||
               lowerUrl.endsWith(".gif") ||
               lowerUrl.endsWith(".svg") ||
               lowerUrl.endsWith("");
    }


    // ==================== 中台接口实现 ====================

    @Override
    public R<IPage<LifeFeedbackListVo>> getWebFeedbackList(LifeFeedbackQueryDto queryDto) {
        try {
            // 这里避免 MyBatis-Plus 分页与 PageHelper 同时对同一查询做 COUNT/LIMIT 转换导致参数映射异常
            PageHelper.startPage(queryDto.getPageNum(), queryDto.getPageSize());
            List<LifeFeedbackListVo> list = lifeFeedbackMapper.selectWebFeedbackList(
                    queryDto.getFeedbackType(),
                    queryDto.getHandleStatus(),
                    queryDto.getFeedbackSource(),
                    queryDto.getFeedbackWay()
            );
            PageInfo<LifeFeedbackListVo> pageInfo = new PageInfo<>(list);

            Page<LifeFeedbackListVo> result = new Page<>(queryDto.getPageNum(), queryDto.getPageSize());
            result.setTotal(pageInfo.getTotal());
            result.setRecords(list);
            return R.data(result);
        } catch (Exception e) {
            log.error("中台-查询意见反馈列表失败", e);
            return R.fail("查询失败:" + e.getMessage());
        }
    }

    @Override
    public R<LifeFeedbackDetailVo> getWebFeedbackDetail(Integer feedbackId) {
        try {
            if (feedbackId == null) {
                return R.fail("反馈ID不能为空");
            }

            // 1. 查询反馈详情
            LifeFeedbackDetailVo detail = lifeFeedbackMapper.selectWebFeedbackDetail(feedbackId);
            if (detail == null) {
                return R.fail("反馈记录不存在");
            }

            // 2. 查询附件列表（图片/视频）
            List<FeedbackAttachmentVo> attachments = new ArrayList<>();
            List<LifeImg> imgList = lifeImgService.getByFeedbackId(feedbackId);
            if (!CollectionUtils.isEmpty(imgList)) {
                for (LifeImg img : imgList) {
                    FeedbackAttachmentVo attachment = new FeedbackAttachmentVo();
                    attachment.setId(img.getId());
                    attachment.setFileType(img.getFileType() != null ? img.getFileType() : 1);
                    attachment.setFileUrl(img.getImgUrl());
                    attachment.setThumbnailUrl(img.getThumbnailUrl());
                    attachments.add(attachment);
                }
            }
            detail.setAttachments(attachments);

            // 3. 查询回复列表（平台回复和用户回复）
            List<LifeFeedbackReply> replyList = lifeFeedbackReplyService.getByFeedbackId(feedbackId);
            List<FeedbackReplyVo> replyVoList = new ArrayList<>();
            for (LifeFeedbackReply reply : replyList) {
                FeedbackReplyVo replyVo = new FeedbackReplyVo();
                replyVo.setId(reply.getId());
                replyVo.setFeedbackId(reply.getFeedbackId());
                replyVo.setReplyType(reply.getReplyType());
                replyVo.setReplyTypeName(reply.getReplyType() == 0 ? "平台回复" : "用户回复");
                replyVo.setReplyContent(reply.getReplyContent());
                replyVo.setCreateTime(reply.getCreateTime());

                // 查询回复的附件（通过时间判断：上传时间在回复创建时间前后5分钟内）
                List<String> replyImgUrls = new ArrayList<>();
                List<String> replyVideoUrls = new ArrayList<>();
                Date replyTime = reply.getCreateTime();
                if (replyTime != null && !CollectionUtils.isEmpty(imgList)) {
                    long replyTimeMs = replyTime.getTime();
                    for (LifeImg img : imgList) {
                        if (img.getUploadTime() != null) {
                            long imgTimeMs = img.getUploadTime().getTime();
                            // 判断附件是否属于该回复（时间差在5分钟内）
                            long timeDiff = Math.abs(imgTimeMs - replyTimeMs);
                            if (timeDiff <= 5 * 60 * 1000) { // 5分钟
                                if (img.getFileType() == 1) {
                                    replyImgUrls.add(img.getImgUrl());
                                } else if (img.getFileType() == 2) {
                                    replyVideoUrls.add(img.getImgUrl());
                                }
                            }
                        }
                    }
                }
                replyVo.setImgUrlList(replyImgUrls);
                replyVo.setVideoUrlList(replyVideoUrls);
                replyVoList.add(replyVo);
            }

            // 按时间升序排序回复
            replyVoList.sort((a, b) -> a.getCreateTime().compareTo(b.getCreateTime()));
            detail.setReplies(replyVoList);

            return R.data(detail);
        } catch (Exception e) {
            log.error("中台-查询反馈详情失败", e);
            return R.fail("查询失败:" + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R<String> webReplyUser(LifeFeedbackReplyWebDto replyDto) {
        try {
            // 1. 参数校验
            if (replyDto.getFeedbackId() == null) {
                return R.fail("反馈ID不能为空");
            }
            if (replyDto.getContent() == null || replyDto.getContent().trim().isEmpty()) {
                return R.fail("回复内容不能为空");
            }

            // 2. 查询原始反馈
            LifeFeedback feedback = lifeFeedbackMapper.selectById(replyDto.getFeedbackId());
            if (feedback == null) {
                return R.fail("反馈记录不存在");
            }

            // 3. 保存平台回复到life_feedback_reply表
            LifeFeedbackReply platformReply = new LifeFeedbackReply();
            platformReply.setFeedbackId(replyDto.getFeedbackId());
            platformReply.setReplyType(0); // 0-平台回复
            platformReply.setReplyContent(replyDto.getContent());
            platformReply.setCreateTime(new Date());
            platformReply.setUpdateTime(new Date());

            boolean saveResult = lifeFeedbackReplyService.save(platformReply);
            if (!saveResult) {
                return R.fail("保存回复失败");
            }

            // 4. 记录回复日志（类型3-回复用户）
            String logContent = replyDto.getContent();
            if (replyDto.getUserReply() != null && !replyDto.getUserReply().trim().isEmpty()) {
                logContent = replyDto.getContent() + "||用户回复:" + replyDto.getUserReply();
            }
            saveFeedbackLog(replyDto.getFeedbackId(), 3, logContent);

            // 5. 发送通知给用户
            sendFeedbackReplyNotice(feedback, replyDto.getContent());

            return R.success("回复成功");
        } catch (Exception e) {
            log.error("中台-回复用户失败", e);
            return R.fail("回复失败:" + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R<String> updateWebFeedbackStatus(LifeFeedbackStatusDto statusDto) {
        try {
            // 1. 参数校验
            if (statusDto.getFeedbackId() == null) {
                return R.fail("反馈ID不能为空");
            }

            // 2. 查询原始反馈记录（用于发送通知）
            LifeFeedback feedback = lifeFeedbackMapper.selectById(statusDto.getFeedbackId());
            if (feedback == null) {
                return R.fail("反馈记录不存在");
            }

            // 3. 更新状态
            LifeFeedback updateFeedback = new LifeFeedback();
            updateFeedback.setId(statusDto.getFeedbackId());
            // 如果DTO中有状态值，使用DTO的值；否则默认为已解决(1)
            Integer handleStatus = statusDto.getHandleStatus() != null ? statusDto.getHandleStatus() : 1;
            updateFeedback.setHandleStatus(handleStatus);
            updateFeedback.setUpdateTime(new Date());

            boolean result = this.updateById(updateFeedback);
            if (!result) {
                return R.fail("更新失败");
            }

            // 3. 记录日志（类型0-问题解决状态）
            String logContent = "问题已解决";
            saveFeedbackLog(statusDto.getFeedbackId(), 0, logContent);

            // 5. 如果状态为已解决，发送问题已解决通知给用户
            if (handleStatus == 1) {
                sendFeedbackResolvedNotice(feedback);
            }

            return R.success("更新成功");
        } catch (Exception e) {
            log.error("中台-更新反馈状态失败", e);
            return R.fail("更新失败:" + e.getMessage());
        }
    }

    /**
     * 保存反馈操作日志
     * @param feedbackId 反馈ID
     * @param type 操作类型：0-问题解决状态,1-分配跟踪人员,2-创建反馈工单,3-回复用户
     * @param context 日志内容
     */
    private void saveFeedbackLog(Integer feedbackId, Integer type, String context) {
        try {
            LifeLog lifeLog = new LifeLog();
            lifeLog.setFeedbackId(feedbackId);
            lifeLog.setType(String.valueOf(type));
            lifeLog.setContext(context);
            lifeLog.setCreatedTime(new Date());
            lifeLog.setDeleteFlag(0);
            lifeLogMapper.insert(lifeLog);
        } catch (Exception e) {
            log.error("保存反馈日志失败", e);
        }
    }

    /**
     * 发送平台回复通知给用户
     * @param feedback 反馈记录
     * @param replyContent 回复内容
     */
    private void sendFeedbackReplyNotice(LifeFeedback feedback, String replyContent) {
        try {
            String receiverId = null;
            String userPhone = null;
            
            // 根据反馈来源判断是用户端还是商家端
            if (feedback.getFeedbackSource() == null) {
                log.warn("反馈来源为空，无法发送通知，feedbackId={}", feedback.getId());
                return;
            }
            
            if (feedback.getUserId() == null) {
                log.warn("用户ID为空，无法发送通知，feedbackId={}", feedback.getId());
                return;
            }
            
            // 根据feedbackSource查询对应的用户表
            if (feedback.getFeedbackSource() == 0) {
                // 用户端 - 查询life_user表
                LifeUser lifeUser = lifeUserMapper.selectById(feedback.getUserId());
                if (lifeUser == null || lifeUser.getUserPhone() == null || lifeUser.getUserPhone().trim().isEmpty()) {
                    log.warn("未找到用户信息或手机号为空，无法发送通知，userId={}", feedback.getUserId());
                    return;
                }
                userPhone = lifeUser.getUserPhone();
                receiverId = "user_" + userPhone;
            } else if (feedback.getFeedbackSource() == 1) {
                // 商家端 - 查询store_user表
                StoreUser storeUser = storeUserMapper.selectById(feedback.getUserId());
                if (storeUser == null || storeUser.getPhone() == null || storeUser.getPhone().trim().isEmpty()) {
                    log.warn("未找到商户用户信息或手机号为空，无法发送通知，userId={}", feedback.getUserId());
                    return;
                }
                userPhone = storeUser.getPhone();
                receiverId = "store_" + userPhone;
            } else {
                log.warn("未知的反馈来源，feedbackSource={}, feedbackId={}", feedback.getFeedbackSource(), feedback.getId());
                return;
            }
            
            // 构建通知消息
            JSONObject messageJson = new JSONObject();
            messageJson.put("feedbackId", feedback.getId()); // 添加反馈ID用于区分
            messageJson.put("message", "平台已回复您的意见反馈：" + replyContent);

            // 创建通知记录
            LifeNotice lifeNotice = new LifeNotice();
            lifeNotice.setReceiverId(receiverId);
            lifeNotice.setContext(messageJson.toJSONString());
            lifeNotice.setTitle("意见反馈回复通知");
            lifeNotice.setSenderId("system");
            lifeNotice.setIsRead(0);
            lifeNotice.setNoticeType(1); // 1-系统通知
            lifeNotice.setBusinessId(feedback.getId());

            // 保存通知
            lifeNoticeUtil.fillUserTypeAndRefId(lifeNotice);
            lifeNoticeMapper.insert(lifeNotice);

            // 通过WebSocket发送实时通知
            WebSocketVo webSocketVo = new WebSocketVo();
            webSocketVo.setSenderId("system");
            webSocketVo.setReceiverId(receiverId);
            webSocketVo.setCategory("notice");
            webSocketVo.setNoticeType("1");
            webSocketVo.setIsRead(0);
            webSocketVo.setText(JSONObject.toJSONString(lifeNotice));

            try {
                webSocketProcess.sendMessage(receiverId, JSONObject.toJSONString(webSocketVo));
                log.info("平台回复通知发送成功，feedbackId={}, receiverId={}", feedback.getId(), receiverId);
            } catch (Exception e) {
                log.error("发送WebSocket通知失败，feedbackId={}, receiverId={}, error={}",
                        feedback.getId(), receiverId, e.getMessage());
            }

        } catch (Exception e) {
            log.error("发送平台回复通知异常，feedbackId={}, error={}", feedback.getId(), e.getMessage(), e);
        }
    }

    /**
     * 发送问题已解决通知给用户
     * @param feedback 反馈记录
     */
    private void sendFeedbackResolvedNotice(LifeFeedback feedback) {
        try {
            String receiverId = null;
            
            // 根据反馈来源判断是用户端还是商家端
            if (feedback.getFeedbackSource() == null) {
                log.warn("反馈来源为空，无法发送通知，feedbackId={}", feedback.getId());
                return;
            }
            
            if (feedback.getUserId() == null) {
                log.warn("用户ID为空，无法发送通知，feedbackId={}", feedback.getId());
                return;
            }
            
            // 根据feedbackSource查询对应的用户表
            if (feedback.getFeedbackSource() == 0) {
                // 用户端 - 查询life_user表
                LifeUser lifeUser = lifeUserMapper.selectById(feedback.getUserId());
                if (lifeUser == null || lifeUser.getUserPhone() == null || lifeUser.getUserPhone().trim().isEmpty()) {
                    log.warn("未找到用户信息或手机号为空，无法发送通知，userId={}", feedback.getUserId());
                    return;
                }
                receiverId = "user_" + lifeUser.getUserPhone();
            } else if (feedback.getFeedbackSource() == 1) {
                // 商家端 - 查询store_user表
                StoreUser storeUser = storeUserMapper.selectById(feedback.getUserId());
                if (storeUser == null || storeUser.getPhone() == null || storeUser.getPhone().trim().isEmpty()) {
                    log.warn("未找到商户用户信息或手机号为空，无法发送通知，userId={}", feedback.getUserId());
                    return;
                }
                receiverId = "store_" + storeUser.getPhone();
            } else {
                log.warn("未知的反馈来源，feedbackSource={}, feedbackId={}", feedback.getFeedbackSource(), feedback.getId());
                return;
            }
            
            // 根据反馈类型生成通知消息
            String feedbackTypeText = "";
            if (feedback.getFeedbackType() != null) {
                switch (feedback.getFeedbackType()) {
                    case 0:
                        feedbackTypeText = "BUG";
                        break;
                    case 1:
                        feedbackTypeText = "优化";
                        break;
                    case 2:
                        feedbackTypeText = "功能";
                        break;
                    default:
                        feedbackTypeText = "BUG/优化/功能";
                        break;
                }
            } else {
                feedbackTypeText = "BUG/优化/功能";
            }
            String message = "您反馈的" + feedbackTypeText + "问题已解决，感谢您的反馈";
            
            // 构建通知消息
            JSONObject messageJson = new JSONObject();
            messageJson.put("feedbackId", feedback.getId());
            messageJson.put("message", message);

            // 创建通知记录
            LifeNotice lifeNotice = new LifeNotice();
            lifeNotice.setReceiverId(receiverId);
            lifeNotice.setContext(messageJson.toJSONString());
            lifeNotice.setTitle("意见反馈解决通知");
            lifeNotice.setSenderId("system");
            lifeNotice.setIsRead(0);
            lifeNotice.setNoticeType(1); // 1-系统通知
            lifeNotice.setBusinessId(feedback.getId());

            // 保存通知
            lifeNoticeUtil.fillUserTypeAndRefId(lifeNotice);
            lifeNoticeMapper.insert(lifeNotice);

            // 通过WebSocket发送实时通知
            WebSocketVo webSocketVo = new WebSocketVo();
            webSocketVo.setSenderId("system");
            webSocketVo.setReceiverId(receiverId);
            webSocketVo.setCategory("notice");
            webSocketVo.setNoticeType("1");
            webSocketVo.setIsRead(0);
            webSocketVo.setText(JSONObject.toJSONString(lifeNotice));

            try {
                webSocketProcess.sendMessage(receiverId, JSONObject.toJSONString(webSocketVo));
                log.info("问题已解决通知发送成功，feedbackId={}, receiverId={}", feedback.getId(), receiverId);
            } catch (Exception e) {
                log.error("发送WebSocket通知失败，feedbackId={}, receiverId={}, error={}",
                        feedback.getId(), receiverId, e.getMessage());
            }

        } catch (Exception e) {
            log.error("发送问题已解决通知异常，feedbackId={}, error={}", feedback.getId(), e.getMessage(), e);
        }
    }

    /**
     * 调用AI分配跟踪人员
     * @param feedback 反馈记录
     * @return 分配的跟踪人员ID（对应life_sys表的id），失败返回null
     */
    private Integer assignStaffByAI(LifeFeedback feedback) {
        try {
            // 调用AI工具类分配跟踪人员（只需要feedback_id）
            return aiFeedbackAssignUtils.assignStaffByAI(feedback);
        } catch (Exception e) {
            log.error("调用AI分配跟踪人员失败，feedbackId={}, error={}", feedback.getId(), e.getMessage(), e);
            return null;
        }
    }

    /**
     * 发送分配跟踪人员通知给中台（平台端）
     *
     * 根据AI接口文档：
     * - staff_id 对应 life_sys 表的 id
     * - 用户端和商户端反馈都需要发送通知
     *
     * @param feedback 反馈记录
     * @param staffId 跟踪人员ID（对应life_sys表的id）
     */
    private void sendStaffAssignmentNotice(LifeFeedback feedback, Integer staffId) {
        try {
            // 如果没有分配跟踪人员，则无法发送通知
            if (staffId == null) {
                log.warn("未分配跟踪人员，无法发送通知，feedbackId={}", feedback.getId());
                return;
            }

            // 查询跟踪人员信息（从life_sys表查询）
            LifeSys staff = lifeSysMapper.selectById(staffId);
            if (staff == null) {
                log.warn("未找到跟踪人员信息（life_sys），无法发送通知，staffId={}, feedbackId={}",
                        staffId, feedback.getId());
                return;
            }

            // 平台端接收者ID格式：staff_{staffId}（与用户回复通知保持一致）
            String receiverId = "staff_" + staffId;

            // 获取用户信息（用于显示在通知中）
            String userName = "用户";
            if (feedback.getUserId() != null) {
                StoreUser storeUser = storeUserMapper.selectById(feedback.getUserId());
                if (storeUser != null && storeUser.getPhone() != null) {
                    userName = storeUser.getPhone();
                }
            }

            // 获取反馈来源名称
            String sourceName = feedback.getFeedbackSource() != null && feedback.getFeedbackSource() == 1 ? "商户" : "用户";

            // 构建通知消息
            JSONObject messageJson = new JSONObject();
            messageJson.put("feedbackId", feedback.getId());
            messageJson.put("staffId", staffId);
            messageJson.put("staffName", staff.getUserName()); // life_sys表使用userName字段
            messageJson.put("userId", feedback.getUserId());
            messageJson.put("userName", userName);
            messageJson.put("feedbackSource", feedback.getFeedbackSource());
            messageJson.put("feedbackContent", feedback.getContent());
            messageJson.put("message", "您已被分配处理" + sourceName + "反馈工单，反馈内容：" + feedback.getContent());

            // 创建通知记录
            LifeNotice lifeNotice = new LifeNotice();
            lifeNotice.setReceiverId(receiverId);
            lifeNotice.setContext(messageJson.toJSONString());
            lifeNotice.setTitle("反馈工单分配通知");
            lifeNotice.setSenderId("system");
            lifeNotice.setIsRead(0);
            lifeNotice.setNoticeType(1); // 1-系统通知
            lifeNotice.setBusinessId(feedback.getId());

            // 保存通知
            lifeNoticeUtil.fillUserTypeAndRefId(lifeNotice);
            lifeNoticeMapper.insert(lifeNotice);

            // 通过WebSocket发送实时通知
            WebSocketVo webSocketVo = new WebSocketVo();
            webSocketVo.setSenderId("system");
            webSocketVo.setReceiverId(receiverId);
            webSocketVo.setCategory("notice");
            webSocketVo.setNoticeType("1");
            webSocketVo.setIsRead(0);
            webSocketVo.setText(JSONObject.toJSONString(lifeNotice));

            try {
                webSocketProcess.sendMessage(receiverId, JSONObject.toJSONString(webSocketVo));
                log.info("分配跟踪人员通知发送成功（中台），feedbackId={}, receiverId={}, staffId={}, staffName={}",
                        feedback.getId(), receiverId, staffId, staff.getUserName());
            } catch (Exception e) {
                log.error("发送WebSocket通知失败，feedbackId={}, receiverId={}, error={}",
                        feedback.getId(), receiverId, e.getMessage());
            }

        } catch (Exception e) {
            log.error("发送分配跟踪人员通知异常（中台），feedbackId={}, error={}", feedback.getId(), e.getMessage(), e);
        }
    }

    /**
     * 发送提交反馈工单通知到中台
     *
     * 根据AI接口文档：
     * - staff_id 对应 life_sys 表的 id
     * - 用户端和商户端反馈都会发送通知
     *
     * @param feedback 反馈记录
     */
    private void sendFeedbackSubmittedNoticeToPlatform(LifeFeedback feedback) {
        try {
            // 如果没有分配跟踪人员，则无法发送通知到中台
            if (feedback.getStaffId() == null) {
                log.warn("反馈未分配跟踪人员，无法发送提交通知到中台，feedbackId={}", feedback.getId());
                return;
            }

            // 查询跟踪人员信息（从life_sys表查询）
            LifeSys staff = lifeSysMapper.selectById(feedback.getStaffId());
            if (staff == null) {
                log.warn("未找到跟踪人员信息（life_sys），无法发送通知，staffId={}, feedbackId={}",
                        feedback.getStaffId(), feedback.getId());
                return;
            }

            // 获取用户信息（用于显示在通知中）
            String userName = "用户";
            if (feedback.getUserId() != null) {
                StoreUser storeUser = storeUserMapper.selectById(feedback.getUserId());
                if (storeUser != null && storeUser.getPhone() != null) {
                    userName = storeUser.getPhone();
                }
            }

            // 获取反馈来源名称
            String sourceName = feedback.getFeedbackSource() != null && feedback.getFeedbackSource() == 1 ? "商户" : "用户";

            // 中台接收者ID格式：staff_{staffId}
            String receiverId = "staff_" + feedback.getStaffId();

            // 构建通知消息
            JSONObject messageJson = new JSONObject();
            messageJson.put("feedbackId", feedback.getId());
            messageJson.put("staffId", feedback.getStaffId());
            messageJson.put("staffName", staff.getUserName()); // life_sys表使用userName字段
            messageJson.put("userId", feedback.getUserId());
            messageJson.put("userName", userName);
            messageJson.put("feedbackSource", feedback.getFeedbackSource());
            messageJson.put("feedbackContent", feedback.getContent());
            messageJson.put("message", sourceName + "提交了新的反馈工单，反馈内容：" + feedback.getContent());

            // 创建通知记录
            LifeNotice lifeNotice = new LifeNotice();
            lifeNotice.setReceiverId(receiverId);
            lifeNotice.setContext(messageJson.toJSONString());
            lifeNotice.setTitle("反馈工单提交通知");
            lifeNotice.setSenderId("system");
            lifeNotice.setIsRead(0);
            lifeNotice.setNoticeType(1); // 1-系统通知
            lifeNotice.setBusinessId(feedback.getId());

            // 保存通知
            lifeNoticeUtil.fillUserTypeAndRefId(lifeNotice);
            lifeNoticeMapper.insert(lifeNotice);

            // 通过WebSocket发送实时通知
            WebSocketVo webSocketVo = new WebSocketVo();
            webSocketVo.setSenderId("system");
            webSocketVo.setReceiverId(receiverId);
            webSocketVo.setCategory("notice");
            webSocketVo.setNoticeType("1");
            webSocketVo.setIsRead(0);
            webSocketVo.setText(JSONObject.toJSONString(lifeNotice));

            try {
                webSocketProcess.sendMessage(receiverId, JSONObject.toJSONString(webSocketVo));
                log.info("{}提交反馈工单通知发送成功（中台），feedbackId={}, receiverId={}, staffId={}",
                        sourceName, feedback.getId(), receiverId, feedback.getStaffId());
            } catch (Exception e) {
                log.error("发送WebSocket通知失败，feedbackId={}, receiverId={}, error={}",
                        feedback.getId(), receiverId, e.getMessage());
            }

        } catch (Exception e) {
            log.error("发送提交反馈工单通知异常（中台），feedbackId={}, error={}", feedback.getId(), e.getMessage(), e);
        }
    }

    /**
     * 发送用户回复通知给平台端（跟踪人员）
     *
     * 根据AI接口文档：
     * - staff_id 对应 life_sys 表的 id
     *
     * @param feedback 反馈记录
     * @param replyContent 用户回复内容
     */
    private void sendUserReplyNoticeToPlatform(LifeFeedback feedback, String replyContent) {
        try {
            // 如果反馈没有分配跟踪人员，则无法发送通知
            if (feedback.getStaffId() == null) {
                log.warn("反馈未分配跟踪人员，无法发送用户回复通知，feedbackId={}", feedback.getId());
                return;
            }

            // 查询跟踪人员信息（从life_sys表查询）
            LifeSys staff = lifeSysMapper.selectById(feedback.getStaffId());
            if (staff == null) {
                log.warn("未找到跟踪人员信息（life_sys），无法发送通知，staffId={}, feedbackId={}",
                        feedback.getStaffId(), feedback.getId());
                return;
            }

            // 获取反馈来源名称
            String sourceName = feedback.getFeedbackSource() != null && feedback.getFeedbackSource() == 1 ? "商户" : "用户";

            // 构建接收者ID（平台端跟踪人员，使用staff_前缀）
            String receiverId = "staff_" + feedback.getStaffId();

            // 构建通知消息
            JSONObject messageJson = new JSONObject();
            messageJson.put("feedbackId", feedback.getId());
            messageJson.put("staffId", feedback.getStaffId());
            messageJson.put("staffName", staff.getUserName()); // life_sys表使用userName字段
            messageJson.put("feedbackSource", feedback.getFeedbackSource());
            messageJson.put("message", sourceName + "已回复您的意见反馈：" + replyContent);

            // 创建通知记录
            LifeNotice lifeNotice = new LifeNotice();
            lifeNotice.setReceiverId(receiverId);
            lifeNotice.setContext(messageJson.toJSONString());
            lifeNotice.setTitle(sourceName + "回复通知");
            lifeNotice.setSenderId("system");
            lifeNotice.setIsRead(0);
            lifeNotice.setNoticeType(1); // 1-系统通知
            lifeNotice.setBusinessId(feedback.getId());

            // 保存通知
            lifeNoticeUtil.fillUserTypeAndRefId(lifeNotice);
            lifeNoticeMapper.insert(lifeNotice);

            // 通过WebSocket发送实时通知
            WebSocketVo webSocketVo = new WebSocketVo();
            webSocketVo.setSenderId("system");
            webSocketVo.setReceiverId(receiverId);
            webSocketVo.setCategory("notice");
            webSocketVo.setNoticeType("1");
            webSocketVo.setIsRead(0);
            webSocketVo.setText(JSONObject.toJSONString(lifeNotice));

            try {
                webSocketProcess.sendMessage(receiverId, JSONObject.toJSONString(webSocketVo));
                log.info("{}回复通知发送成功，feedbackId={}, receiverId={}, staffId={}",
                        sourceName, feedback.getId(), receiverId, feedback.getStaffId());
            } catch (Exception e) {
                log.error("发送WebSocket通知失败，feedbackId={}, receiverId={}, error={}",
                        feedback.getId(), receiverId, e.getMessage());
            }

        } catch (Exception e) {
            log.error("发送用户回复通知异常，feedbackId={}, error={}", feedback.getId(), e.getMessage(), e);
        }
    }
}

