package com.jwipc.supplier.logic.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.jwipc.constant.DelFlag;
import com.jwipc.constant.EnableStatus;
import com.jwipc.page.PageUtil;
import com.jwipc.page.PageView;
import com.jwipc.security.LoginUtil;
import com.jwipc.supplier.constant.TemplateFiledType;
import com.jwipc.supplier.convert.SupplierTemplateConvert;
import com.jwipc.supplier.convert.SupplierTemplateFieldConvert;
import com.jwipc.supplier.dto.*;
import com.jwipc.supplier.entity.SupplierTemplate;
import com.jwipc.supplier.entity.SupplierTemplateField;
import com.jwipc.supplier.entity.SupplierTemplateFieldRelation;
import com.jwipc.supplier.entity.SupplierTemplateQuestionnaireRelation;
import com.jwipc.supplier.logic.SupplierTemplateLogic;
import com.jwipc.supplier.model.po.FieldDictPO;
import com.jwipc.supplier.model.po.SupplierTemplateFieldPO;
import com.jwipc.supplier.model.query.SupplierTemplateQuery;
import com.jwipc.supplier.service.ISupplierTemplateFieldRelationService;
import com.jwipc.supplier.service.ISupplierTemplateFieldService;
import com.jwipc.supplier.service.ISupplierTemplateQuestionnaireRelationService;
import com.jwipc.supplier.service.ISupplierTemplateService;
import com.jwipc.sys.client.UserClient;
import com.jwipc.sys.client.dto.UserDTO;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;


/**
 * <p> </p>
 *
 * @author BOGON
 * @version 1.0
 * @since JDK 1.8
 */
@Service
@RequiredArgsConstructor
public class SupplierTemplateLogicImpl implements SupplierTemplateLogic {
    private final ISupplierTemplateService supplierTemplateService;
    private final ISupplierTemplateFieldRelationService supplierTemplateFieldRelationService;
    private final SupplierTemplateConvert supplierTemplateConvert;
    private final SupplierTemplateFieldConvert supplierTemplateFieldConvert;
    private final UserClient userClient;
    private final ISupplierTemplateFieldService supplierTemplateFieldService;
    private final ISupplierTemplateQuestionnaireRelationService questionnaireRelationService;


    @Override
    public PageView getList(SupplierTemplateQuery query) {
        final LambdaQueryWrapper<SupplierTemplate> queryWrapper = new LambdaQueryWrapper<SupplierTemplate>()
                .like(StrUtil.isNotEmpty(query.getName()), SupplierTemplate::getTemplateName, query.getName())
                .like(StrUtil.isNotEmpty(query.getCode()), SupplierTemplate::getTemplateCode, query.getCode());
        final Page<SupplierTemplate> page = PageUtil.toPage(query);
        final List<SupplierTemplate> list = supplierTemplateService.list(page, queryWrapper);
        List<SupplierTemplateBaseDTO> moduleTemplateBaseDTOS = supplierTemplateConvert.entities2Dtos(list);
        final List<Long> userIds = moduleTemplateBaseDTOS.stream().filter(a -> Objects.nonNull(a.getCreateId()))
                .map(a -> a.getCreateId()).collect(Collectors.toSet()).stream().toList();
        Map<Long, String> userMap = Maps.newHashMap();
        if (CollUtil.isNotEmpty(userIds)) {
            final List<UserDTO> byUserIds = userClient.getByUserIds(userIds);
            userMap = byUserIds.stream()
                    .collect(Collectors.toMap(a -> a.getId(), a -> a.getUsername()));
        }
        for (SupplierTemplateBaseDTO moduleTemplateBaseDTO : moduleTemplateBaseDTOS) {
            if (Objects.nonNull(moduleTemplateBaseDTO.getCreateId())) {
                moduleTemplateBaseDTO.setCreateName(userMap.get(moduleTemplateBaseDTO.getCreateId()));
            }
        }
        return PageUtil.getPV(moduleTemplateBaseDTOS, page.getTotal());
    }

    @Override
    public SupplierTemplateBaseDTO getDetail(Long id) {
        final SupplierTemplate supplierTemplate = supplierTemplateService.getById(id);
        final SupplierTemplateBaseDTO supplierTemplateBaseDTO;
        if (Objects.nonNull(supplierTemplate)) {
            supplierTemplateBaseDTO = supplierTemplateConvert.entity2Dto(supplierTemplate);
        } else {
            supplierTemplateBaseDTO = new SupplierTemplateBaseDTO();
        }
        return supplierTemplateBaseDTO;
    }

    @Override
    public SupplierTemplateFieldsDTO getField(Long templateId) {
        final SupplierTemplate supplierTemplate = supplierTemplateService.getById(templateId);
        final SupplierTemplateBaseDTO supplierTemplateBaseDTO = supplierTemplateConvert.entity2Dto(supplierTemplate);
        SupplierTemplateFieldsDTO supplierTemplateFieldsDTO = new SupplierTemplateFieldsDTO();
        supplierTemplateFieldsDTO.setTemplate(supplierTemplateBaseDTO);
        List<SupplierTemplateFieldPO> moduleTemplateFieldFormMapList =
                supplierTemplateFieldRelationService.selectByTemplate(
                        String.valueOf(templateId),
                        DelFlag.NORMAL.getStatus());
        for (SupplierTemplateFieldPO e : moduleTemplateFieldFormMapList) {
            if (e.getFormControl() == TemplateFiledType.DICT.getType()) {
                final String sqlSentence = e.getSqlSentence();
                if (StringUtils.isNotEmpty(sqlSentence)) {
                    List<FieldDictPO> map = supplierTemplateFieldRelationService.selectDataBySql(sqlSentence);
                    e.setData(JSON.toJSONString(map));
                    e.setFieldLength(map.size());
                }
            }
        }
        List<SupplierTemplateFieldDTO> templateTextFieldList = supplierTemplateFieldConvert.pos2Dtos(
                moduleTemplateFieldFormMapList);
        supplierTemplateFieldsDTO.setFieldList(templateTextFieldList);
        return supplierTemplateFieldsDTO;
    }

    @Override
    public PageView getFieldsListAll() {
        final List<SupplierTemplateField> list = supplierTemplateFieldService.list();
        List<SupplierTemplateFieldBaseDTO> fieldBaseDTOS = supplierTemplateFieldConvert.entities2Dtos(list);
        return PageUtil.getPV(fieldBaseDTOS, fieldBaseDTOS.size());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveOrUpdate(SupplierTemplateSaveDTO supplierTemplateSaveDTO) {
        final Long id = supplierTemplateSaveDTO.getId();
        SupplierTemplate supplierTemplate = supplierTemplateConvert.dto2Entity(supplierTemplateSaveDTO);
        final Long userId = LoginUtil.getUserId();
        if (Objects.nonNull(id) && supplierTemplateSaveDTO.getCopyFlag() == 1) {
            supplierTemplate.setCreateId(userId);
            supplierTemplate.setCreateTime(LocalDateTime.now());
            supplierTemplate.setId(null);
        } else if (Objects.nonNull(id)) {
            //编辑
            supplierTemplateFieldRelationService.remove(new LambdaQueryWrapper<SupplierTemplateFieldRelation>().eq(
                    SupplierTemplateFieldRelation::getTemplateId, id));
            questionnaireRelationService.remove(new LambdaQueryWrapper<SupplierTemplateQuestionnaireRelation>().eq(
                    SupplierTemplateQuestionnaireRelation::getTemplateId, id));
            supplierTemplate.setUpdateId(userId);
            supplierTemplate.setUpdateTime(LocalDateTime.now());
        } else {
            supplierTemplate.setCreateId(userId);
            supplierTemplate.setCreateTime(LocalDateTime.now());
        }
        supplierTemplateService.saveOrUpdate(supplierTemplate);
        //保存字段的关联信息
        final List<SupplierTemplateFieldDTO> fields = supplierTemplateSaveDTO.getFields();
        List<SupplierTemplateFieldRelation> fieldRelations = supplierTemplateFieldConvert.dtos2entities(fields);
        if (CollUtil.isNotEmpty(fieldRelations)) {
            fieldRelations.forEach(a -> {
                a.setTemplateId(supplierTemplate.getId());
                a.setCreateId(userId);
                a.setEditFlag(EnableStatus.ENABLE.getStatus());
                a.setCreateTime(LocalDateTime.now());
            });
            supplierTemplateFieldRelationService.saveBatch(fieldRelations);
        }
        //需要查询是否有问卷调查
        if (supplierTemplate.getEnableQuestionnaire() != null && supplierTemplate.getEnableQuestionnaire() == EnableStatus.DISABLE.getStatus()) {
            //如果不启用需要删除关联
            questionnaireRelationService.remove(new LambdaQueryWrapper<SupplierTemplateQuestionnaireRelation>().eq(
                    SupplierTemplateQuestionnaireRelation::getTemplateId, supplierTemplate.getId()));
        } else {
            final Set<Long> questionnaireList = supplierTemplateSaveDTO.getQuestionnaireList();
            List<SupplierTemplateQuestionnaireRelation> insertList = Lists.newArrayList();
            for (Long i : questionnaireList) {
                SupplierTemplateQuestionnaireRelation supplierTemplateQuestionnaireRelation =
                        new SupplierTemplateQuestionnaireRelation();
                supplierTemplateQuestionnaireRelation.setTemplateId(supplierTemplate.getId());
                supplierTemplateQuestionnaireRelation.setQuestionnaireId(i);
                insertList.add(supplierTemplateQuestionnaireRelation);
            }
            if (CollUtil.isNotEmpty(insertList)) {
                questionnaireRelationService.saveBatch(insertList);
            }
        }

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void remove(Long id) {
        /**
         * 删除模板表 t_supplier_template
         * 删除模板字段关联表 t_supplier_template_field_relation
         * 删除模板问卷关联表 t_supplier_template_questionnaire_relation
         */
        supplierTemplateService.removeById(id);
        supplierTemplateFieldRelationService.remove(
                new LambdaQueryWrapper<SupplierTemplateFieldRelation>()
                        .eq(SupplierTemplateFieldRelation::getTemplateId,
                                id));
        questionnaireRelationService.remove(new LambdaQueryWrapper<SupplierTemplateQuestionnaireRelation>()
                .eq(SupplierTemplateQuestionnaireRelation::getTemplateId,
                        id));
    }

    @Override
    public List<SupplierTemplateBaseDTO> getListAll() {
        final List<SupplierTemplate> list = supplierTemplateService.list();
        List<SupplierTemplateBaseDTO> moduleTemplateBaseDTOS = supplierTemplateConvert.entities2Dtos(list);
        return moduleTemplateBaseDTOS;
    }
}