package com.ruoyi.custclient.service.impl;

import com.alibaba.nacos.shaded.com.google.common.collect.Lists;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.custclient.dto.QueryLabelCodeDto;
import com.ruoyi.custclient.dto.QueryLabelTypeDto;
import com.ruoyi.custclient.dto.SaveLabelDto;
import com.ruoyi.custclient.service.ILabelCodeService;
import com.ruoyi.custclient.service.ILabelTypeService;
import com.ruoyi.custclient.service.LabelService;
import com.ruoyi.custclient.vo.PageLabelCodeVo;
import com.ruoyi.custclient.vo.PageLabelTypeVO;
import com.ruoyi.system.domain.LabelCode;
import com.ruoyi.system.domain.LabelType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

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

@Service
public class LabelServiceImpl implements LabelService {

    @Autowired
    private ILabelTypeService labelTypeService;

    @Autowired
    private ILabelCodeService labelCodeService;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean saveLabel(SaveLabelDto dto) {
        List<LabelCode> labelCodeList = dto.getLabelCodeList();
        if (CollectionUtils.isEmpty(labelCodeList)) {
            throw new ServiceException("至少要拥有一个标签!");
        }
        LambdaQueryWrapper<LabelType> typeQw = new LambdaQueryWrapper<>();
        typeQw.eq(LabelType::getName, dto.getLabelType().getName());
        long count = labelTypeService.count(typeQw);
        if (count > 0) {
            throw new ServiceException("该标签已经存在!(名称重复)");
        }
        boolean save = this.labelTypeService.save(dto.getLabelType());
        if (save) {
            Long labelTypeId = dto.getLabelType().getId();
            for (LabelCode labelCode : labelCodeList) {
                labelCode.setLabelTypeId(labelTypeId);
            }
            return labelCodeService.saveBatch(labelCodeList);
        }
        return false;
    }

    @Override
    public Page<PageLabelCodeVo> getLabelCodeInPage(QueryLabelCodeDto dto) {
        Page page = new Page<>(dto.getPageNum(), dto.getPageSize());
        LambdaQueryWrapper<LabelCode> qw = new LambdaQueryWrapper<>();
        qw.like(StringUtils.isNotEmpty(dto.getName()), LabelCode::getName, dto.getName());
        qw.eq(dto.getLabelTypeId() != null, LabelCode::getLabelTypeId, dto.getLabelTypeId());
        Page pageInfo = this.labelCodeService.page(page, qw);
        List<LabelCode> records = pageInfo.getRecords();
        List<PageLabelCodeVo> vos = Lists.newArrayList();
        Page<PageLabelCodeVo> pageVo = new Page<>(pageInfo.getCurrent(), pageInfo.getSize(), pageInfo.getTotal());
        if (!CollectionUtils.isEmpty(records)) {
            List<LabelType> labelTypes = labelTypeService.list();
            for (LabelCode record : records) {
                PageLabelCodeVo codeVo = new PageLabelCodeVo();
                codeVo.setId(record.getId()).setLabelTypeId(record.getLabelTypeId())
                        .setName(record.getName()).setAutomatic(record.getAutomatic());
                for (LabelType labelType : labelTypes) {
                    if (codeVo.getLabelTypeId().equals(labelType.getId())) {
                        codeVo.setLabelTypeName(labelType.getName());
                        break;
                    }
                }
                vos.add(codeVo);
            }
        }
        pageVo.setRecords(vos);
        return pageVo;
    }

    @Override
    public List<LabelCode> getLabelCodeList() {
        return this.labelCodeService.list();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public List<PageLabelTypeVO> getLabelTypeInPage(QueryLabelTypeDto dto) {
        LambdaQueryWrapper<LabelType> qw = new LambdaQueryWrapper<>();
        qw.like(StringUtils.isNotEmpty(dto.getName()), LabelType::getName, dto.getName());
        qw.orderByDesc(LabelType::getCreateTime);
        List<LabelType> labelTypes = this.labelTypeService.list(qw);
        List<PageLabelTypeVO> vos = Lists.newArrayList();

        if (!CollectionUtils.isEmpty(labelTypes)) {
            List<LabelCode> labelCodeList = labelCodeService.list();
            if (!CollectionUtils.isEmpty(labelCodeList)) {
                for (LabelType labelType : labelTypes) {
                    PageLabelTypeVO labelTypeVO = new PageLabelTypeVO();
                    labelTypeVO.setRule(labelType.getRule()).setId(labelType.getId()).setName(labelType.getName());
                    List<String> codeNames = labelCodeList.stream()
                            .filter(labelCode -> labelCode.getLabelTypeId().equals(labelType.getId()))
                            .map(LabelCode::getName)
                            .collect(Collectors.toList());
                    labelTypeVO.setLabelCodeNames(String.join(",", codeNames));
                    vos.add(labelTypeVO);
                }
                return vos;
            }
        }
        return vos;
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean removeLabelTypeById(Long labelTypeId) {
        boolean remove = this.labelTypeService.removeById(labelTypeId);
        if (remove) {
            LambdaQueryWrapper<LabelCode> qw = new LambdaQueryWrapper<>();
            qw.eq(LabelCode::getLabelTypeId, labelTypeId);
            return this.labelCodeService.remove(qw);
        }
        return false;
    }
}

