package com.supervision.police.service.impl;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.plugins.pagination.PageDTO;
import com.supervision.police.daoService.CaseEvidenceDaoService;
import com.supervision.police.daoService.EvidenceFileDaoService;
import com.supervision.police.domain.CaseEvidence;
import com.supervision.police.domain.ComDictionary;
import com.supervision.police.domain.EvidenceFile;
import com.supervision.police.dto.CaseEvidenceDetailDTO;
import com.supervision.police.dto.EvidenceFileDTO;
import com.supervision.police.service.CaseEvidenceService;
import com.supervision.police.dto.CaseEvidenceDTO;
import com.supervision.police.service.CaseStatusManageService;
import com.supervision.police.service.ComDictionaryService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class CaseEvidenceServiceImpl implements CaseEvidenceService {

    private final CaseEvidenceDaoService caseEvidenceDaoService;

    private final EvidenceFileDaoService evidenceFileDaoService;

    private final ComDictionaryService comDictionaryService;

    private final CaseStatusManageService caseStatusManageService;

    @Override
    @Transactional(transactionManager = "dataSourceTransactionManager",rollbackFor = Exception.class)
    public String saveEvidence(CaseEvidenceDTO caseEvidenceDTO) {
        // 必填校验
        caseEvidencePersistenceAssert(caseEvidenceDTO);

        // 保存证据信息
        CaseEvidence caseEvidence = caseEvidenceDTO.toCaseEvidence();
        caseEvidenceDaoService.save(caseEvidence);

        //保存文件关联信息
        caseEvidenceDTO.getFileIdList().forEach(fileId -> {
            EvidenceFile evidenceFile = new EvidenceFile();
            evidenceFile.setFileId(fileId);
            evidenceFile.setEvidenceId(caseEvidence.getId());
            evidenceFileDaoService.save(evidenceFile);
        });
        caseStatusManageService.whenUpdateEvidence(caseEvidence.getCaseId());
        return caseEvidence.getId();
    }

    private void caseEvidencePersistenceAssert(CaseEvidenceDTO caseEvidenceDTO) {
        Assert.notEmpty(caseEvidenceDTO.getCaseId(),"案件id不能为空");
        Assert.notEmpty(caseEvidenceDTO.getEvidenceName(),"证据名称不能为空");
        Assert.notEmpty(caseEvidenceDTO.getEvidenceType(),"证据类型不能为空");
        Assert.notEmpty(caseEvidenceDTO.getProvider(),"证据提供人不能为空");
        Assert.notEmpty(caseEvidenceDTO.getFileIdList(),"文件id不能为空");
    }

    @Override
    @Transactional(transactionManager = "dataSourceTransactionManager",rollbackFor = Exception.class)
    public String updateEvidence(CaseEvidenceDTO caseEvidenceDTO) {

        Assert.notEmpty(caseEvidenceDTO.getId(),"证据id不能为空");
        caseEvidencePersistenceAssert(caseEvidenceDTO);
        caseEvidenceDaoService.getOptById(caseEvidenceDTO.getId()).orElseThrow(() -> new IllegalArgumentException("证据信息不存在"));

        // 更新证据信息
        CaseEvidence caseEvidence = caseEvidenceDTO.toCaseEvidence();
        caseEvidenceDaoService.updateById(caseEvidence);

        // 更新文件关联信息
        evidenceFileDaoService.lambdaUpdate().eq(EvidenceFile::getEvidenceId,caseEvidence.getId()).remove();
        caseEvidenceDTO.getFileIdList().forEach(fileId -> {
            EvidenceFile evidenceFile = new EvidenceFile();
            evidenceFile.setFileId(fileId);
            evidenceFile.setEvidenceId(caseEvidence.getId());
            evidenceFileDaoService.save(evidenceFile);
        });
        caseStatusManageService.whenUpdateEvidence(caseEvidenceDTO.getCaseId());
        return caseEvidenceDTO.getId();
    }

    @Override
    @Transactional(transactionManager = "dataSourceTransactionManager",rollbackFor = Exception.class)
    public boolean deleteEvidence(String evidenceId) {

        CaseEvidence caseEvidence = caseEvidenceDaoService.getOptById(evidenceId).orElseThrow(() -> new IllegalArgumentException("证据信息不存在"));
        boolean remove = caseEvidenceDaoService.lambdaUpdate().eq(CaseEvidence::getId, evidenceId).remove();

        if (remove){
            evidenceFileDaoService.lambdaUpdate().eq(EvidenceFile::getEvidenceId,evidenceId).remove();
            caseStatusManageService.whenUpdateEvidence(caseEvidence.getCaseId());
        }
        return remove;
    }

    @Override
    @Transactional(transactionManager = "dataSourceTransactionManager",rollbackFor = Exception.class)
    public List<CaseEvidenceDetailDTO> queryEvidenceList(String caseId) {

        return caseEvidenceDaoService.queryEvidenceList(caseId);
    }

    @Override
    @Transactional(transactionManager = "dataSourceTransactionManager",rollbackFor = Exception.class)
    public IPage<CaseEvidenceDetailDTO> pageListEvidence(String caseId,String evidenceName, Integer pageNum, Integer pageSize) {

        Assert.notEmpty(caseId,"案件id不能为空");
        Page<CaseEvidence> caseEvidencePage = caseEvidenceDaoService.lambdaQuery().eq(CaseEvidence::getCaseId, caseId)
                .like(StrUtil.isNotEmpty(evidenceName), CaseEvidence::getEvidenceName,evidenceName)
                .orderBy(true, false,CaseEvidence::getUpdateTime)
                .page(new Page<>(pageNum, pageSize));

        if (caseEvidencePage.getTotal() == 0){
            return PageDTO.of(pageNum,pageSize,0);
        }

        // 查询文件信息
        List<String> evidenceIds = caseEvidencePage.getRecords().stream().map(CaseEvidence::getId).distinct().toList();
        List<EvidenceFileDTO> fileInfoList = evidenceFileDaoService.listFileInfo(evidenceIds);
        Map<String, List<EvidenceFileDTO>> evidenceFileMap = fileInfoList.stream().collect(Collectors.groupingBy(EvidenceFileDTO::getEvidenceId));

        // 转换分页结果
        //查询字典
        List<ComDictionary> evidenceTypeDic = comDictionaryService.lambdaQuery().eq(ComDictionary::getType, "evidence_type").list();
        return caseEvidencePage.convert(caseEvidence -> {
            CaseEvidenceDetailDTO caseEvidenceDetailDTO = new CaseEvidenceDetailDTO(caseEvidence, evidenceFileMap.get(caseEvidence.getId()));
            caseEvidenceDetailDTO.setEvidenceTypeDesc(
                    comDictionaryService.getName(evidenceTypeDic, "evidence_type", caseEvidence.getEvidenceType()));
            return caseEvidenceDetailDTO;
        });
    }

    @Override
    @Transactional(transactionManager = "dataSourceTransactionManager",rollbackFor = Exception.class)
    public CaseEvidenceDetailDTO queryEvidenceDetail(String evidenceId) {
        return caseEvidenceDaoService.queryEvidenceDetail(evidenceId);
    }
}