package org.dromara.system.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.system.domain.TblDzbcFeedback;
import org.dromara.system.domain.vo.SysUserVo;
import org.dromara.system.domain.bo.FeedbackSubmitBo;
import org.dromara.system.domain.bo.TblDzbcFeedbackBo;
import org.dromara.system.domain.SysOss;
import org.dromara.system.domain.vo.SysOssVo;
import org.dromara.system.domain.vo.TblDzbcFeedbackVo;
import org.dromara.system.mapper.TblDzbcFeedbackMapper;
import org.dromara.system.service.ISysOssService;
import org.dromara.system.service.ISysUserService;
import org.dromara.system.service.ITblDzbcFeedbackService;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

@RequiredArgsConstructor
@Service
public class TblDzbcFeedbackServiceImpl implements ITblDzbcFeedbackService {

    private final TblDzbcFeedbackMapper baseMapper;
    private final ISysOssService ossService;
    private final ISysUserService userService;

    @Override
    public TblDzbcFeedbackVo queryById(Long id) {
        return baseMapper.selectVoById(id);
    }

    @Override
    public TableDataInfo<TblDzbcFeedbackVo> queryPageList(TblDzbcFeedbackBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<TblDzbcFeedback> lqw = buildQueryWrapper(bo);
        Page<TblDzbcFeedbackVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        fillUserInfo(result.getRecords());
        return TableDataInfo.build(result);
    }

    @Override
    public List<TblDzbcFeedbackVo> queryList(TblDzbcFeedbackBo bo) {
        LambdaQueryWrapper<TblDzbcFeedback> lqw = buildQueryWrapper(bo);
        List<TblDzbcFeedbackVo> list = baseMapper.selectVoList(lqw);
        fillUserInfo(list);
        return list;
    }

    @Override
    public List<TblDzbcFeedbackVo> queryByUserId(Long userId) {
        LambdaQueryWrapper<TblDzbcFeedback> lqw = Wrappers.lambdaQuery();
        lqw.eq(TblDzbcFeedback::getUserId, userId);
        lqw.orderByDesc(TblDzbcFeedback::getCreateTime);
        List<TblDzbcFeedbackVo> list = baseMapper.selectVoList(lqw);
        fillUserInfo(list);
        return list;
    }

    @Override
    public TblDzbcFeedbackVo submit(FeedbackSubmitBo bo) {
        Long userId = LoginHelper.getUserId();
        SysUserVo user = userService.selectUserById(userId);

        List<String> imageUrls = new ArrayList<>();
        if (bo.getImages() != null && !bo.getImages().isEmpty()) {
            for (MultipartFile file : bo.getImages()) {
                SysOssVo oss = ossService.upload(file);
                imageUrls.add(oss.getUrl());
            }
        }

        TblDzbcFeedback feedback = new TblDzbcFeedback();
        feedback.setUserId(userId);
        feedback.setUserName(user != null ? user.getNickName() : null);
        feedback.setUserPhone(user != null ? user.getPhonenumber() : null);
        feedback.setContent(bo.getContent());
        feedback.setImageUrls(imageUrls.isEmpty() ? null : String.join(",", imageUrls));
        feedback.setType(bo.getType());
        feedback.setStatus(0);

        baseMapper.insert(feedback);
        return baseMapper.selectVoById(feedback.getId());
    }

    @Override
    public Boolean insertByBo(TblDzbcFeedbackBo bo) {
        TblDzbcFeedback add = MapstructUtils.convert(bo, TblDzbcFeedback.class);
        validEntityBeforeSave(add);
        return baseMapper.insert(add) > 0;
    }

    @Override
    public Boolean updateByBo(TblDzbcFeedbackBo bo) {
        TblDzbcFeedback update = MapstructUtils.convert(bo, TblDzbcFeedback.class);
        validEntityBeforeSave(update);
        if(update.getId()!=null){
            return baseMapper.updateById(update) > 0;
        }
        return baseMapper.insert(update) > 0;
    }

    @Override
    public Boolean reply(Long id, String replyContent) {
        Long userId = LoginHelper.getUserId();
        SysUserVo user = userService.selectUserById(userId);

        TblDzbcFeedback feedback = new TblDzbcFeedback();
        feedback.setId(id);
        feedback.setReplyContent(replyContent);
        feedback.setReplyUserId(userId);
        feedback.setReplyUserName(user != null ? user.getNickName() : null);
        feedback.setReplyTime(LocalDateTime.now());
        feedback.setStatus(2);

        return baseMapper.updateById(feedback) > 0;
    }

    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    private LambdaQueryWrapper<TblDzbcFeedback> buildQueryWrapper(TblDzbcFeedbackBo bo) {
        LambdaQueryWrapper<TblDzbcFeedback> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getUserId() != null, TblDzbcFeedback::getUserId, bo.getUserId());
        lqw.like(StrUtil.isNotBlank(bo.getUserName()), TblDzbcFeedback::getUserName, bo.getUserName());
        lqw.like(StrUtil.isNotBlank(bo.getContent()), TblDzbcFeedback::getContent, bo.getContent());
        lqw.eq(bo.getType() != null, TblDzbcFeedback::getType, bo.getType());
        lqw.eq(bo.getStatus() != null, TblDzbcFeedback::getStatus, bo.getStatus());
        lqw.orderByDesc(TblDzbcFeedback::getCreateTime);
        return lqw;
    }

    private void validEntityBeforeSave(TblDzbcFeedback entity) {
        if (StrUtil.isBlank(entity.getContent())) {
            throw new IllegalArgumentException("反馈内容不能为空");
        }
        if (entity.getType() == null) {
            throw new IllegalArgumentException("反馈类型不能为空");
        }
    }

    private void fillUserInfo(List<TblDzbcFeedbackVo> list) {
        if (list == null || list.isEmpty()) {
            return;
        }
        list.forEach(vo -> {
            if (vo.getUserId() != null && StrUtil.isBlank(vo.getUserName())) {
                SysUserVo user = userService.selectUserById(vo.getUserId());
                if (user != null) {
                    vo.setUserName(user.getNickName());
                    vo.setUserPhone(user.getPhonenumber());
                }
            }
        });
    }
}
