package com.clx.performance.service.impl.export;

import com.clx.performance.dao.export.ExportFieldDao;
import com.clx.performance.dao.export.ExportTemplateDao;
import com.clx.performance.dao.export.ExportTemplateFieldDao;
import com.clx.performance.enums.ResultEnum;
import com.clx.performance.model.export.ExportField;
import com.clx.performance.model.export.ExportTemplate;
import com.clx.performance.model.export.ExportTemplateField;
import com.clx.performance.param.pc.export.SaveExportTemplateParam;
import com.clx.performance.service.export.ExportFieldService;
import com.clx.performance.struct.export.ExportFieldStruct;
import com.clx.performance.struct.export.ExportTemplateStruct;
import com.clx.performance.vo.pc.export.ExportFieldVo;
import com.clx.performance.vo.pc.export.ExportTemplateDetailVo;
import com.clx.performance.vo.pc.export.ExportTemplateVo;
import com.msl.common.base.Optional;
import com.msl.common.enums.WhetherEnum;
import com.msl.common.exception.ServiceSystemException;
import com.msl.user.data.UserSessionData;
import com.msl.user.utils.TokenUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.compress.utils.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Comparator;
import java.util.List;
import java.util.Objects;

@Service
public class ExportFieldServiceImpl implements ExportFieldService {

    private static final long TEMPLATE_NUM = 10;
    @Autowired
    private ExportTemplateDao exportTemplateDao;
    @Autowired
    private ExportTemplateFieldDao exportTemplateFieldDao;
    @Autowired
    private ExportFieldDao exportFieldDao;
    @Autowired
    private ExportTemplateStruct exportTemplateStruct;
    @Autowired
    private ExportFieldStruct exportFieldStruct;

    @Override
    public List<ExportTemplateVo> listUserFunctionTemplate(String functionCode) {
        List<ExportTemplateVo> templateVos = exportTemplateStruct.convert(exportTemplateDao.listUserFunctionTemplate(functionCode));
        //将默认模板放置于第一位
        templateVos.sort(Comparator.comparing(ExportTemplateVo::getDefaultFlag).reversed());
        return templateVos;
    }

    @Override
    public List<ExportTemplateVo> listUserFunctionsTemplate(List<String> functionCodes) {
        List<ExportTemplateVo> templateVos = exportTemplateStruct.convert(exportTemplateDao.listUserFunctionsTemplate(functionCodes));
        //将默认模板放置于第一位
        templateVos.sort(Comparator.comparing(ExportTemplateVo::getDefaultFlag).reversed());
        return templateVos;
    }

    @Override
    public Optional<ExportTemplateDetailVo> getTemplateDetail(Integer id) {
        return exportTemplateDao.getEntityByKey(id)
                .mapWithObj(listFieldByTemplate(id), exportTemplateStruct::convert);
    }

    @Override
    public List<ExportFieldVo> listFieldByTemplate(Integer templateId) {
        List<ExportFieldVo> list = exportFieldStruct.convert(exportFieldDao.listFieldByTemplate(templateId));
        return list;
    }

    @Override
    public Integer saveTemplate(SaveExportTemplateParam param) {

        //校验模板数量
        long templateNums = exportTemplateDao.countUserFunctionTemplate(param.getExportFunctionCode());
        if (templateNums >= TEMPLATE_NUM) {
            //模板数量达上限，无法新增
            throw new ServiceSystemException(ResultEnum.TemplateEnum.EXPORT_TEMPLATE_NUM_LIMIT);
        }

        //校验模板名称是否存在
        Optional<ExportTemplate> exists = exportTemplateDao.getUserFunctionTemplateByName(param.getExportFunctionCode(), param.getName());
        if (exists.isPresent()) {
            //模板名称已存在
            throw new ServiceSystemException(ResultEnum.TemplateEnum.EXPORT_TEMPLATE_NAME_EXIST);
        }
        ExportTemplate template = exportTemplateStruct.convert(param);
        exportTemplateDao.saveTemplate(template);
        //保存成功时，查询功能的所有必填字段加入到模板下
        saveTemplateFields(template.getId(), exportFieldDao.listRequiredFieldByFunctionCode(param.getExportFunctionCode()));
        return template.getId();
    }

    @Override
    public void deleteTemplate(Integer id) {
        exportTemplateDao.deleteTemplate(id);
    }

    @Override
    public void updateTemplateName(Integer templateId, String name) {
        //判断模板是否已存在
        ExportTemplate template = exportTemplateDao.getById(templateId).orElseThrow(ResultEnum.TemplateEnum.EXPORT_TEMPLATE_NULL);
        //判断名称是否已存在
        Optional<ExportTemplate> exists = exportTemplateDao.getUserFunctionTemplateByName(template.getExportFunctionCode(), name);
        if (exists.isPresent()) {
            if (!Objects.equals(exists.get().getId(), templateId)) {
                //名称已存在，且为其他模板所用
                throw new ServiceSystemException(ResultEnum.TemplateEnum.EXPORT_TEMPLATE_NAME_EXIST);
            } else {
                //名称已存在且为当前模板时，不需再次修改
                return;
            }
        }
        exportTemplateDao.updateTemplateName(templateId, name);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateTemplateDefaultFlag(Integer templateId) {
        //查询模板数据
        ExportTemplate template = exportTemplateDao.getById(templateId)
                .orElseThrow(() -> new ServiceSystemException(ResultEnum.TemplateEnum.EXPORT_TEMPLATE_NULL));
        //若模板已为默认，则无需修改
        if (WhetherEnum.isTrue(template.getDefaultFlag())) {
            return;
        }
        //去除用户在模板所属功能下已设置过的默认模板
        exportTemplateDao.updateTemplateNotDefault(template.getExportFunctionCode());
        //设置当前模板为默认
        exportTemplateDao.updateTemplateDefault(templateId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateTemplateFields(Integer id, List<Integer> fieldIds) {
        //准备新模板字段数据
        UserSessionData user = TokenUtil.getLoginUserInfo();
        List<ExportTemplateField> templateFields = Lists.newArrayList();
        for (int i = 0; i < fieldIds.size(); i++) {
            ExportTemplateField field = new ExportTemplateField();
            field.setExportTemplateId(id);
            field.setExportFieldId(fieldIds.get(i));
            field.setSort(i);
            templateFields.add(field);
        }

        //删除模板已有字段
        exportTemplateFieldDao.deleteTemplateFields(id);

        //批量增加新字段
        exportTemplateFieldDao.saveBatchList(templateFields);
    }

    @Transactional(rollbackFor = Exception.class)
    public void saveTemplateFields(Integer id, List<ExportField> fields) {
        if (id == null || CollectionUtils.isEmpty(fields)) {
            return;
        }
        //组装待增加字段数据
        List<ExportTemplateField> templateFields = Lists.newArrayList();
        for (int i = 0; i < fields.size(); i++) {
            ExportTemplateField field = new ExportTemplateField();
            field.setExportTemplateId(id);
            field.setExportFieldId(fields.get(i).getId());
            field.setSort(i);
            templateFields.add(field);
        }

        //批量增加新字段
        exportTemplateFieldDao.saveBatchList(templateFields);
    }

    @Override
    public List<ExportFieldVo> listFieldByFunctionCode(String functionCode) {
        return exportFieldStruct.convert(exportFieldDao.listFieldByFunctionCode(functionCode));
    }

}
