package shop.alien.store.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
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 lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import shop.alien.entity.result.R;
import shop.alien.entity.store.CommonRating;
import shop.alien.entity.store.StoreCommentAppeal;
import shop.alien.entity.store.StoreCommentAppealSupplement;
import shop.alien.entity.store.dto.StoreCommentAppealSupplementAddDto;
import shop.alien.entity.store.dto.StoreCommentAppealSupplementUpdateDto;
import shop.alien.entity.store.vo.StoreCommentAppealSupplementVo;
import shop.alien.mapper.CommonRatingMapper;
import shop.alien.mapper.StoreCommentAppealMapper;
import shop.alien.mapper.StoreCommentAppealSupplementMapper;
import shop.alien.store.service.StoreCommentAppealSupplementService;
import shop.alien.util.common.safe.TextModerationResultVO;
import shop.alien.util.common.safe.TextModerationUtil;
import shop.alien.util.common.safe.TextReviewServiceEnum;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 评论申诉-用户补充内容 服务实现类
 */
@Slf4j
@Service
@Transactional
@RequiredArgsConstructor
public class StoreCommentAppealSupplementServiceImpl
        extends ServiceImpl<StoreCommentAppealSupplementMapper, StoreCommentAppealSupplement>
        implements StoreCommentAppealSupplementService {

    private static final List<Integer> OPEN_APPEAL_STATUS = Arrays.asList(0, 3);

    private final StoreCommentAppealSupplementMapper supplementMapper;
    private final StoreCommentAppealMapper storeCommentAppealMapper;
    private final CommonRatingMapper commonRatingMapper;

    @Autowired
    private TextModerationUtil textModerationUtil;

    @Override
    public R<StoreCommentAppealSupplementVo> addSupplement(StoreCommentAppealSupplementAddDto dto) {
        StoreCommentAppealSupplementVo resultVo = new StoreCommentAppealSupplementVo();
        try {
            if (dto == null || dto.getAppealId() == null || dto.getUserId() == null
                    || StringUtils.isEmpty(dto.getSupplementContent())) {
                resultVo.setResult(1);
                return R.data(resultVo);
            }

            StoreCommentAppeal appeal = storeCommentAppealMapper.selectById(dto.getAppealId());
            if (appeal == null) {
                resultVo.setResult(1);
                return R.data(resultVo);
            }
            if (!OPEN_APPEAL_STATUS.contains(appeal.getAppealStatus())) {
                resultVo.setResult(2);
                return R.data(resultVo);
            }

            CommonRating rating = commonRatingMapper.selectById(appeal.getCommentId());
            if (rating == null || !dto.getUserId().equals(rating.getUserId())) {
                resultVo.setResult(4);
                return R.data(resultVo);
            }

            if (isTextRisk(dto.getSupplementContent())) {
                resultVo.setResult(3);
                return R.data(resultVo);
            }

            StoreCommentAppealSupplement supplement = new StoreCommentAppealSupplement();
            supplement.setAppealId(dto.getAppealId());
            supplement.setCommentId(appeal.getCommentId());
            supplement.setUserId(dto.getUserId());
            supplement.setStoreId(appeal.getStoreId());
            supplement.setSupplementContent(dto.getSupplementContent().trim());
            supplement.setImageUrls(normalizeImageUrls(dto.getImageUrls()));
            supplement.setAuditStatus(1);
            supplement.setCreatedUserId(dto.getUserId().intValue());

            if (!this.save(supplement)) {
                resultVo.setResult(1);
                return R.data(resultVo);
            }

            StoreCommentAppealSupplementVo vo = supplementMapper.getDetailById(supplement.getId());
            fillImgList(vo);
            vo.setResult(0);
            return R.data(vo);
        } catch (Exception e) {
            log.error("新增申诉补充异常", e);
            resultVo.setResult(1);
            return R.data(resultVo);
        }
    }

    @Override
    public R<StoreCommentAppealSupplementVo> updateSupplement(StoreCommentAppealSupplementUpdateDto dto) {
        try {
            if (dto == null || dto.getId() == null || dto.getUserId() == null) {
                return R.fail("参数不完整");
            }

            StoreCommentAppealSupplement existing = this.getById(dto.getId());
            if (existing == null) {
                return R.fail("补充记录不存在");
            }
            if (!dto.getUserId().equals(existing.getUserId())) {
                return R.fail("无权限修改该补充");
            }

            StoreCommentAppeal appeal = storeCommentAppealMapper.selectById(existing.getAppealId());
            if (appeal == null || !OPEN_APPEAL_STATUS.contains(appeal.getAppealStatus())) {
                return R.fail("申诉已结案，无法修改补充");
            }

            if (StringUtils.isNotEmpty(dto.getSupplementContent())) {
                if (isTextRisk(dto.getSupplementContent())) {
                    return R.fail("补充内容包含敏感信息");
                }
                existing.setSupplementContent(dto.getSupplementContent().trim());
            }
            if (dto.getImageUrls() != null) {
                existing.setImageUrls(normalizeImageUrls(dto.getImageUrls()));
            }
            existing.setUpdatedUserId(dto.getUserId().intValue());
            existing.setAuditStatus(1);

            if (!this.updateById(existing)) {
                return R.fail("修改补充失败");
            }

            StoreCommentAppealSupplementVo vo = supplementMapper.getDetailById(existing.getId());
            fillImgList(vo);
            vo.setResult(0);
            return R.data(vo);
        } catch (Exception e) {
            log.error("修改申诉补充异常, id={}", dto != null ? dto.getId() : null, e);
            return R.fail("修改补充失败");
        }
    }

    @Override
    public R<Boolean> deleteSupplement(Integer id, Long userId) {
        try {
            if (id == null || userId == null) {
                return R.fail("参数不完整");
            }

            StoreCommentAppealSupplement existing = this.getById(id);
            if (existing == null) {
                return R.fail("补充记录不存在");
            }
            if (!userId.equals(existing.getUserId())) {
                return R.fail("无权限删除该补充");
            }

            StoreCommentAppeal appeal = storeCommentAppealMapper.selectById(existing.getAppealId());
            if (appeal == null || !OPEN_APPEAL_STATUS.contains(appeal.getAppealStatus())) {
                return R.fail("申诉已结案，无法删除补充");
            }

            if (!this.removeById(id)) {
                return R.fail("删除补充失败");
            }
            return R.success("删除成功");
        } catch (Exception e) {
            log.error("删除申诉补充异常, id={}", id, e);
            return R.fail("删除补充失败");
        }
    }

    @Override
    public StoreCommentAppealSupplementVo getDetail(Integer id) {
        StoreCommentAppealSupplementVo vo = supplementMapper.getDetailById(id);
        fillImgList(vo);
        return vo;
    }

    @Override
    public List<StoreCommentAppealSupplementVo> listByAppealId(Integer appealId) {
        List<StoreCommentAppealSupplementVo> list = supplementMapper.listByAppealId(appealId);
        list.forEach(this::fillImgList);
        return list;
    }

    @Override
    public List<StoreCommentAppealSupplementVo> listByCommentId(Integer commentId) {
        List<StoreCommentAppealSupplementVo> list = supplementMapper.listByCommentId(commentId);
        list.forEach(this::fillImgList);
        return list;
    }

    @Override
    public IPage<StoreCommentAppealSupplementVo> getPage(Integer pageNum, Integer pageSize,
                                                         Integer appealId, Long userId,
                                                         Integer storeId, Integer auditStatus) {
        LambdaQueryWrapper<StoreCommentAppealSupplement> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(appealId != null, StoreCommentAppealSupplement::getAppealId, appealId)
                .eq(userId != null, StoreCommentAppealSupplement::getUserId, userId)
                .eq(storeId != null, StoreCommentAppealSupplement::getStoreId, storeId)
                .eq(auditStatus != null, StoreCommentAppealSupplement::getAuditStatus, auditStatus)
                .orderByDesc(StoreCommentAppealSupplement::getCreatedTime);

        IPage<StoreCommentAppealSupplement> page = this.page(new Page<>(pageNum, pageSize), wrapper);

        Page<StoreCommentAppealSupplementVo> voPage = new Page<>(page.getCurrent(), page.getSize(), page.getTotal());
        List<StoreCommentAppealSupplementVo> records = new ArrayList<>();
        for (StoreCommentAppealSupplement item : page.getRecords()) {
            StoreCommentAppealSupplementVo vo = supplementMapper.getDetailById(item.getId());
            if (vo == null) {
                vo = new StoreCommentAppealSupplementVo();
                BeanUtils.copyProperties(item, vo);
            }
            fillImgList(vo);
            records.add(vo);
        }
        voPage.setRecords(records);
        return voPage;
    }

    private boolean isTextRisk(String content) {
        try {
            List<String> servicesList = Lists.newArrayList();
            servicesList.add(TextReviewServiceEnum.COMMENT_DETECTION_PRO.getService());
            servicesList.add(TextReviewServiceEnum.LLM_QUERY_MODERATION.getService());
            TextModerationResultVO textCheckResult = textModerationUtil.invokeFunction(content, servicesList);
            return "high".equals(textCheckResult.getRiskLevel());
        } catch (Exception e) {
            log.error("补充内容文本审核异常", e);
            return false;
        }
    }

    private String normalizeImageUrls(String imageUrls) {
        if (StringUtils.isEmpty(imageUrls)) {
            return null;
        }
        return Arrays.stream(imageUrls.split(","))
                .map(String::trim)
                .filter(StringUtils::isNotEmpty)
                .collect(Collectors.joining(","));
    }

    private void fillImgList(StoreCommentAppealSupplementVo vo) {
        if (vo == null || StringUtils.isEmpty(vo.getImageUrls())) {
            if (vo != null) {
                vo.setImgList(new ArrayList<>());
            }
            return;
        }
        vo.setImgList(splitImageUrls(vo.getImageUrls()));
    }

    private List<String> splitImageUrls(String imageUrls) {
        List<String> imgList = new ArrayList<>();
        for (String item : imageUrls.split(",")) {
            String trimmed = item.trim();
            if (StringUtils.isNotEmpty(trimmed)) {
                imgList.add(trimmed);
            }
        }
        return imgList;
    }
}
