package com.ruoyi.ibs.task.service.impl;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.ibs.list.domain.LowcodeVisstFeedbackModel;
import com.ruoyi.ibs.list.mapper.LowcodeVisstFeedbackModelMapper;
import com.ruoyi.ibs.task.domain.dto.CustomFeedbackDTO;
import com.ruoyi.ibs.task.domain.dto.VisitFeedbackPrivateDTO;
import com.ruoyi.ibs.task.domain.dto.VisitFeedbackPublicDTO;
import com.ruoyi.ibs.task.domain.entity.IntentionProductDict;
import com.ruoyi.ibs.task.domain.entity.TaskVisitRecord;
import com.ruoyi.ibs.task.domain.entity.VisitFeedbackPrivate;
import com.ruoyi.ibs.task.domain.entity.VisitFeedbackPublic;
import com.ruoyi.ibs.task.domain.vo.VisitFeedbackPrivateVo;
import com.ruoyi.ibs.task.mapper.IntentionProductDictMapper;
import com.ruoyi.ibs.task.mapper.TaskVisitRecordMapper;
import com.ruoyi.ibs.task.mapper.VisitFeedbackPrivateMapper;
import com.ruoyi.ibs.task.mapper.VisitFeedbackPublicMapper;
import com.ruoyi.ibs.task.service.VisitFeedbackService;
import com.ruoyi.system.domain.OssFileUploadDTO;
import com.ruoyi.system.enums.OssFileEnum;
import com.ruoyi.system.service.OssFileService;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.List;
import java.util.Objects;

/**
 * @Author 吴凯程
 * @Date 2025/6/19
 **/
@Service
@Slf4j
public class VisitFeedbackServiceImpl implements VisitFeedbackService {

    private final ObjectMapper objectMapper = new ObjectMapper();
    @Resource
    private TaskVisitRecordMapper taskVisitRecordMapper;
    @Resource
    private OssFileService ossFileService;
    @Resource
    private VisitFeedbackPublicMapper visitFeedbackPublicMapper;
    @Resource
    private VisitFeedbackPrivateMapper visitFeedbackPrivateMapper;
    @Resource
    private IntentionProductDictMapper intentionProductDictMapper;
    @Resource
    private LowcodeVisstFeedbackModelMapper lowcodeVisstFeedbackModelMapper;

    @SneakyThrows
    @Override
    public JsonNode getFeedback(String feedbackType, String feedbackId) {
        if (feedbackType.equals("0")) {
            VisitFeedbackPrivate visitFeedbackPrivate = visitFeedbackPrivateMapper.selectById(feedbackId);
            if (visitFeedbackPrivate == null) {
                return null;
            }
            VisitFeedbackPrivateVo visitFeedbackPrivateVo = new VisitFeedbackPrivateVo(visitFeedbackPrivate);
            return objectMapper.convertValue(visitFeedbackPrivateVo, JsonNode.class);
        }else if (feedbackType.equals("1")){
            VisitFeedbackPublic visitFeedbackPublic = visitFeedbackPublicMapper.selectById(feedbackId);
            if (visitFeedbackPublic == null) {
                return null;
            }
            return objectMapper.convertValue(visitFeedbackPublic, JsonNode.class);
        }else if (feedbackType.equals("2")){
            MultipartFile fileFromOss = ossFileService.getFileFromOss(feedbackId);
            if (fileFromOss == null) {
                return null;
            }
            return convertJsonFile(fileFromOss);
        }
        return null;
    }

    /**
     * @param customFeedbackDTO
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String saveCustomFeedback(CustomFeedbackDTO customFeedbackDTO) {
        OssFileUploadDTO ossFileUploadDTO = new OssFileUploadDTO();
        ossFileUploadDTO.setOssFileEnum(OssFileEnum.FEEDBACK);
        MultipartFile feedback = new MockMultipartFile(customFeedbackDTO.getRecordId() + ".json", customFeedbackDTO.getRecordId() + ".json", "application/json",customFeedbackDTO.getFeedback().toString().getBytes());
        ossFileUploadDTO.setFile(feedback);
        String fileId = ossFileService.uploadFileToOss(ossFileUploadDTO);

        TaskVisitRecord taskVisitRecord = taskVisitRecordMapper.selectById(customFeedbackDTO.getRecordId());
        if (Objects.isNull(taskVisitRecord)){
            ossFileService.deleteFileFromOss(fileId);
            throw new ServiceException("走访记录不存在");
        }
        if (Objects.nonNull(taskVisitRecord.getFeedbackId())){
            ossFileService.deleteFileFromOss(taskVisitRecord.getFeedbackId());
            log.info("删除旧反馈文件:" + taskVisitRecord.getFeedbackId());
        }
        taskVisitRecord.setFeedbackId(fileId);
        taskVisitRecordMapper.updateById(taskVisitRecord);
        return "自定义反馈模板保存成功";
    }

    /**
     * @param visitFeedbackPrivateDTO
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String savePrivateFeedback(VisitFeedbackPrivateDTO visitFeedbackPrivateDTO) {
        TaskVisitRecord taskVisitRecord = taskVisitRecordMapper.selectById(visitFeedbackPrivateDTO.getRecordId());
        if (Objects.isNull(taskVisitRecord)){
            throw new ServiceException("走访记录不存在");
        }
        if (Objects.isNull(taskVisitRecord.getFeedbackType()) || !taskVisitRecord.getFeedbackType().equals("0")){
            throw new ServiceException("走访反馈模板与类型不符");
        }
        if (Objects.nonNull(taskVisitRecord.getFeedbackId())){
            VisitFeedbackPrivate visitFeedbackPrivate = visitFeedbackPrivateMapper.selectById(taskVisitRecord.getFeedbackId());
            BeanUtils.copyProperties(visitFeedbackPrivateDTO, visitFeedbackPrivate);
            visitFeedbackPrivateMapper.updateById(visitFeedbackPrivate);
            taskVisitRecord.setFeedbackId(visitFeedbackPrivate.getId());
            taskVisitRecordMapper.updateById(taskVisitRecord);
        }else{
            String uuid = IdUtils.fastSimpleUUID();
            VisitFeedbackPrivate visitFeedbackPrivate = new VisitFeedbackPrivate();
            visitFeedbackPrivate.setId(uuid);
            BeanUtils.copyProperties(visitFeedbackPrivateDTO, visitFeedbackPrivate);
            visitFeedbackPrivateMapper.insert(visitFeedbackPrivate);
            taskVisitRecord.setFeedbackId(visitFeedbackPrivate.getId());
            taskVisitRecordMapper.updateById(taskVisitRecord);
        }

        return "走访反馈保存成功";
    }

    /**
     * @param visitFeedbackPublicDTO
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String savePublicFeedback(VisitFeedbackPublicDTO visitFeedbackPublicDTO) {
        TaskVisitRecord taskVisitRecord = taskVisitRecordMapper.selectById(visitFeedbackPublicDTO.getRecordId());
        if (Objects.isNull(taskVisitRecord)){
            throw new ServiceException("走访记录不存在");
        }
        if (Objects.isNull(taskVisitRecord.getFeedbackType()) || !taskVisitRecord.getFeedbackType().equals("1")){
            throw new ServiceException("走访反馈模板与类型不符");
        }
        if (Objects.nonNull(taskVisitRecord.getFeedbackId())){
            VisitFeedbackPublic visitFeedbackPublic = visitFeedbackPublicMapper.selectById(taskVisitRecord.getFeedbackId());
            BeanUtils.copyProperties(visitFeedbackPublicDTO, visitFeedbackPublic);
            visitFeedbackPublic.setRelatePerson(JSON.toJSONString(visitFeedbackPublicDTO.getRelatePerson()));
            visitFeedbackPublicMapper.updateById(visitFeedbackPublic);
            taskVisitRecord.setFeedbackId(visitFeedbackPublic.getId());
            taskVisitRecordMapper.updateById(taskVisitRecord);
        }else{
            String uuid = IdUtils.fastSimpleUUID();
            VisitFeedbackPublic visitFeedbackPublic = new VisitFeedbackPublic();
            visitFeedbackPublic.setId(uuid);
            BeanUtils.copyProperties(visitFeedbackPublicDTO, visitFeedbackPublic);
            visitFeedbackPublic.setRelatePerson(JSON.toJSONString(visitFeedbackPublicDTO.getRelatePerson()));
            visitFeedbackPublicMapper.insert(visitFeedbackPublic);
            taskVisitRecord.setFeedbackId(visitFeedbackPublic.getId());
            taskVisitRecordMapper.updateById(taskVisitRecord);
        }
        return "走访反馈保存成功";
    }

    /**
     * @return
     */
    @Override
    public List<IntentionProductDict> getIntentionProductDict() {
        String dept = SecurityUtils.getHeadId();
        LambdaQueryWrapper<IntentionProductDict> intentionProductDictLambdaQueryWrapper = new LambdaQueryWrapper<>();
        intentionProductDictLambdaQueryWrapper.likeRight(IntentionProductDict::getBelOrg, dept);
        return intentionProductDictMapper.selectList(intentionProductDictLambdaQueryWrapper);
    }

    /**
     * @param feedbackTemplate
     * @return
     */
    @SneakyThrows
    @Override
    public JsonNode getCustomFeedbackTemplate(String feedbackTemplate) {
        LambdaQueryWrapper<LowcodeVisstFeedbackModel> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(LowcodeVisstFeedbackModel::getDeptId, SecurityUtils.getDeptId() / 1000 * 1000);
        queryWrapper.eq(LowcodeVisstFeedbackModel::getUuid, feedbackTemplate);
        LowcodeVisstFeedbackModel lowcodeVisstFeedbackModel = lowcodeVisstFeedbackModelMapper.selectOne(queryWrapper);
        return objectMapper.convertValue(lowcodeVisstFeedbackModel.getModelDetal(), JsonNode.class);
    }

    private JsonNode convertJsonFile(MultipartFile multipartFile) throws IOException {
        return objectMapper.readTree(multipartFile.getInputStream());
    }
}
