package com.njcn.gather.pqdif.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.njcn.common.pojo.constant.PatternRegex;
import com.njcn.common.pojo.enums.common.DataStateEnum;
import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.gather.pojo.constant.DetectionValidMessage;
import com.njcn.gather.pqdif.mapper.PqPqdifPathMapper;
import com.njcn.gather.pqdif.pojo.enums.PqdifResponseEnum;
import com.njcn.gather.pqdif.pojo.param.PqPqdifPathParam;
import com.njcn.gather.pqdif.pojo.po.PqPqdifPath;
import com.njcn.gather.pqdif.service.IPqPqdifPathService;
import com.njcn.web.factory.PageFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Slf4j
@Service
public class PqPqdifPathServiceImpl extends ServiceImpl<PqPqdifPathMapper, PqPqdifPath> implements IPqPqdifPathService {

    @Override
    public List<PqPqdifPath> listAll() {
        return this.lambdaQuery()
                .select(PqPqdifPath::getId, PqPqdifPath::getName)
                .eq(PqPqdifPath::getState, DataStateEnum.ENABLE.getCode())
                .orderByDesc(PqPqdifPath::getCreateTime)
                .list();
    }

    @Override
    public Page<PqPqdifPath> listPqdif(PqPqdifPathParam.QueryParam param) {
        Page<PqPqdifPath> page = new Page<>(PageFactory.getPageNum(param), PageFactory.getPageSize(param));
        page.setRecords(this.baseMapper.selectPageList(page, StrUtil.trim(param.getName()), param.getResult()));
        return page;
    }

    @Override
    @Transactional
    public boolean importPqdif(List<PqPqdifPathParam.ImportItem> items) {
        if (CollUtil.isEmpty(items)) {
            return true;
        }
        validateItems(items);
        for (PqPqdifPathParam.ImportItem item : items) {
            PqPqdifPath entity = toEntity(item);
            boolean saved = this.saveOrUpdate(entity);
            if (!saved) {
                throw new BusinessException(PqdifResponseEnum.IMPORT_FAILED);
            }
        }
        return true;
    }

    private void validateItems(List<PqPqdifPathParam.ImportItem> items) {
        Set<String> ids = new HashSet<>();
        for (PqPqdifPathParam.ImportItem item : items) {
            if (item == null) {
                throw new BusinessException(PqdifResponseEnum.IMPORT_ITEM_NOT_NULL);
            }
            String id = StrUtil.trim(item.getId());
            if (StrUtil.isBlank(id)) {
                throw new BusinessException(DetectionValidMessage.ID_NOT_BLANK);
            }
            if (!ReUtil.isMatch(PatternRegex.SYSTEM_ID, id)) {
                throw new BusinessException(DetectionValidMessage.ID_FORMAT_ERROR);
            }
            if (!ids.add(id)) {
                throw new BusinessException(PqdifResponseEnum.IMPORT_ID_REPEAT);
            }
            if (StrUtil.isBlank(item.getName())) {
                throw new BusinessException(DetectionValidMessage.NAME_NOT_BLANK);
            }
        }
    }

    private PqPqdifPath toEntity(PqPqdifPathParam.ImportItem item) {
        PqPqdifPath entity = new PqPqdifPath();
        entity.setId(StrUtil.trim(item.getId()));
        entity.setName(StrUtil.trim(item.getName()));
        entity.setFilePath(StrUtil.trim(item.getFilePath()));
        entity.setRecordCount(item.getRecordCount());
        entity.setObservationCount(item.getObservationCount());
        entity.setSampleValueCount(item.getSampleValueCount());
        entity.setResult(item.getResult());
        entity.setMsg(item.getMsg());
        entity.setState(item.getState() == null ? DataStateEnum.ENABLE.getCode() : item.getState());
        entity.setCreateBy(StrUtil.trim(item.getCreateBy()));
        entity.setUpdateBy(StrUtil.trim(item.getUpdateBy()));
        entity.setCreateTime(parseDateTime(item.getCreateTime()));
        entity.setUpdateTime(parseDateTime(item.getUpdateTime()));
        return entity;
    }

    private LocalDateTime parseDateTime(String value) {
        if (StrUtil.isBlank(value)) {
            return null;
        }
        try {
            return LocalDateTime.parse(StrUtil.trim(value));
        } catch (Exception ex) {
            throw new BusinessException(PqdifResponseEnum.JSON_FORMAT_ERROR);
        }
    }
}
