package cn.ibizlab.core.data.service.impl;

import cn.ibizlab.core.data.domain.DOModel;
import cn.ibizlab.core.data.domain.DOModel;
import cn.ibizlab.core.data.dto.*;
import cn.ibizlab.core.data.filter.DOModelSearchContext;
import cn.ibizlab.core.data.mapper.DbDataMapper;
import cn.ibizlab.core.data.model.POSchema;
import cn.ibizlab.core.data.model.PojoSchema;
import cn.ibizlab.core.data.service.IDOModelService;
import cn.ibizlab.core.data.service.IDataService;
import cn.ibizlab.core.data.service.ModelService;
import cn.ibizlab.util.errors.BadRequestAlertException;
import cn.ibizlab.util.filter.SearchContextBase;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * 实体[业务实体] 无存储服务对象接口实现
 */
@Slf4j
@Service
public class DbDataServiceImpl implements IDataService {


    @Autowired
    private DbDataMapper dbDataMapper;

    @Override
    public ResponseData call(DOModel model, String scope, String datasource, String method, RequestData requestData)
    {
        return null;
    }

    @Override
    public boolean create(DOModel model, String scope, String datasource, BaseData et)
    {
        Serializable key=model.getKeyValue(et,true);
        if(ObjectUtils.isEmpty(key))
            throw new BadRequestAlertException("未找到主键",model.getName(),null);
        if(dbDataMapper.insertData(model.getPOSchema(datasource),et)==1)
            et.setAll(get(model,scope,datasource,key));
        return true;
    }

    @Override
    public void createBatch(DOModel model, String scope, String datasource, List<BaseData> list)
    {

    }

    @Override
    public boolean update(DOModel model, String scope, String datasource, BaseData et)
    {
        Serializable key=model.getKeyValue(et,false);
        if(ObjectUtils.isEmpty(key))
            throw new BadRequestAlertException("未找到主键",model.getName(),null);
        dbDataMapper.updateData(model.getPOSchema(datasource),et);
        et.setAll(get(model,scope,datasource,(Serializable)key));
        return true;
    }

    @Override
    public void updateBatch(DOModel model, String scope, String datasource, List<BaseData> list)
    {

    }

    @Override
    public boolean remove(DOModel model, String scope, String datasource, Serializable key)
    {
        if(ObjectUtils.isEmpty(key))
            throw new BadRequestAlertException("未找到主键",model.getName(),null);
        BaseData et = model.newData(key);
        if(et==null)
            throw new BadRequestAlertException("未找到主键",model.getName(),null);
        dbDataMapper.removeData(model.getPOSchema(datasource),et);
        return true;
    }

    @Override
    public void removeBatch(DOModel model, String scope, String datasource, List<Serializable> idList)
    {

    }

    @Override
    public boolean removeByMap(DOModel model, String scope, String datasource, BaseData et)
    {
        Serializable key=model.getKeyValue(et,false);
        if(ObjectUtils.isEmpty(key))
            throw new BadRequestAlertException("未找到主键",model.getName(),null);
        POSchema poSchema=model.getPOSchema(datasource);
        dbDataMapper.removeData(poSchema,et);
        return true;
    }

    @Override
    public BaseData get(DOModel model, String scope, String datasource, Serializable key)
    {
        if(ObjectUtils.isEmpty(key))
            throw new BadRequestAlertException("未找到主键",model.getName(),null);
        BaseData et = model.newData(key);
        if(et==null)
            throw new BadRequestAlertException("未找到主键",model.getName(),null);
        POSchema poSchema=model.getPOSchema(datasource);
        List<BaseData> list=dbDataMapper.getData(poSchema,et);
        if(ObjectUtils.isEmpty(list)||list.size()>1)
            throw new BadRequestAlertException("未找到数据",model.getName(),key.toString());
        return poSchema.trans(list.get(0));
    }

    @Override
    public List<BaseData> getBatch(DOModel model, String scope, String datasource, List<Serializable> idList)
    {
        return null;
    }

    @Override
    public BaseData getByMap(DOModel model, String scope, String datasource, BaseData et)
    {
        Serializable key=model.getKeyValue(et,false);
        if(ObjectUtils.isEmpty(key))
            throw new BadRequestAlertException("未找到主键",model.getName(),null);
        POSchema poSchema=model.getPOSchema(datasource);
        List<BaseData> list=dbDataMapper.getData(poSchema,et);
        if(ObjectUtils.isEmpty(list)||list.size()>1)
            throw new BadRequestAlertException("未找到数据",model.getName(),key.toString());
        return poSchema.trans(list.get(0));
    }

    @Override
    public BaseData getDraft(DOModel model, String scope, String datasource, BaseData et)
    {
        return null;
    }

    @Override
    public boolean checkKey(DOModel model, String scope, String datasource, BaseData et)
    {
        Serializable key=model.getKeyValue(et,false);
        if(ObjectUtils.isEmpty(key))
            return false;

        int cnt=dbDataMapper.countData(model.getPOSchema(datasource),et);
        return cnt==1;
    }

    @Override
    public boolean save(DOModel model, String scope, String datasource, BaseData et)
    {
        if(checkKey(model,scope,datasource,et))
            return update(model,scope,datasource,et);
        else
            return create(model,scope,datasource,et);
    }

    @Override
    public void saveBatch(DOModel model, String scope, String datasource, List<BaseData> list)
    {

    }

    @Override
    public List<BaseData> select(DOModel model, String scope, String datasource, BaseData et)
    {
        POSchema poSchema=model.getPOSchema(datasource);
        return dbDataMapper.selectData(poSchema,et);
    }

    @Override
    public Page<BaseData> select(DOModel model, String scope, String datasource, BaseData et, Pageable pageable)
    {
        POSchema poSchema=model.getPOSchema(datasource);
        com.baomidou.mybatisplus.extension.plugins.pagination.Page<BaseData> pages=dbDataMapper.selectData(poSchema,et,FilterData.getPages(poSchema,pageable));
        return new PageImpl<BaseData>(pages.getRecords(), pageable, pages.getTotal());
    }

    @Override
    public List<BaseData> query(DOModel model, String scope, String datasource, String dataQuery, FilterData context)
    {
        POSchema poSchema=model.getPOSchema(datasource);
        POSchema.Segment segment=poSchema.getSegment("-dq-"+dataQuery+"-","");
        return dbDataMapper.queryData(poSchema,context.getSql(segment),context,context.getSearchCond());
    }

    @Override
    public Page<BaseData> query(DOModel model, String scope, String datasource, String dataQuery, FilterData context, Pageable pageable)
    {
        POSchema poSchema=model.getPOSchema(datasource);
        POSchema.Segment segment=poSchema.getSegment("-dq-"+dataQuery+"-","");

        if(pageable!=null)
            context.setPageable(pageable);
        else
            pageable=context.getPageable();

        com.baomidou.mybatisplus.extension.plugins.pagination.Page<BaseData> pages=
                dbDataMapper.queryData(poSchema,context.getSql(segment),context,context.getSearchCond(),context.getPages(poSchema));
        return new PageImpl<BaseData>(pages.getRecords(), pageable, pages.getTotal());
    }

    @Override
    public List<BaseData> selectRaw(DOModel model, String scope, String datasource, String sql, FilterData context)
    {
        POSchema poSchema=model.getPOSchema(datasource);
        return dbDataMapper.queryData(poSchema,sql,context,context.getSearchCond());
    }

    @Override
    public boolean execRaw(DOModel model, String scope, String datasource, String sql, BaseData param)
    {
        POSchema poSchema=model.getPOSchema(datasource);
        return dbDataMapper.executeRaw(poSchema,sql,param);
    }

    @Override
    public List<BaseData> fetch(DOModel model, String scope, String datasource, String dataSet, FilterData context)
    {
        POSchema poSchema=model.getPOSchema(datasource);
        POSchema.Segment segment=poSchema.getSegment("-ds-"+dataSet+"-","");

        return dbDataMapper.queryData(poSchema,context.getSql(segment),context,context.getSearchCond());
    }

    @Override
    public Page<BaseData> fetch(DOModel model, String scope, String datasource, String dataSet, FilterData context, Pageable pageable)
    {
        POSchema poSchema=model.getPOSchema(datasource);
        POSchema.Segment segment=poSchema.getSegment("-ds-"+dataSet+"-","");
        if(pageable!=null)
            context.setPageable(pageable);
        else
            pageable=context.getPageable();
        com.baomidou.mybatisplus.extension.plugins.pagination.Page<BaseData> pages=
                dbDataMapper.queryData(poSchema,context.getSql(segment),context,context.getSearchCond(),context.getPages(poSchema));
        return new PageImpl<BaseData>(pages.getRecords(), pageable, pages.getTotal());
    }

    @Override
    public DOModel getDOModel(String system, String entity)
    {
        return modelService.getDOModel(system,entity);
    }


    @Autowired
    private ModelService modelService;

}


