package com.kingtom.shengtai.app.srm.service.impl;

import java.util.*;
import java.util.stream.Collectors;

import com.kingtom.kirin.app.space.service.ISpaceFileService;
import com.kingtom.kirin.app.system.utils.SystemUtils;
import com.kingtom.kirin.core.common.CommonConst;
import com.kingtom.kirin.core.common.base.service.impl.BaseServiceImpl;
import com.kingtom.kirin.core.common.exception.AppException;
import com.kingtom.kirin.core.common.utils.CollectionUtils;
import com.kingtom.kirin.core.common.utils.IDUtils;
import com.kingtom.kirin.core.common.utils.JsonUtils;
import com.kingtom.shengtai.app.srm.dao.IProductDirDao;
import com.kingtom.shengtai.app.srm.model.ProductDir;
import com.kingtom.shengtai.app.srm.service.IProductDirService;
import com.kingtom.shengtai.app.srm.SrmConst;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryCondition;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.core.row.Row;
import com.mybatisflex.core.service.IService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import static com.kingtom.shengtai.app.srm.model.table.ProductDirTableDef.PRODUCT_DIR;

/**
 * 应用模块名称</p>
 * 产品目录表 服务层实现。</p>
 * Copyright: Copyright (C) 2024 , Inc. All rights reserved. <p>
 * Company: 成都诚唐科技有限责任公司</p>
 *
 * @author wany
 * @since 2024/01/17
 */
@Service
public class ProductDirServiceImpl extends BaseServiceImpl<IProductDirDao, ProductDir> implements IProductDirService{

    @Autowired
    private ISpaceFileService spaceFileService;

    @Override
    public ProductDir create(ProductDir productDir){
        checkBeforeCreate(productDir);
        fillBeforeCreate(productDir);
        boolean f = mapper.insertSelective(productDir) == 1;
        if(!f){
            throw new AppException("落库出错，新建产品目录失败！");
        }
        saveFileFormal(productDir);
        return findById(productDir.getId());
    }

    private void saveFileFormal(ProductDir entity){
        spaceFileService.doFormalOfReplace(entity.getImage(), SrmConst.PRODUCT_DIR_RESOURCE_KEY,
                entity.getId(), SrmConst.PRODUCT_DIR_IMAGE);
    }

    private void checkBeforeCreate(ProductDir productDir){
        if(productDir == null){
            throw new AppException("产品目录表为空，新建失败！");
        }
        if(StringUtils.isBlank(productDir.getName())){
            throw new AppException("名称为空，新建失败！");
        } else{
            ProductDir byName = findByName(productDir.getName());
            if(byName != null){
                throw new AppException("标识符重复，新建失败！").setM(productDir.getName());
            }
        }
        if(StringUtils.isBlank(productDir.getCode())){
            throw new AppException("标识符为空，新建失败！");
        } else{
            ProductDir dbByCode = findByCode(productDir.getCode());
            if(dbByCode != null){
                throw new AppException("标识符重复，新建失败！").setM(productDir.getCode());
            }
        }
        if(StringUtils.isBlank(productDir.getSysId())){
            throw new AppException("系统Id为空，新建失败！");
        }
    }

    private void fillBeforeCreate(ProductDir productDir){
        if(productDir.getId() == null){
            productDir.setId(IDUtils.newUUID());
        }
        if(StringUtils.isEmpty(productDir.getSysId())){
            productDir.setSysId(SystemUtils.getCurrentSystemId());
        }
        if(StringUtils.isEmpty(productDir.getExt3())){
            productDir.setExt3(CommonConst.EMPTY_OBJECT_STRING);
        }
        if(productDir.getPath() == null){
            productDir.setPath(CommonConst.EMPTY_ARRAY_STRING);
        }
        //path填充
        if(StringUtils.isBlank(productDir.getParentId())){
            productDir.setParentId(productDir.getSysId());
            productDir.setPath(JsonUtils.toJson(List.of(productDir.getSysId(), productDir.getId())));
        } else{
            ProductDir parent = findById(productDir.getParentId());
            if(parent == null){
                throw new AppException("父目录不存在，新建失败！");
            }
            List<String> parentPath = JsonUtils.toObjectList(parent.getPath(), String.class);
            parentPath.add(productDir.getId());
            productDir.setPath(JsonUtils.toJson(parentPath));
        }
        productDir.setGmtCreate(new Date());
        productDir.setGmtModified(productDir.getGmtCreate());
    }

    @Override
    public ProductDir update(ProductDir productDir){
        checkBeforeUpdate(productDir);
        ProductDir dir = new ProductDir();
        dir.setId(productDir.getId());
        dir.setGmtModified(new Date());
        dir.setCode(productDir.getCode());
        dir.setName(productDir.getName());
        dir.setImage(productDir.getImage());
        dir.setRemark(productDir.getRemark());
        boolean f = mapper.update(dir) == 1;
        if(!f){
            throw new AppException("落库出错，更新产品目录表失败！");
        }
        saveFileFormal(productDir);
        return findById(productDir.getId());
    }

    private void checkBeforeUpdate(ProductDir productDir){
        if(productDir == null){
            throw new AppException("产品目录为空，更新失败！");
        }
        if(StringUtils.isEmpty(productDir.getId())){
            throw new AppException("产品目录id为空，更新失败！");
        }
        if(StringUtils.isNotEmpty(productDir.getName())){
            ProductDir byName = findByName(productDir.getName());
            if(byName != null && !byName.getId().equals(productDir.getId())){
                throw new AppException("标识符重复，更新失败！").setM(productDir.getName());
            }
        }
        if(StringUtils.isNotEmpty(productDir.getCode())){
            ProductDir byCode = findByCode(productDir.getCode());
            if(byCode != null && !byCode.getId().equals(productDir.getId())){
                throw new AppException("标识符重复，更新失败！").setM(productDir.getCode());
            }
        }
    }

    @Override
    public void deleteById(String id){
        if(id == null){
            return;
        }
        //同步删除子目录
        int i = mapper.deleteByCondition(QueryCondition.createEmpty().and("path::jsonb ?? '" + id + "'"));
        if(i <= 0){
            throw new AppException("落库出错，删除产品目录表失败！");
        }
    }

    @Override
    public void deleteByIds(List<String> ids){
        if(CollectionUtils.isEmpty(ids)){
            return;
        }
        for(String id : ids){
            deleteById(id);
        }
    }

    @Override
    public ProductDir findById(String id){
        if(id == null){
            return null;
        }
        return mapper.selectOneById(id);
    }

    @Override
    public List<ProductDir> findByIds(List<String> ids){
        if(CollectionUtils.isEmpty(ids)){
            return new ArrayList<>();
        }
        return mapper.selectListByIds(ids);
    }

    @Override
    public ProductDir findByName(String name){
        return mapper.selectOneByCondition(PRODUCT_DIR.NAME.eq(name));
    }

    @Override
    public ProductDir findByCode(String code){
        return mapper.selectOneByCondition(PRODUCT_DIR.CODE.eq(code));
    }

    @Override
    public List<ProductDir> findChild(String id){
        if(StringUtils.isEmpty(id)){
            return new ArrayList<>();
        }
        QueryCondition condition =
                QueryCondition.createEmpty().and("path::jsonb ?? '" + id + "'").and(PRODUCT_DIR.ID.ne(id));
        return mapper.selectListByCondition(condition);
    }

    @Override
    public Page<ProductDir> page(String search, int pageNum, int pageSize){
        QueryWrapper wrapper = QueryWrapper.create();
        //todo 查询条件构造
        return mapper.paginate(pageNum, pageSize, wrapper);
    }

    @Override
    public List<Map<String, Object>> findSupplierCountGroupByProduct(boolean filterCount0){
        //SELECT a.ID, a.NAME, COUNT ( b.sid ) AS c
        //FROM( SELECT id, name FROM product_dir WHERE id NOT IN ( SELECT DISTINCT parent_id FROM product_dir ) ) AS a
        //LEFT JOIN ( SELECT SUBSTRING ( json_array_elements ( product :: JSON ) :: TEXT, 2, 36 ) AS pid, id AS sid
        // FROM srm_supplier ) AS b ON a.ID = b.pid
        //GROUP BY a.ID, a.NAME  HAVING COUNT ( b.sid ) > 0 ORDER BY c DESC;
        QueryWrapper wrapper = QueryWrapper.create().select("a.id", "a.name", "COUNT ( b.sid ) AS c")
                .from(QueryWrapper.create().select("id,name").from("product_dir").where("id not in(select DISTINCT parent_id from product_dir)")).as("a")
                .leftJoin(QueryWrapper.create()
                                      .select("SUBSTRING ( json_array_elements ( product :: json ) :: TEXT, 2, 36 ) AS pid","id AS sid")
                                      .from("srm_supplier")).as("b").on("a.id = b.pid")
                .groupBy("a.id", "a.name")
                .having(QueryCondition.createEmpty().and("COUNT ( b.sid ) > 0").when(filterCount0))
                .orderBy("c desc");
        List<Row> objects = mapper.selectRowsByQuery(wrapper);
        return objects.stream().map(HashMap::new).collect(Collectors.toList());
    }

}
