package com.yd.csf.api.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yd.common.constant.CodeGeneratorConstants;
import com.yd.common.enums.CommonEnum;
import com.yd.common.enums.ResultCode;
import com.yd.common.exception.BusinessException;
import com.yd.common.result.Result;
import com.yd.common.utils.CodeGenerator;
import com.yd.common.utils.RandomStringGenerator;
import com.yd.csf.api.service.ApiFormulaConfigService;
import com.yd.csf.api.service.ApiRelObjectFormulaService;
import com.yd.csf.feign.dto.formulaconfig.ApiRelObjectFormulaDto;
import com.yd.csf.feign.request.formulaconfig.ApiFormulaConfigAddRequest;
import com.yd.csf.feign.request.formulaconfig.ApiFormulaConfigEditRequest;
import com.yd.csf.feign.request.formulaconfig.ApiFormulaConfigPageRequest;
import com.yd.csf.feign.response.formulaconfig.ApiFormulaConfigDetailResponse;
import com.yd.csf.feign.response.formulaconfig.ApiFormulaConfigPageResponse;
import com.yd.csf.service.dto.FormulaConfigDto;
import com.yd.csf.service.model.FormulaConfig;
import com.yd.csf.service.service.IFormulaConfigService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class ApiFormulaConfigServiceImpl implements ApiFormulaConfigService {

    @Autowired
    private IFormulaConfigService iFormulaConfigService;

    @Autowired
    private ApiRelObjectFormulaService apiRelObjectFormulaService;

    /**
     * 分页查询-公式配置信息
     * @param request
     * @return
     */
    @Override
    public Result<IPage<ApiFormulaConfigPageResponse>> page(ApiFormulaConfigPageRequest request) {
        Page<ApiFormulaConfigPageResponse> page = new Page<>(request.getPageNo(), request.getPageSize());
        IPage<ApiFormulaConfigPageResponse> iPage = iFormulaConfigService.page(page, request);
        return Result.success(iPage);
    }

    /**
     * 详情-公式配置信息
     * @param formulaBizId
     * @return
     */
    @Override
    public Result<ApiFormulaConfigDetailResponse> detail(String formulaBizId) {
        Result<FormulaConfig> result = checkFormulaConfigIsExist(formulaBizId);
        FormulaConfig formulaConfig = result.getData();
        ApiFormulaConfigDetailResponse response = new ApiFormulaConfigDetailResponse();
        BeanUtils.copyProperties(formulaConfig,response);
        return Result.success(response);
    }

    /**
     * 添加-公式配置信息
     * @param request
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result add(ApiFormulaConfigAddRequest request) {
        //校验公式名称唯一性
        List<FormulaConfig> formulaConfigList = iFormulaConfigService.queryList(FormulaConfigDto.builder()
                .name(request.getName())
                .build());
        if (!CollectionUtils.isEmpty(formulaConfigList)) {
            throw new BusinessException("公式名称已存在");
        }
        FormulaConfig formulaConfig = new FormulaConfig();
        BeanUtils.copyProperties(request,formulaConfig);
        formulaConfig.setFormulaBizId(RandomStringGenerator.generateBizId16(CommonEnum.UID_TYPE_FORMULA_CONFIG.getCode()));
        //公式编码
        formulaConfig.setCode(CodeGenerator.generate10Code(CodeGeneratorConstants.PREFIX_FORMULA_CODE));
        iFormulaConfigService.saveOrUpdate(formulaConfig);
        //保存变量对象列表和公式配置关系
        apiRelObjectFormulaService.saveObjectList(buildApiRelObjectFormulaDtoList(request.getVariableBizIdList()),formulaConfig.getFormulaBizId());
        return Result.success();
    }

    /**
     * 编辑-公式配置信息
     * @param request
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result edit(ApiFormulaConfigEditRequest request) {
        Result<FormulaConfig> result = checkFormulaConfigIsExist(request.getFormulaBizId());
        FormulaConfig formulaConfig = result.getData();
        //校验公式名称唯一性
        List<FormulaConfig> formulaConfigList = iFormulaConfigService.queryList(FormulaConfigDto.builder()
                .name(request.getName())
                .isExcludeMy(true)
                .formulaBizId(request.getFormulaBizId())
                .build());
        if (!CollectionUtils.isEmpty(formulaConfigList)) {
            throw new BusinessException("公式名称已存在");
        }
        BeanUtils.copyProperties(request,formulaConfig);
        iFormulaConfigService.saveOrUpdate(formulaConfig);
        //保存变量对象列表和公式配置关系
        apiRelObjectFormulaService.saveObjectList(buildApiRelObjectFormulaDtoList(request.getVariableBizIdList()),formulaConfig.getFormulaBizId());
        return Result.success();
    }

    /**
     * 删除-公式配置信息 TODO
     * @param formulaBizId
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result del(String formulaBizId) {
        return null;
    }

    /**
     * 构造变量对象列表
     * @return
     */
    public List<ApiRelObjectFormulaDto> buildApiRelObjectFormulaDtoList(List<String> variableBizIdList) {
        List<ApiRelObjectFormulaDto> apiRelObjectFormulaDtoList = variableBizIdList.stream().map(variableBizId -> {
            return ApiRelObjectFormulaDto.builder()
                    .objectBizId(variableBizId)
                    .objectName(CommonEnum.UID_TYPE_VARIABLE.getName())
                    .objectTableName(CommonEnum.UID_TYPE_VARIABLE.getCode())
                    .objectType(CommonEnum.UID_TYPE_VARIABLE.getCode())
                    .build();
        }).collect(Collectors.toList());
        return apiRelObjectFormulaDtoList;
    }

    /**
     * 校验公式配置信息是否存在
     * @param formulaBizId
     * @return
     */
    public Result<FormulaConfig> checkFormulaConfigIsExist(String formulaBizId) {
        FormulaConfig formulaConfig = iFormulaConfigService.queryOne(formulaBizId);
        if (Objects.isNull(formulaConfig)) {
            //数据不存在
            throw new BusinessException(ResultCode.NULL_ERROR.getCode(),ResultCode.NULL_ERROR.getMessage());
        }
        return Result.success(formulaConfig);
    }
}
