package {{packageName}}.core.{{entity.module}}.service.impl;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.Map;
import java.util.HashSet;
import java.util.HashMap;
import java.util.Collection;
import java.util.Objects;
import java.util.Optional;
import java.math.BigInteger;
import lombok.extern.slf4j.Slf4j;

import cn.ibizlab.util.security.SpringContextHolder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cglib.beans.BeanCopier;
import org.springframework.stereotype.Service;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.util.Assert;
import org.springframework.beans.factory.annotation.Value;
import cn.ibizlab.util.errors.BadRequestAlertException;
{{#system.enableGlobalTransaction}}
import io.seata.spring.annotation.GlobalTransactional;
{{/system.enableGlobalTransaction}}
import org.springframework.transaction.annotation.Transactional;
import org.springframework.context.annotation.Lazy;
import {{packageName}}.core.{{entity.module}}.domain.{{entity.codeName}};
import {{packageName}}.core.{{entity.module}}.filter.{{entity.codeName}}SearchContext;
import {{packageName}}.core.{{entity.module}}.service.I{{entity.codeName}}Service;
import cn.ibizlab.util.helper.CachedBeanCopier;
import cn.ibizlab.util.helper.DEFieldCacheMap;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.core.conditions.Wrapper;


/**
 * 实体[{{entity.logicName}}] 服务对象接口实现
 */
@Slf4j
@Service("{{entity.codeName}}ServiceImpl")
public class {{entity.codeName}}ServiceImpl implements I{{entity.codeName}}Service {

    protected I{{entity.codeName}}Service {{camelCase entity.codeName}}Service = SpringContextHolder.getBean(this.getClass());

    {{#entity.relEntities}}
    {{#neq storage "NONE"}}
    @Autowired
    @Lazy
    protected {{packageName}}.core.{{module}}.service.I{{codeName}}Service {{camelCase codeName}}Service;
   
    {{/neq}}
    {{/entity.relEntities}}
    {{#if entity.indexSubDE}}
    @Autowired
    @Lazy
    protected {{packageName}}.core.{{entity.module}}.mapping.{{entity.codeName}}InheritMapping {{camelCase entity.codeName}}InheritMapping;
    {{/if}}

    protected int batchSize = 500;

    public {{entity.codeName}} get({{entity.codeName}} et) {

        return et;
    }
    
    public List<{{entity.codeName}}> getByEntities(List<{{entity.codeName}}> entities) {
        return null;
    }

    {{#entity.hasReferences}}
    public void fillParentData({{entity.codeName}} et) {
        
    }
    {{/entity.hasReferences}}

    public {{entity.codeName}} getDraft({{entity.codeName}} et) {
        {{#entity.hasReferences}}
        fillParentData(et);
        {{/entity.hasReferences}}
        return et;
    }

    public boolean checkKey({{entity.codeName}} et) {
        return false;
    }

    @Override
    {{#eq entity.actions.create.transactionMode "GLOBAL"}}@GlobalTransactional{{/eq}}{{#eq entity.actions.create.transactionMode "DEFAULT"}}@Transactional{{/eq}}
    public boolean create({{entity.codeName}} et) {
        return true;
    }
    {{#eq entity.actions.create.transactionMode "GLOBAL"}}@GlobalTransactional{{/eq}}{{#eq entity.actions.create.transactionMode "DEFAULT"}}@Transactional{{/eq}}
    public boolean createBatch(List<{{entity.codeName}}> list) {
        return true;
    }

    {{#eq entity.actions.update.transactionMode "GLOBAL"}}@GlobalTransactional{{/eq}}{{#eq entity.actions.update.transactionMode "DEFAULT"}}@Transactional{{/eq}}
    public boolean update({{entity.codeName}} et) {
        {{#entity.hasReferences}}
        fillParentData(et);
        {{/entity.hasReferences}}
        return true;
    }

    {{#eq entity.actions.update.transactionMode "GLOBAL"}}@GlobalTransactional{{/eq}}{{#eq entity.actions.update.transactionMode "DEFAULT"}}@Transactional{{/eq}}
    public boolean updateBatch(List<{{entity.codeName}}> list) {
        return true;
    }

    {{#eq entity.actions.save.transactionMode "GLOBAL"}}@GlobalTransactional{{/eq}}{{#eq entity.actions.save.transactionMode "DEFAULT"}}@Transactional{{/eq}}
    public boolean save({{entity.codeName}} et) {
        if(checkKey(et))
            return {{camelCase entity.codeName}}Service.update(et);
        else
            return {{camelCase entity.codeName}}Service.create(et);
    }

    {{#eq entity.actions.save.transactionMode "GLOBAL"}}@GlobalTransactional{{/eq}}{{#eq entity.actions.save.transactionMode "DEFAULT"}}@Transactional{{/eq}}
    public boolean saveBatch(List<{{entity.codeName}}> list) {
        List<{{entity.codeName}}> rt=this.getByEntities(list);
        Set<Serializable> keys=new HashSet<>();
        rt.forEach(et->{
            Serializable key = et.get{{pascalCase entity.keyField.codeName}}();
            if(!ObjectUtils.isEmpty(key))
                keys.add(key);
        });
        List<{{entity.codeName}}> _create=new ArrayList<>();
        List<{{entity.codeName}}> _update=new ArrayList<>();
        list.forEach(et-> {
            Serializable key = et.get{{pascalCase entity.keyField.codeName}}();
            if(keys.contains(key))
                _update.add(et);
            else
                _create.add(et);
        });
        List rtList=new ArrayList<>();
        if(_update.size()>0 && (!{{camelCase entity.codeName}}Service.updateBatch(_update)))
            return false;
        if(_create.size()>0 && (!{{camelCase entity.codeName}}Service.createBatch(_create)))
            return false;
        return true;
    }

    {{#eq entity.actions.remove.transactionMode "GLOBAL"}}@GlobalTransactional{{/eq}}{{#eq entity.actions.remove.transactionMode "DEFAULT"}}@Transactional{{/eq}}
    public boolean remove({{entity.codeName}} et) {

        return false ;
    }
    
    {{#eq entity.actions.remove.transactionMode "GLOBAL"}}@GlobalTransactional{{/eq}}{{#eq entity.actions.remove.transactionMode "DEFAULT"}}@Transactional{{/eq}}
    public boolean removeBatch(Collection<{{entity.keyField.type.java}}> ids) {

        return false;
    }

    {{#entity.extActions}}
    {{#eq transactionMode "GLOBAL"}}@GlobalTransactional{{/eq}}{{#eq transactionMode "DEFAULT"}}@Transactional{{/eq}}
    public {{entity.codeName}} {{camelCase codeName}}({{entity.codeName}} et) {
        return et;
    }
    {{#eq transactionMode "GLOBAL"}}@GlobalTransactional{{/eq}}{{#eq transactionMode "DEFAULT"}}@Transactional{{/eq}}
    public boolean {{camelCase codeName}}Batch(List<{{entity.codeName}}> list) {
        return false;
    }

    {{/entity.extActions}}
    {{#entity.dataSets}}
    public Page<{{#if enableGroup}}Map{{else}}{{entity.codeName}}{{/if}}> search{{pascalCase codeName}}({{entity.codeName}}SearchContext context) {
        return null;
    }
    public List<{{#if enableGroup}}Map{{else}}{{entity.codeName}}{{/if}}> list{{pascalCase codeName}}({{entity.codeName}}SearchContext context) {
        return null;
    }

    {{/entity.dataSets}}
    {{#entity.references}}
    public List<{{entity.codeName}}> selectBy{{pascalCase fkField.codeName}}({{fkField.type.java}} {{camelCase fkField.codeName}}) {
        return null;
    }

    public boolean removeBy{{pascalCase fkField.codeName}}({{fkField.type.java}} {{camelCase fkField.codeName}}) {
        return false;
    }

    public boolean resetBy{{pascalCase fkField.codeName}}({{fkField.type.java}} {{camelCase fkField.codeName}}) {
        return false;
    }

    public boolean saveBy{{pascalCase fkField.codeName}}({{fkField.type.java}} {{camelCase fkField.codeName}},List<{{entity.codeName}}> list) {

        return false;
    }

    {{/entity.references}}

}