package shop.alien.store.service.impl;

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.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartRequest;
import shop.alien.entity.store.*;
import shop.alien.entity.store.excelVo.util.ExcelExporter;
import shop.alien.entity.store.vo.StoreCommentAppealLogVo;
import shop.alien.entity.store.vo.StoreCommentAppealInfoVo;
import shop.alien.entity.store.vo.StoreCommentAppealVo;
import shop.alien.mapper.*;
import shop.alien.store.service.StoreCommentAppealService;
import shop.alien.store.util.FileUploadUtil;
import shop.alien.util.common.netease.TextCheckUtil;
import shop.alien.util.common.safe.TextModerationResultVO;
import shop.alien.util.common.safe.TextModerationUtil;
import shop.alien.util.common.safe.TextReviewServiceEnum;

import java.net.URLEncoder;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 评论申诉表 服务实现类
 *
 * @author ssk
 * @since 2025-01-02
 */
@Service
@Transactional
@RequiredArgsConstructor
public class StoreCommentAppealServiceImpl extends ServiceImpl<StoreCommentAppealMapper, StoreCommentAppeal> implements StoreCommentAppealService {

    private final StoreCommentAppealMapper storeCommentAppealMapper;

    private final StoreCommentMapper storeCommentMapper;

    private final StoreImgMapper storeImgMapper;

    private final StoreCommentAppealLogMapper storeCommentAppealLogMapper;

    private final FileUploadUtil fileUploadUtil;

    private final WebAuditMapper webAuditMapper;

    private final StoreDictionaryMapper storeDictionaryMapper;

    @Autowired
    private TextModerationUtil textModerationUtil;

    /**
     * 懒得查, 留着导出Excel
     */
    private List<StoreCommentAppealVo> toExcel = new ArrayList<>();

    /**
     * 申诉历史-分页
     *
     * @param pageNum      页数
     * @param pageSize     页容
     * @param storeId      门店id
     * @param appealStatus 申诉状态: 0:待处理, 1:已驳回, 2:已同意
     * @return IPage<StoreCommentAppeal>
     */
    @Override
    public IPage<StoreCommentAppealVo> getAppealHistory(Integer pageNum, Integer pageSize, Integer storeId, String appealStatus) {
        QueryWrapper<StoreCommentAppealVo> wrapper = new QueryWrapper<>();
        wrapper.eq("a.store_id", storeId)
                .eq(!appealStatus.isEmpty() && !"null".equals(appealStatus), "a.appeal_status", appealStatus)
                .eq("a.delete_flag", 0)
                .orderByDesc("a.created_time");
        IPage<StoreCommentAppealVo> storeCommentAppealPage = storeCommentAppealMapper.getStoreCommentAppealPage(new Page<>(pageNum, pageSize), wrapper);
        storeCommentAppealPage.getRecords().forEach(item -> {
            String[] split = item.getImgId().split(",");
            List<String> imgList = new ArrayList<>();
            for (String s : split) {
                StoreImg storeImg = storeImgMapper.selectById(s);
                if (null != storeImg) {
                    imgList.add(storeImg.getImgUrl());
                }
            }
            item.setImgList(imgList);
        });
        return storeCommentAppealPage;
    }

    @Override
    public Map<String, Integer> getAppealHistoryCountStatus(Integer storeId) {
        Map<String, Integer> map = new HashMap<>();
        //全部
        map.put("-1", storeCommentAppealMapper.selectCount(new LambdaQueryWrapper<StoreCommentAppeal>().eq(StoreCommentAppeal::getStoreId, storeId).eq(StoreCommentAppeal::getDeleteFlag, 0)));
        //审核中
        map.put("0", storeCommentAppealMapper.selectCount(new LambdaQueryWrapper<StoreCommentAppeal>().eq(StoreCommentAppeal::getStoreId, storeId).eq(StoreCommentAppeal::getDeleteFlag, 0).eq(StoreCommentAppeal::getAppealStatus, 0)));
        //驳回
        map.put("1", storeCommentAppealMapper.selectCount(new LambdaQueryWrapper<StoreCommentAppeal>().eq(StoreCommentAppeal::getStoreId, storeId).eq(StoreCommentAppeal::getDeleteFlag, 0).eq(StoreCommentAppeal::getAppealStatus, 1)));
        // 通过
        map.put("2", storeCommentAppealMapper.selectCount(new LambdaQueryWrapper<StoreCommentAppeal>().eq(StoreCommentAppeal::getStoreId, storeId).eq(StoreCommentAppeal::getDeleteFlag, 0).eq(StoreCommentAppeal::getAppealStatus, 2)));
        return map;
    }

    /**
     * 新增申诉
     *
     * @param multipartRequest 文件
     * @param storeId          门店id
     * @param commentId        评论id
     * @param appealReason     申诉原因
     * @return Integer(0 : 申诉成功, 1 : 申诉失败, 2 : 申诉已存在, 3 : 文本内容异常)
     */
    @Override
    public Integer addAppeal(MultipartRequest multipartRequest, Integer storeId, Integer commentId, String appealReason) {
        try {
            /*Map<String, String> checkText = TextCheckUtil.check(appealReason);
            if (null == checkText || checkText.get("result").equals("1")) {
                return 3;
            }*/

            List<String> servicesList = Lists.newArrayList();
            servicesList.add(TextReviewServiceEnum.COMMENT_DETECTION_PRO.getService());
            servicesList.add(TextReviewServiceEnum.LLM_QUERY_MODERATION.getService());
            TextModerationResultVO textCheckResult = textModerationUtil.invokeFunction(appealReason, servicesList);
            if ("high".equals(textCheckResult.getRiskLevel())) {
                return 3;
            }

            List<String> fileNameSet = new ArrayList<>(multipartRequest.getMultiFileMap().keySet());
            LambdaQueryWrapper<StoreCommentAppeal> wrapper = new LambdaQueryWrapper<>();
            //待审批, 已通过
            List<Integer> list = new ArrayList<>();
            list.add(0);
            list.add(2);
            wrapper.eq(StoreCommentAppeal::getStoreId, storeId)
                    .eq(StoreCommentAppeal::getCommentId, commentId)
                    .in(StoreCommentAppeal::getAppealStatus, list)
                    .orderByDesc(StoreCommentAppeal::getCreatedTime)
                    .last("limit 1");
            /*if (this.getOne(wrapper) != null) {
                return 2;
            }*/
            StoreCommentAppeal storeCommentAppeal = new StoreCommentAppeal();
            StringBuilder imgId = new StringBuilder();
            for (int i = 0; i < fileNameSet.size(); i++) {
                MultipartFile multipartFile = multipartRequest.getFileMap().get(fileNameSet.get(i));
                if (null != multipartFile) {
                    StoreImg storeImg = new StoreImg();
                    storeImg.setStoreId(storeId);
                    storeImg.setImgType(9);
                    storeImg.setImgSort(i + 1);
                    storeImg.setImgUrl(fileUploadUtil.uploadOneFile(multipartFile));
                    storeImgMapper.insert(storeImg);
                    imgId.append(storeImg.getId()).append(",");
                }
            }
            if (!imgId.toString().isEmpty()) {
                storeCommentAppeal.setImgId(imgId.substring(0, imgId.length() - 1));
            }
            storeCommentAppeal.setStoreId(storeId);
            storeCommentAppeal.setCommentId(commentId);
            storeCommentAppeal.setAppealReason(appealReason);
            storeCommentAppeal.setAppealStatus(0);
            boolean storeCommentAppealSave = this.save(storeCommentAppeal);
            //商家申诉
            StoreCommentAppealLog storeCommentAppealLog = new StoreCommentAppealLog();
            storeCommentAppealLog.setAppealId(storeCommentAppeal.getId());
            storeCommentAppealLog.setProcessType(0);
            storeCommentAppealLog.setDeleteFlag(0);
            storeCommentAppealLog.setCreatedTime(storeCommentAppeal.getCreatedTime());
            boolean result = storeCommentAppealSave && storeCommentAppealLogMapper.insert(storeCommentAppealLog) > 0;
            //系统审核
            StoreCommentAppealLog storeCommentAppealLogSystem = new StoreCommentAppealLog();
            storeCommentAppealLogSystem.setAppealId(storeCommentAppeal.getId());
            storeCommentAppealLogSystem.setProcessType(1);
            storeCommentAppealLogSystem.setDeleteFlag(0);
            storeCommentAppealLogSystem.setCreatedTime(storeCommentAppeal.getCreatedTime());
            boolean resultSystem = storeCommentAppealSave && storeCommentAppealLogMapper.insert(storeCommentAppealLogSystem) > 0;
            return result && resultSystem ? 0 : 1;
        } catch (Exception e) {
            return 1;
        }
    }

    /**
     * 新增申诉
     *
     * @param multipartRequest 文件
     * @param storeId          门店id
     * @param commentId        评论id
     * @param appealReason     申诉原因
     * @return Integer(0 : 申诉成功, 1 : 申诉失败, 2 : 申诉已存在, 3 : 文本内容异常)
     */
    @Override
    public StoreCommentAppealInfoVo addAppealNew(MultipartRequest multipartRequest, Integer storeId, Integer commentId, String appealReason) {
        StoreCommentAppealInfoVo storeCommentAppealInfoVo = new StoreCommentAppealInfoVo();
        try {
            Map<String, String> checkText = TextCheckUtil.check(appealReason);
            // todo 暂时去掉校验，防止校验不通过
//            if (null == checkText || checkText.get("result").equals("1")) {
//                storeCommentAppealInfoVo.setResult(3);
//                return storeCommentAppealInfoVo;
//            }

            List<String> servicesList = Lists.newArrayList();
            servicesList.add(TextReviewServiceEnum.COMMENT_DETECTION_PRO.getService());
            servicesList.add(TextReviewServiceEnum.LLM_QUERY_MODERATION.getService());
            TextModerationResultVO textCheckResult = textModerationUtil.invokeFunction(appealReason, servicesList);
            if ("high".equals(textCheckResult.getRiskLevel())) {
                storeCommentAppealInfoVo.setResult(3);
                return storeCommentAppealInfoVo;
            }

            List<String> fileNameSet = new ArrayList<>(multipartRequest.getMultiFileMap().keySet());
            LambdaQueryWrapper<StoreCommentAppeal> wrapper = new LambdaQueryWrapper<>();
            //待审批, 已通过
            List<Integer> list = new ArrayList<>();
            list.add(0);
            list.add(2);
            wrapper.eq(StoreCommentAppeal::getStoreId, storeId)
                    .eq(StoreCommentAppeal::getCommentId, commentId)
                    .in(StoreCommentAppeal::getAppealStatus, list)
                    .orderByDesc(StoreCommentAppeal::getCreatedTime)
                    .last("limit 1");
            if (this.getOne(wrapper) != null) {
                storeCommentAppealInfoVo.setResult(2);
                return storeCommentAppealInfoVo;
            }
            /*if (this.getOne(wrapper) != null) {
                return 2;
            }*/
            StoreCommentAppeal storeCommentAppeal = new StoreCommentAppeal();
            StringBuilder imgId = new StringBuilder();
            for (int i = 0; i < fileNameSet.size(); i++) {
                MultipartFile multipartFile = multipartRequest.getFileMap().get(fileNameSet.get(i));
                if (null != multipartFile) {
                    StoreImg storeImg = new StoreImg();
                    storeImg.setStoreId(storeId);
                    storeImg.setImgType(9);
                    storeImg.setImgSort(i + 1);
                    storeImg.setImgUrl(fileUploadUtil.uploadOneFile(multipartFile));
                    storeImgMapper.insert(storeImg);
                    imgId.append(storeImg.getId()).append(",");
                }
            }
            if (!imgId.toString().isEmpty()) {
                storeCommentAppeal.setImgId(imgId.substring(0, imgId.length() - 1));
            }
            storeCommentAppeal.setStoreId(storeId);
            storeCommentAppeal.setCommentId(commentId);
            storeCommentAppeal.setAppealReason(appealReason);
            storeCommentAppeal.setAppealStatus(0);

            int insertResult = storeCommentAppealMapper.insert(storeCommentAppeal);
            boolean storeCommentAppealSave = insertResult > 0;

            BeanUtils.copyProperties(storeCommentAppeal, storeCommentAppealInfoVo);
            //商家申诉
            StoreCommentAppealLog storeCommentAppealLog = new StoreCommentAppealLog();
            storeCommentAppealLog.setAppealId(storeCommentAppeal.getId());
            storeCommentAppealLog.setProcessType(0);
            storeCommentAppealLog.setDeleteFlag(0);
            storeCommentAppealLog.setCreatedTime(storeCommentAppeal.getCreatedTime());
            boolean result = storeCommentAppealSave && storeCommentAppealLogMapper.insert(storeCommentAppealLog) > 0;
            //系统审核
            StoreCommentAppealLog storeCommentAppealLogSystem = new StoreCommentAppealLog();
            storeCommentAppealLogSystem.setAppealId(storeCommentAppeal.getId());
            storeCommentAppealLogSystem.setProcessType(1);
            storeCommentAppealLogSystem.setDeleteFlag(0);
            storeCommentAppealLogSystem.setCreatedTime(storeCommentAppeal.getCreatedTime());
            boolean resultSystem = storeCommentAppealSave && storeCommentAppealLogMapper.insert(storeCommentAppealLogSystem) > 0;
            storeCommentAppealInfoVo.setResult(result && resultSystem ? 0 : 1);
        } catch (Exception e) {
            storeCommentAppealInfoVo.setResult(1);
            return storeCommentAppealInfoVo;
        }
        return storeCommentAppealInfoVo;
    }

    /**
     * 申诉详情
     *
     * @param id 申诉id
     * @return StoreCommentAppealVo
     */
    @Override
    public StoreCommentAppealVo getStoreCommentAppealDetail(Integer id) {
        QueryWrapper<StoreCommentAppealVo> storeCommentAppealVoQueryWrapper = new QueryWrapper<>();
        storeCommentAppealVoQueryWrapper.eq("a.id", id);
        StoreCommentAppealVo commentDetail = storeCommentAppealMapper.getCommentDetail(storeCommentAppealVoQueryWrapper);

        String[] split = commentDetail.getImgId().split(",");
        List<String> imgList = new ArrayList<>();
        for (String s : split) {
            StoreImg storeImg = storeImgMapper.selectById(s);
            if (null != storeImg) {
                imgList.add(storeImg.getImgUrl());
            }
        }
        commentDetail.setImgList(imgList);

        if (StringUtils.isNotEmpty(commentDetail.getCommentImgId())) {
            String[] split2 = commentDetail.getCommentImgId().split(",");
            List<String> imgList2 = new ArrayList<>();
            for (String s : split2) {
                StoreImg storeImg = storeImgMapper.selectById(s);
                if (null != storeImg) {
                    imgList2.add(storeImg.getImgUrl());
                }
            }
            commentDetail.setCommentImgList(imgList2);
        } else {
            commentDetail.setCommentImgList(new ArrayList<>());
        }

        List<StoreCommentAppealLogVo> storeCommentAppealLogVo = storeCommentAppealLogMapper.getStoreCommentAppealLogVo(commentDetail.getId());
        commentDetail.setStoreCommentAppealLogList(storeCommentAppealLogVo);
        if (ObjectUtils.isNotEmpty(storeCommentAppealLogVo)) {
            commentDetail.setLogRemark(storeCommentAppealLogVo.get(storeCommentAppealLogVo.size() - 1).getLogRemark());
        }
        return commentDetail;
    }

    /**
     * web-申诉分页查询
     *
     * @param pageNum      页数
     * @param pageSize     页容
     * @param storeName    门店名称
     * @param storeContact 门店联系人
     * @param storePhone   门店电话
     * @param appealStatus 申诉状态: 0:待处理, 1:已驳回, 2:已同意
     * @return IPage<StoreCommentAppealVo>
     */
    @Override
    public IPage<StoreCommentAppealVo> getStoreAppealPage(Integer pageNum, Integer pageSize, String storeName, String storeContact, String storePhone, String appealStatus) {
        IPage<StoreCommentAppealVo> storePage = new Page<>(pageNum, pageSize);
        QueryWrapper<StoreCommentAppealVo> queryWrapper = new QueryWrapper<>();
        queryWrapper.like(!storeName.isEmpty(), "e.store_name", storeName);
        queryWrapper.like(!storeContact.isEmpty(), "f.name", storeContact);
        queryWrapper.like(!storePhone.isEmpty(), "f.phone", storePhone);
        queryWrapper.like(!appealStatus.isEmpty(), "a.appeal_status", appealStatus);
        queryWrapper.orderByDesc("a.created_time");
        IPage<StoreCommentAppealVo> storeCommentAppealPage = storeCommentAppealMapper.getStoreCommentAppealPage(storePage, queryWrapper);
        List<StoreCommentAppealVo> records = storeCommentAppealPage.getRecords();
        if (!records.isEmpty()) {
            // 提前查询所有需要的字典数据
            Set<String> allTypes = records.stream()
                    .map(StoreCommentAppealVo::getStoreType)
                    .flatMap(type -> Arrays.stream(type.split(",")))
                    .collect(Collectors.toSet());
            List<StoreDictionary> storeDictionaries = storeDictionaryMapper.selectList(
                    new LambdaQueryWrapper<StoreDictionary>()
                            .eq(StoreDictionary::getTypeName, "storeType")
                            .in(StoreDictionary::getDictId, allTypes)
            );
            Map<String, String> typeMap = storeDictionaries.stream()
                    .collect(Collectors.toMap(
                            StoreDictionary::getDictId,
                            StoreDictionary::getDictDetail
                    ));
            storeCommentAppealPage.getRecords().forEach(item -> {
                String[] types = item.getStoreType().split(",");
                List<String> typeDetails = Arrays.stream(types)
                        .map(typeMap::get)
                        .filter(Objects::nonNull)
                        .collect(Collectors.toList());
                item.setStoreTypeStr(String.join(",", typeDetails));
                String[] split = item.getImgId().split(",");
                List<String> imgList = new ArrayList<>();
                for (String s : split) {
                    StoreImg storeImg = storeImgMapper.selectById(s);
                    if (null != storeImg) {
                        imgList.add(storeImg.getImgUrl());
                    }
                }
                item.setImgList(imgList);
            });
        }
        toExcel = storeCommentAppealPage.getRecords();
        return storeCommentAppealPage;
    }

    /**
     * 修改申诉状态
     *
     * @param id           申诉id
     * @param appealStatus 申诉状态: 0:待处理, 1:已驳回, 2:已同意
     * @return boolean
     */
    @Override
    public boolean setAppealStatus(Integer id, Integer appealStatus, String logRemark) {
        StoreCommentAppeal storeCommentAppeal = new StoreCommentAppeal();
        storeCommentAppeal.setId(id);
        storeCommentAppeal.setAppealStatus(appealStatus);
        switch (appealStatus) {
            case 0:
                storeCommentAppeal.setFinalResult("待处理");
                break;
            case 1:
                storeCommentAppeal.setFinalResult("已驳回");
                break;
            case 2:
                storeCommentAppeal.setFinalResult("已同意");
                //删除原评论
                StoreCommentAppeal byId = this.getById(id);
                storeCommentMapper.deleteById(byId.getCommentId());
                //删除原评论下的评论
                storeCommentMapper.update(null, new LambdaUpdateWrapper<StoreComment>().eq(StoreComment::getReplyId, byId.getCommentId()).set(StoreComment::getDeleteFlag, 1));
                break;
        }
        //商家申诉
        //处理中台审核记录
        LambdaUpdateWrapper<WebAudit> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(WebAudit::getStoreCommentAppealId, storeCommentAppeal.getId());
        wrapper.set(WebAudit::getStatus, "1");
        webAuditMapper.update(null, wrapper);

        StoreCommentAppealLog storeCommentAppealLog = new StoreCommentAppealLog();
        storeCommentAppealLog.setAppealId(storeCommentAppeal.getId());
        if (appealStatus == 1) {
            storeCommentAppealLog.setProcessType(4);
        } else if (appealStatus == 2) {
            storeCommentAppealLog.setProcessType(5);
        }
        storeCommentAppealLog.setDeleteFlag(0);
        storeCommentAppealLog.setCreatedTime(new Date());
        storeCommentAppealLog.setLogRemark(logRemark);
        storeCommentAppealLogMapper.insert(storeCommentAppealLog);
        return this.updateById(storeCommentAppeal);
    }

    /**
     * 导出Excel
     *
     * @return ResponseEntity
     */
    @Override
    public ResponseEntity<byte[]> exportToExcel() {
        try {
            String[] headers = {"商家名称", "联系人", "联系电话", "经营种类", "申诉时间", "顾客评论", "申诉理由", "状态"};
            byte[] excelData = ExcelExporter.exportToExcel(toExcel, headers, "申诉管理列表");
            HttpHeaders responseHeaders = new HttpHeaders();
            responseHeaders.add("Content-Disposition", "attachment; filename=\"" + URLEncoder.encode("申诉管理列表.xlsx") + "\";charset=utf-8");
            responseHeaders.set("charset", "UTF-8");
            return new ResponseEntity<>(excelData, responseHeaders, HttpStatus.OK);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

}
