package cn.stylefeng.team.form.modular.manage.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.stylefeng.roses.kernel.db.api.factory.PageFactory;
import cn.stylefeng.roses.kernel.db.api.factory.PageResultFactory;
import cn.stylefeng.roses.kernel.db.api.pojo.page.PageResult;
import cn.stylefeng.roses.kernel.rule.exception.base.ServiceException;
import cn.stylefeng.team.form.api.callback.RemoveFormModelCallbackApi;
import cn.stylefeng.team.form.api.entity.FormDefinition;
import cn.stylefeng.team.form.modular.manage.enums.FormDefinitionExceptionEnum;
import cn.stylefeng.team.form.modular.manage.mapper.FormDefinitionMapper;
import cn.stylefeng.team.form.modular.manage.request.FormDefinitionRequest;
import cn.stylefeng.team.form.modular.manage.service.FormDefinitionService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class FormDefinitionServiceImpl extends ServiceImpl<FormDefinitionMapper, FormDefinition> implements FormDefinitionService,
        RemoveFormModelCallbackApi {

    @Override
    public void add(FormDefinitionRequest formDefinitionRequest) {
        FormDefinition formDefinition = new FormDefinition();
        BeanUtil.copyProperties(formDefinitionRequest, formDefinition);
        this.save(formDefinition);
    }

    @Override
    public void del(FormDefinitionRequest formDefinitionRequest) {
        FormDefinition formDefinition = this.queryFormDefinition(formDefinitionRequest);
        this.removeById(formDefinition.getFormDefinitionId());
    }

    @Override
    public void edit(FormDefinitionRequest formDefinitionRequest) {
        FormDefinition formDefinition = this.queryFormDefinition(formDefinitionRequest);
        BeanUtil.copyProperties(formDefinitionRequest, formDefinition);
        this.updateById(formDefinition);
    }

    @Override
    public FormDefinition detail(Long definitionId) {
        FormDefinitionRequest formDefinitionRequest = new FormDefinitionRequest();
        formDefinitionRequest.setFormDefinitionId(definitionId);
        return this.queryFormDefinition(formDefinitionRequest);
    }

    @Override
    public PageResult<FormDefinition> findPage(FormDefinitionRequest formDefinitionRequest) {
        LambdaQueryWrapper<FormDefinition> wrapper = createWrapper(formDefinitionRequest);
        Page<FormDefinition> sysRolePage = this.page(PageFactory.defaultPage(), wrapper);
        return PageResultFactory.createPageResult(sysRolePage);
    }

    @Override
    public FormDefinition findModelNewestDefinition(Long formModelId) {

        LambdaQueryWrapper<FormDefinition> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(FormDefinition::getFormModelId, formModelId);

        wrapper.orderByDesc(FormDefinition::getFldVersion);

        Page<FormDefinition> result = this.page(PageFactory.defaultPage(), wrapper);
        if (ObjectUtil.isNotEmpty(result.getRecords())) {
            return result.getRecords().get(0);
        } else {
            throw new ServiceException(FormDefinitionExceptionEnum.FORM_DEFINITION_NOT_EXISTED);
        }
    }

    @Override
    public List<FormDefinition> findList(FormDefinitionRequest formDefinitionRequest) {
        LambdaQueryWrapper<FormDefinition> wrapper = this.createWrapper(formDefinitionRequest);
        return this.list(wrapper);
    }

    @Override
    public void modelRemoveAction(Long modelId) {
        LambdaQueryWrapper<FormDefinition> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(FormDefinition::getFormModelId, modelId);
        this.remove(wrapper);
    }

    private FormDefinition queryFormDefinition(FormDefinitionRequest formDefinitionRequest) {
        FormDefinition formDefinition = this.getById(formDefinitionRequest.getFormDefinitionId());
        if (ObjectUtil.isEmpty(formDefinition)) {
            throw new ServiceException(FormDefinitionExceptionEnum.FORM_DEFINITION_NOT_EXISTED);
        }
        return formDefinition;
    }

    private LambdaQueryWrapper<FormDefinition> createWrapper(FormDefinitionRequest formDefinitionRequest) {
        LambdaQueryWrapper<FormDefinition> queryWrapper = new LambdaQueryWrapper<>();

        Long formDefinitionId = formDefinitionRequest.getFormDefinitionId();
        Long formModelId = formDefinitionRequest.getFormModelId();
        String fldVersion = formDefinitionRequest.getFldVersion();

        queryWrapper.eq(ObjectUtil.isNotNull(formDefinitionId), FormDefinition::getFormDefinitionId, formDefinitionId);
        queryWrapper.eq(ObjectUtil.isNotNull(formModelId), FormDefinition::getFormModelId, formModelId);
        queryWrapper.like(ObjectUtil.isNotEmpty(fldVersion), FormDefinition::getFldVersion, fldVersion);

        return queryWrapper;
    }

}