package org.qinan.safetyeval.infrastructure.gatewayimpl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.qinan.safetyeval.domain.entity.QualFilingMaterialEntity;
import org.qinan.safetyeval.domain.gateway.QualFilingMaterialGateway;
import org.qinan.safetyeval.domain.query.QualFilingMaterialQuery;
import org.qinan.safetyeval.domain.query.PageResult;
import org.qinan.safetyeval.infrastructure.dataobject.QualFilingMaterialDO;
import org.qinan.safetyeval.infrastructure.mapper.QualFilingMaterialMapper;
import org.qinan.safetyeval.infrastructure.support.InsertFieldDefaults;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 备案申请材料Gateway实现（Infrastructure层）
 *
 * @author safety-eval
 */
@Component
public class QualFilingMaterialGatewayImpl implements QualFilingMaterialGateway {

    @Resource
    private QualFilingMaterialMapper qualFilingMaterialMapper;

    @Override
    public QualFilingMaterialEntity save(QualFilingMaterialEntity entity) {
        QualFilingMaterialDO dataObject = toDO(entity);
        InsertFieldDefaults.apply(dataObject);
        qualFilingMaterialMapper.insert(dataObject);
        entity.setId(dataObject.getId());
        return entity;
    }

    @Override
    public QualFilingMaterialEntity get(Long id) {
        QualFilingMaterialDO dataObject = qualFilingMaterialMapper.selectById(id);
        return toEntity(dataObject);
    }
@Override
    public List<QualFilingMaterialEntity> listByFilingId(Long filingId) {
        LambdaQueryWrapper<QualFilingMaterialDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(QualFilingMaterialDO::getFilingId, filingId);
        wrapper.eq(QualFilingMaterialDO::getDeleteEnum, "false");
        List<QualFilingMaterialDO> dataObjects = qualFilingMaterialMapper.selectList(wrapper);
        return dataObjects.stream().map(this::toEntity).collect(Collectors.toList());
    }

    @Override
    public QualFilingMaterialEntity modify(QualFilingMaterialEntity entity) {
        QualFilingMaterialDO dataObject = toDO(entity);
        dataObject.setId(entity.getId());
        InsertFieldDefaults.applyForUpdate(dataObject);
        qualFilingMaterialMapper.updateById(dataObject);
        return get(entity.getId());
    }

    @Override
    public void delete(Long id) {
        qualFilingMaterialMapper.deleteById(id);
    }

    @Override
    public PageResult<QualFilingMaterialEntity> page(QualFilingMaterialQuery query) {
        LambdaQueryWrapper<QualFilingMaterialDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(QualFilingMaterialDO::getDeleteEnum, "false");
        if (query.getFilingId() != null) {
            wrapper.eq(QualFilingMaterialDO::getFilingId, query.getFilingId());
        }
        if (StringUtils.hasText(query.getMaterialContent())) {
            wrapper.like(QualFilingMaterialDO::getMaterialContent, query.getMaterialContent());
        }

        Page<QualFilingMaterialDO> page = new Page<>(query.getPageNum(), query.getPageSize());
        IPage<QualFilingMaterialDO> result = qualFilingMaterialMapper.selectPage(page, wrapper);

        List<QualFilingMaterialEntity> entities = result.getRecords().stream()
                .map(this::toEntity)
                .collect(Collectors.toList());

        return PageResult.of(entities, result.getTotal(), result.getCurrent(), result.getSize());
    }

    @Override
    public int countByFilingIdAndUploadStatusCodeAndMaterialType(Long filingId, Integer uploadStatusCode, Integer materialType) {
        LambdaQueryWrapper<QualFilingMaterialDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(QualFilingMaterialDO::getFilingId, filingId);
        wrapper.eq(QualFilingMaterialDO::getDeleteEnum, "false");
        wrapper.eq(QualFilingMaterialDO::getUploadStatusCode, uploadStatusCode);
        wrapper.eq(QualFilingMaterialDO::getMaterialType, materialType);
        return qualFilingMaterialMapper.selectCount(wrapper).intValue();
    }

    private QualFilingMaterialDO toDO(QualFilingMaterialEntity entity) {
        QualFilingMaterialDO dataObject = new QualFilingMaterialDO();
        dataObject.setFilingId(entity.getFilingId());
        dataObject.setMaterialContent(entity.getMaterialContent());
        dataObject.setMaterialFormat(entity.getMaterialFormat());
        dataObject.setSortOrder(entity.getSortOrder());
        dataObject.setRequiredFlag(entity.getRequiredFlag());
        dataObject.setUploadStatusCode(entity.getUploadStatusCode());
        dataObject.setUploadStatusName(entity.getUploadStatusName());
        dataObject.setAttachmentDesc(entity.getAttachmentDesc());
        dataObject.setAttachmentUrl(entity.getAttachmentUrl());
        dataObject.setMaterialRemark(entity.getMaterialRemark());
        dataObject.setMaterialType(entity.getMaterialType());
        dataObject.setTenantId(entity.getTenantId());
        return dataObject;
    }

    private QualFilingMaterialEntity toEntity(QualFilingMaterialDO dataObject) {
        if (dataObject == null) {
            return null;
        }
        QualFilingMaterialEntity entity = new QualFilingMaterialEntity();
        entity.setId(dataObject.getId());
        entity.setFilingId(dataObject.getFilingId());
        entity.setMaterialContent(dataObject.getMaterialContent());
        entity.setMaterialFormat(dataObject.getMaterialFormat());
        entity.setSortOrder(dataObject.getSortOrder());
        entity.setRequiredFlag(dataObject.getRequiredFlag());
        entity.setUploadStatusCode(dataObject.getUploadStatusCode());
        entity.setUploadStatusName(dataObject.getUploadStatusName());
        entity.setAttachmentDesc(dataObject.getAttachmentDesc());
        entity.setAttachmentUrl(dataObject.getAttachmentUrl());
        entity.setMaterialRemark(dataObject.getMaterialRemark());
        entity.setMaterialType(dataObject.getMaterialType());
        entity.setTenantId(dataObject.getTenantId());
        return entity;
    }
}
