package com.ssyf.module.custom.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ssyf.common.core.util.AssertUtil;
import com.ssyf.common.core.util.EntityUtil;
import com.ssyf.common.web.apicode.ApiCodeUser;
import com.ssyf.common.web.error.ServiceRuntimeException;
import com.ssyf.module.custom.domain.entity.CustomField;
import com.ssyf.module.custom.domain.query.CustomFieldQuery;
import com.ssyf.module.custom.service.CustomDataService;
import com.ssyf.module.custom.service.CustomFieldService;
import com.ssyf.module.custom.mapper.CustomFieldMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
* @author admin
* @description 针对表【custom_field(自定义表字段)】的数据库操作Service实现
* @createDate 2024-08-13 09:29:55
*/
@Service
public class CustomFieldServiceImpl extends ServiceImpl<CustomFieldMapper, CustomField> implements CustomFieldService {

    /**
     * 字段数量最大个数
     */
    private static final int FIELD_NUMBER_MAX = 19;
    /**
     * 字段名称前缀
     */
    static final String FIELD_NAME_PREFIX = "field";

    @Lazy
    @Autowired
    private CustomDataService customDataService;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public CustomField addOne(String tableUid, CustomFieldQuery query) {
        List<CustomField> customFields = addBatch(tableUid ,Arrays.asList(query));
        return customFields.get(0);
    }

    @Override
    public List<CustomField> addBatch(String tableUid, List<CustomFieldQuery> queries) {
        List<CustomField> customFields = this.getAll(tableUid ,new CustomFieldQuery());
        List<String> fieldNames = EntityUtil.extractProperty(customFields ,CustomField::getMapCustomDataField);
        Set<String> availableFieldName = getAvailableFieldName(fieldNames);
        if(CollectionUtil.isEmpty(availableFieldName) || queries.size() > availableFieldName.size()){
            throw ServiceRuntimeException.instance(ApiCodeUser.PARAMETER_ERROR.getCode() ,"不能新增：超出字段限制");
        }
        List<CustomField> customFieldList = new ArrayList<>();
        Iterator<String> iterator = availableFieldName.iterator();
        for(CustomFieldQuery query : queries){
            CustomField customField = BeanUtil.toBean(query , CustomField.class);
            customField.setTableUid(tableUid).setUid(IdUtil.simpleUUID());
            //设置对应关系
            customField.setMapCustomDataField(iterator.next());

            customFieldList.add(customField);
        }
        saveBatch(customFieldList);
        return customFieldList;
    }

    @Override
    public void updateByUid(String uid, CustomFieldQuery query) {
        CustomField customField = this.getByUid(uid);
        AssertUtil.isNotNull(customField ,ServiceRuntimeException.instance(ApiCodeUser.PARAMETER_ERROR.getCode() ,"数据不存在"));

        //不能更新uid，和tableUid
        query.setUid(null).setTableUid(null);
        CustomField update = BeanUtil.toBean(query ,CustomField.class);
        update.setId(customField.getId());
        updateById(update);
    }

    /**
     * 删除字段；
     * 1. 删除字段
     * 2. 删除字段映射数据表字段的内容，为后续新增字段预留映射字段和清理数据
     * @param uid
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void removeByUid(String uid) {
        CustomField customField = this.getByUid(uid);
        AssertUtil.isNotNull(customField ,ServiceRuntimeException.instance(ApiCodeUser.PARAMETER_ERROR.getCode() ,"数据不存在"));

        removeById(customField);

        //映射字段
        String mapCustomDataField = customField.getMapCustomDataField();
        this.customDataService.cleanDataOfFieldName(mapCustomDataField);
    }

    @Override
    public CustomField getByUid(String uid) {
        return getOne(new LambdaQueryWrapper<CustomField>().eq(CustomField::getUid , uid));
    }

    @Override
    public PageInfo<CustomField> getPage(String tableUid, CustomFieldQuery query) {
        PageHelper.startPage(query.getPageNum() ,query.getPageSize());
        return PageInfo.of(getAll(tableUid ,query));
    }

    @Override
    public List<CustomField> getAll(String tableUid, CustomFieldQuery query) {
        return list(this.createWrapper(tableUid ,query));
    }

    /**
     * 获取可用的字段名
     * @param oldFieldNameList
     * @return
     */
    private Set<String> getAvailableFieldName(List<String> oldFieldNameList) {
        Set<String> allSet = new HashSet<>();
        for (int i = 0; i < FIELD_NUMBER_MAX; i++) {
            allSet.add(FIELD_NAME_PREFIX + i);
        }
        if(CollectionUtil.isNotEmpty(oldFieldNameList)){
            allSet.removeAll(oldFieldNameList);
        }
        return allSet;
    }

    private LambdaQueryWrapper<CustomField> createWrapper(String tableUid,CustomFieldQuery query) {
        query = query == null ? new CustomFieldQuery() : query;
        LambdaQueryWrapper<CustomField> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CustomField::getTableUid ,tableUid);
        queryWrapper.like(StrUtil.isNotBlank(query.getUid()),CustomField::getUid ,query.getUid());
        queryWrapper.like(StrUtil.isNotBlank(query.getZhName()),CustomField::getZhName ,query.getZhName());
        queryWrapper.like(StrUtil.isNotBlank(query.getEnName()),CustomField::getEnName ,query.getEnName());
        //排序
        queryWrapper.orderByDesc(CustomField::getOrderSortPriority);
        return queryWrapper;
    }
}




