package com.jeesharp.business.modules.common.bizscene.application;

import cn.hutool.core.util.StrUtil;
import com.jeesharp.business.modules.common.bizscene.convert.BizSceneConvert;
import com.jeesharp.business.modules.common.bizscene.dto.BizSceneSaveDTO;
import com.jeesharp.business.modules.common.bizscene.entity.BizScene;
import com.jeesharp.business.modules.common.bizscene.enums.BizSceneGroupEnum;
import com.jeesharp.business.modules.common.bizscene.enums.BizSceneStatusEnum;
import com.jeesharp.business.modules.common.bizscene.service.BizSceneService;
import com.jeesharp.business.modules.common.bizscene.vo.BizSceneInfoVO;
import com.jeesharp.business.modules.common.bizscene.vo.BizSceneListVO;
import com.jeesharp.business.modules.common.bizscene.vo.BizSceneOptionVO;
import com.jeesharp.business.modules.common.bizscene.vo.BizSceneQueryVO;
import com.jeesharp.framework.exception.BizErrorException;
import com.jeesharp.framework.pojo.Page;
import com.jeesharp.framework.pojo.query.PageRespVO;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 业务业态场景应用服务：管理端 CRUD 与启用场景选项查询。
 *
 * @author jeesharp
 * @since 2026-07-03
 */
@Service
@AllArgsConstructor
@Transactional(readOnly = true)
public class BizSceneApplicationService {

    private final BizSceneService bizSceneService;

    public BizSceneInfoVO get(String id) {
        BizScene entity = bizSceneService.get(id);
        if (entity == null) {
            throw new BizErrorException("业务场景不存在");
        }
        BizSceneInfoVO vo = BizSceneConvert.INSTANCE.toInfoVO(entity);
        fillDisplay(vo);
        return vo;
    }

    public PageRespVO<BizSceneListVO> findPage(Page<BizScene> page, BizSceneQueryVO query) {
        Page<BizScene> result = bizSceneService.findPage(page, query);
        PageRespVO<BizSceneListVO> resp = BizSceneConvert.INSTANCE.toPageRespVO(result);
        if (resp.getRecords() != null) {
            resp.getRecords().forEach(this::fillDisplay);
        }
        return resp;
    }

    public List<BizSceneOptionVO> listEnabledOptions(String capability, String tenantId) {
        return bizSceneService.listEnabled(tenantId, capability).stream()
                .map(this::toOption)
                .collect(Collectors.toList());
    }

    public BizSceneOptionVO getOptionByCode(String sceneCode, String tenantId) {
        BizScene scene = bizSceneService.findBySceneCode(sceneCode, tenantId);
        if (scene == null || !BizSceneStatusEnum.ENABLED.getValue().equals(scene.getStatus())) {
            return null;
        }
        return toOption(scene);
    }

    @Transactional(readOnly = false)
    public void create(BizSceneSaveDTO dto) {
        if (StrUtil.isNotBlank(dto.getId())) {
            throw new BizErrorException("新增请求不应携带主键 id");
        }
        bizSceneService.createBizScene(BizSceneConvert.INSTANCE.toEntity(dto));
    }

    @Transactional(readOnly = false)
    public void update(BizSceneSaveDTO dto) {
        if (StrUtil.isBlank(dto.getId())) {
            throw new BizErrorException("更新请求必须携带主键 id");
        }
        bizSceneService.updateBizScene(BizSceneConvert.INSTANCE.toEntity(dto));
    }

    @Transactional(readOnly = false)
    public void delete(String ids) {
        bizSceneService.batchDelete(Arrays.asList(ids.split(",")));
    }

    public void assertSceneEnabled(String sceneCode, String tenantId) {
        bizSceneService.assertSceneEnabled(sceneCode, tenantId);
    }

    private BizSceneOptionVO toOption(BizScene scene) {
        BizSceneOptionVO vo = new BizSceneOptionVO();
        vo.setSceneCode(scene.getSceneCode());
        vo.setSceneName(scene.getSceneName());
        vo.setSceneGroup(scene.getSceneGroup());
        vo.setAdminListUrl(scene.getAdminListUrl());
        vo.setKeywordField(scene.getKeywordField());
        vo.setNameField(scene.getNameField());
        vo.setCoverField(scene.getCoverField());
        vo.setCapabilities(scene.getCapabilities());
        vo.setExtJson(scene.getExtJson());
        return vo;
    }

    private void fillDisplay(BizSceneInfoVO vo) {
        vo.setStatusName(BizSceneStatusEnum.getDescByValue(vo.getStatus()));
        vo.setSceneGroupName(BizSceneGroupEnum.getDescByCode(vo.getSceneGroup()));
    }

    private void fillDisplay(BizSceneListVO vo) {
        vo.setStatusName(BizSceneStatusEnum.getDescByValue(vo.getStatus()));
        vo.setSceneGroupName(BizSceneGroupEnum.getDescByCode(vo.getSceneGroup()));
    }
}
