package com.jeesharp.business.modules.common.bizscene.service.impl;

import cn.hutool.core.util.StrUtil;
import com.jeesharp.business.modules.common.bizscene.entity.BizScene;
import com.jeesharp.business.modules.common.bizscene.enums.BizSceneStatusEnum;
import com.jeesharp.business.modules.common.bizscene.mapper.BizSceneMapper;
import com.jeesharp.business.modules.common.bizscene.service.BizSceneService;
import com.jeesharp.business.modules.common.bizscene.vo.BizSceneQueryVO;
import com.jeesharp.framework.exception.BizErrorException;
import com.jeesharp.framework.mybatis.core.service.CrudService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 业务业态场景领域服务实现。
 *
 * @author jeesharp
 * @since 2026-07-03
 */
@Service
@Transactional(readOnly = true)
public class BizSceneServiceImpl extends CrudService<BizSceneMapper, BizScene, BizSceneQueryVO>
        implements BizSceneService {

    @Override
    @Transactional(readOnly = false)
    public BizScene createBizScene(BizScene scene) {
        if (StrUtil.isNotBlank(scene.getId())) {
            throw new BizErrorException("新增场景不应预置主键");
        }
        normalizeDefaults(scene);
        assertSceneCodeUnique(scene.getSceneCode(), scene.getTenantId(), null);
        getBaseMapper().insert(scene);
        return scene;
    }

    @Override
    @Transactional(readOnly = false)
    public void updateBizScene(BizScene scene) {
        if (StrUtil.isBlank(scene.getId())) {
            throw new BizErrorException("更新场景主键不能为空");
        }
        if (get(scene.getId()) == null) {
            throw new BizErrorException("业务场景不存在");
        }
        normalizeDefaults(scene);
        assertSceneCodeUnique(scene.getSceneCode(), scene.getTenantId(), scene.getId());
        getBaseMapper().update(scene);
    }

    @Override
    public BizScene findBySceneCode(String sceneCode, String tenantId) {
        if (StrUtil.isBlank(sceneCode)) {
            return null;
        }
        return getBaseMapper().findBySceneCode(sceneCode.trim(), tenantId);
    }

    @Override
    public List<BizScene> listEnabled(String tenantId, String capability) {
        return getBaseMapper().listEnabled(tenantId, StrUtil.nullToEmpty(capability).trim());
    }

    @Override
    public void assertSceneEnabled(String sceneCode, String tenantId) {
        if (StrUtil.isBlank(sceneCode)) {
            throw new BizErrorException("请选择业务场景");
        }
        BizScene scene = findBySceneCode(sceneCode, tenantId);
        if (scene == null || !BizSceneStatusEnum.ENABLED.getValue().equals(scene.getStatus())) {
            throw new BizErrorException("业务场景无效或已禁用：" + sceneCode);
        }
    }

    private void normalizeDefaults(BizScene scene) {
        if (scene.getStatus() == null) {
            scene.setStatus(BizSceneStatusEnum.ENABLED.getValue());
        }
        if (scene.getSort() == null) {
            scene.setSort(0);
        }
        if (StrUtil.isBlank(scene.getKeywordField())) {
            scene.setKeywordField("keyword");
        }
        if (StrUtil.isBlank(scene.getNameField())) {
            scene.setNameField("name");
        }
        if (StrUtil.isNotBlank(scene.getSceneCode())) {
            scene.setSceneCode(scene.getSceneCode().trim().toUpperCase());
        }
        if (StrUtil.isNotBlank(scene.getSceneGroup())) {
            scene.setSceneGroup(scene.getSceneGroup().trim().toUpperCase());
        }
        if (StrUtil.isNotBlank(scene.getAdminListUrl())) {
            scene.setAdminListUrl(scene.getAdminListUrl().trim());
        }
        if (StrUtil.isNotBlank(scene.getCapabilities())) {
            scene.setCapabilities(scene.getCapabilities().trim().toUpperCase());
        }
    }

    private void assertSceneCodeUnique(String sceneCode, String tenantId, String excludeId) {
        if (StrUtil.isBlank(sceneCode)) {
            return;
        }
        BizScene existing = findBySceneCode(sceneCode, tenantId);
        if (existing != null && !existing.getId().equals(excludeId)) {
            throw new BizErrorException("场景编号已存在：" + sceneCode);
        }
    }
}
