package com.yeejoin.amos.boot.module.common.biz.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yeejoin.amos.boot.module.common.api.dto.ContractDto;
import com.yeejoin.amos.boot.module.common.api.entity.Contract;
import com.yeejoin.amos.boot.module.common.api.entity.MaintenanceCompany;
import com.yeejoin.amos.boot.module.common.api.entity.SourceFile;
import com.yeejoin.amos.boot.module.common.api.mapper.ContractMapper;
import com.yeejoin.amos.boot.module.common.api.service.IContractService;
import com.yeejoin.amos.component.feign.model.FeignClientResult;
import com.yeejoin.amos.feign.systemctl.Systemctl;
import com.yeejoin.amos.feign.systemctl.model.FileInfoModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.typroject.tyboot.core.foundation.exception.BaseException;
import org.typroject.tyboot.core.foundation.utils.Bean;
import org.typroject.tyboot.core.foundation.utils.StringUtil;
import org.typroject.tyboot.core.foundation.utils.ValidationUtil;
import org.typroject.tyboot.core.rdbms.annotation.Condition;
import org.typroject.tyboot.core.rdbms.annotation.Operator;
import org.typroject.tyboot.core.rdbms.service.BaseService;
import org.typroject.tyboot.core.restful.exception.instance.DataNotFound;

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

/**
 * 维保合同服务实现类
 *
 * @author system_generator
 * @date 2021-07-16
 */
@Service
public class ContractServiceImpl extends BaseService<ContractDto, Contract, ContractMapper> implements IContractService {

    @Autowired
    SourceFileServiceImpl sourceFileServiceImpl;

    @Autowired
    MaintenanceCompanyServiceImpl maintenanceCompanyService;

    /**
     * 分页查询
     */
    public Page<ContractDto> queryForContractPage(Page<ContractDto> page, Boolean isDelete, Long companyId,
                                                  Long signedCompanyId, String name, Long typeCode, String signedDate,
                                                  String amosUserId) {
        if (ValidationUtil.isEmpty(companyId)) {
            MaintenanceCompany company = maintenanceCompanyService.getMaintenanceCompany(amosUserId);
            companyId = company.getSequenceNbr();
        }
        return queryForContractPageByParam(page, isDelete, companyId, signedCompanyId, name, typeCode,
                signedDate);
    }

    public Page<ContractDto> queryForContractPageByParam(Page<ContractDto> page, Boolean isDelete,
                                                  @Condition(Operator.eq) Long companyId,
                                                  @Condition(Operator.eq) Long signedCompanyId,
                                                  @Condition(Operator.like) String name,
                                                  @Condition(Operator.eq) Long typeCode,
                                                  @Condition(Operator.likeRight) String signedDate) {
        return this.queryForPage(page, null, false, isDelete, companyId, signedCompanyId, name, typeCode, signedDate);
    }

    /**
     * 列表查询 示例
     */
    public List<ContractDto> queryForContractList(Boolean isDelete) {
        return this.queryForList("rec_date", false, isDelete);
    }

    /**
     * 保存附件信息
     *
     * @param agencyCode
     * @param attachments
     * @param contractDto
     * @param fileCategory
     * @return
     * @throws Exception
     */
    private List<FileInfoModel> buildFileInfo(String agencyCode, List<String> attachments,
                                              ContractDto contractDto, String fileCategory) throws Exception {
        List<FileInfoModel> fileInfoModelList = new ArrayList<>();
        for (String attachment : attachments) {
            FileInfoModel fileInfoModel = new FileInfoModel();
            fileInfoModel.setEntityId(String.valueOf(contractDto.getSequenceNbr()));
            fileInfoModel.setEntityType(Contract.class.getSimpleName());
            fileInfoModel.setFileCategory(fileCategory);
            fileInfoModel.setFilename(attachment);
            fileInfoModel.setAgencyCode(agencyCode);
            fileInfoModelList.add(fileInfoModel);
        }

        return fileInfoModelList;
    }

    /**
     * 保存附件
     *
     * @param agencyCode
     * @param contractDto
     * @return
     * @throws Exception
     */
    private boolean saveAircraftFile(String agencyCode, ContractDto contractDto) throws Exception {
        List<FileInfoModel> fileInfoModelList = new ArrayList<FileInfoModel>();
        // 获取附件信息
        if (!ValidationUtil.isEmpty(contractDto.getContractAttachment())) {
            List<String> attachments = StringUtil.String2List(contractDto.getContractAttachment());
            for (String attachment : attachments) {
                String format = attachment.substring(attachment.lastIndexOf(".") + 1, attachment.length());
                fileInfoModelList.addAll(buildFileInfo(agencyCode, attachments, contractDto, format));
            }
        }
        // 保存附件
        if (!ValidationUtil.isEmpty(fileInfoModelList)) {
            Systemctl.fileInfoClient.batchCreateByEntity(fileInfoModelList);
        }
        return true;
    }

    /**
     * 保存合同信息
     *
     * @param agencyCode
     * @param contractDto
     * @return
     * @throws Exception
     */
    public ContractDto saveContractDto(String agencyCode, ContractDto contractDto) throws Exception {
        contractDto.setIsDelete(false);
        // 保存合同基本信息
        contractDto = this.createWithModel(contractDto);
        // 保存附件信息
        saveAircraftFile(agencyCode, contractDto);
        return contractDto;
    }

    /**
     * 更新合同信息及附件
     *
     * @param agencyCode
     * @param model
     * @return
     * @throws Exception
     */
    public ContractDto updateAircraft(String agencyCode, ContractDto model) throws Exception {
        ContractDto oldModel = this.queryBySeq(model.getSequenceNbr());
        if (ValidationUtil.isEmpty(oldModel)) {
            throw new DataNotFound("找不到指定的合同信息.");
        }
        //删除附件信息
        Systemctl.fileInfoClient.deleteByAlias(agencyCode, ContractDto.class.getSimpleName(),
                String.valueOf(model.getSequenceNbr()), null);
        //保存合同信息
        saveAircraftFile(agencyCode, model);
        return this.updateWithModel(Bean.copyExistPropertis(model, oldModel));
    }

    /**
     * 附件转成逗号分割String
     *
     * @param fileInfoModels
     * @return
     */
    private String processToStr(List<FileInfoModel> fileInfoModels) {
        return fileInfoModels.stream().map(FileInfoModel::getFilename).collect(Collectors.joining(","));
    }

    /**
     * 根据主键查询合同信息
     *
     * @param agencyCode
     * @param seq
     * @return
     */
    public ContractDto queryByAircraftSeq(String agencyCode, Long seq) {
        ContractDto contractDto = this.queryBySeq(seq);
        // 填充合同附件信息
        FeignClientResult<List<FileInfoModel>> fileInfoModelResult = Systemctl.fileInfoClient.queryByEntity(
                agencyCode, ContractDto.class.getSimpleName(), String.valueOf(seq));
        List<FileInfoModel> fileInfoModels = fileInfoModelResult.getResult();
        // 填充合同信息
        if (!ValidationUtil.isEmpty(fileInfoModels)) {
            contractDto.setContractAttachment(processToStr(fileInfoModels));
        }
        return contractDto;
    }

    /**
     * 删除合同信息 (无约束)
     *
     * @param agencyCode
     * @param ids
     * @return
     * @throws Exception
     */
    @Transactional(rollbackFor = {Exception.class, BaseException.class})
    public List<Long> multDeleteAircraft(String agencyCode, String ids) throws Exception {
        List<Long> seqs = StringUtil.String2LongList(ids);
        for (Long id : seqs) {
            //删除附件信息
            Systemctl.fileInfoClient.deleteByAlias(agencyCode, ContractDto.class.getSimpleName(),
                    String.valueOf(id), null);
            //删除合同信息
            this.deleteBySeq(id);
        }
        return seqs;
    }

    /**
     * 保存合同信息
     *
     * @param contractDto
     * @return
     */
    @Transactional
    public ContractDto saveModel(ContractDto contractDto) {
        // 保存合同基本信息
        contractDto = this.createWithModel(contractDto);
        // 保存附件信息
        sourceFileServiceImpl.saveSourceFile(contractDto.getSequenceNbr(), contractDto.getAttachment());
        return contractDto;
    }

    @Transactional
    public ContractDto updateById(ContractDto contractDto) {
        // 更新合同基本信息
        updateWithModel(contractDto);
        // 更新附件信息
        sourceFileServiceImpl.saveSourceFile(contractDto.getSequenceNbr(), contractDto.getAttachment());
        return contractDto;
    }

    /**
     * 批量删除
     *
     * @param sequenceNbrList
     * @return
     */
    public Boolean batchDelete(List<Long> sequenceNbrList) {
        // 删除基本信息
        List<Contract> contractList = list(new LambdaQueryWrapper<Contract>().in(Contract::getSequenceNbr,
                sequenceNbrList));
        contractList.forEach(item -> item.setIsDelete(true));
        boolean update = updateBatchById(contractList);
        // 删除附件
        sourceFileServiceImpl.getBaseMapper().delete(new LambdaQueryWrapper<SourceFile>().in(SourceFile::getSourceId,
                sequenceNbrList));
        return update;
    }

    /**
     * 查询单个合同
     *
     * @param sequenceNbr
     * @return
     */
    public ContractDto queryOne(Long sequenceNbr) {
        ContractDto contractDto = queryBySeq(sequenceNbr);
        List<SourceFile> sourceFiles = sourceFileServiceImpl.findBySourceId(sequenceNbr);
        contractDto.setAttachment(sourceFiles);
        return contractDto;
    }
}

