package tech.easyflow.admin.controller.ai;

import cn.dev33.satoken.annotation.SaCheckPermission;
import com.mybatisflex.core.query.QueryWrapper;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import tech.easyflow.ai.dto.RemoteModelImportRequest;
import tech.easyflow.ai.entity.Model;
import tech.easyflow.ai.entity.ModelProvider;
import tech.easyflow.ai.service.ModelProviderService;
import tech.easyflow.ai.service.ModelService;
import tech.easyflow.ai.service.discovery.RemoteModelDiscoveryService;
import tech.easyflow.ai.service.discovery.RemoteModelImportResult;
import tech.easyflow.ai.service.discovery.RemoteModelImportService;
import tech.easyflow.ai.service.discovery.RemoteModelListResult;
import tech.easyflow.common.annotation.UsePermission;
import tech.easyflow.common.domain.Result;
import tech.easyflow.common.entity.LoginAccount;
import tech.easyflow.common.satoken.util.SaTokenUtil;
import tech.easyflow.common.web.controller.BaseCurdController;
import tech.easyflow.common.web.exceptions.BusinessException;
import tech.easyflow.common.web.jsonbody.JsonBody;

import java.io.Serializable;
import java.math.BigInteger;

/**
 * 控制层。
 *
 * @author 12076
 * @since 2025-12-16
 */
@RestController
@RequestMapping("/api/v1/modelProvider")
@UsePermission(moduleName = "/api/v1/model")
public class ModelProviderController extends BaseCurdController<ModelProviderService, ModelProvider> {
    private final ModelService modelService;
    private final RemoteModelDiscoveryService remoteModelDiscoveryService;
    private final RemoteModelImportService remoteModelImportService;

    /**
     * 创建模型服务商控制器。
     *
     * @param service 模型服务商服务
     * @param modelService 模型服务
     * @param remoteModelDiscoveryService 远端模型发现服务
     * @param remoteModelImportService 远端模型一键添加服务
     */
    public ModelProviderController(ModelProviderService service,
                                   ModelService modelService,
                                   RemoteModelDiscoveryService remoteModelDiscoveryService,
                                   RemoteModelImportService remoteModelImportService) {
        super(service);
        this.modelService = modelService;
        this.remoteModelDiscoveryService = remoteModelDiscoveryService;
        this.remoteModelImportService = remoteModelImportService;
    }

    /**
     * 删除没有子模型的服务商。
     *
     * @param id 服务商 ID
     * @return 删除结果
     */
    @Override
    @PostMapping("remove")
    @Transactional
    public Result<?> remove(@JsonBody(value = "id", required = true) Serializable id) {
        QueryWrapper modelQueryWrapper = QueryWrapper.create()
                .in(Model::getProviderId, id);
        if (modelService.count(modelQueryWrapper) > 0) {
            throw new BusinessException("Delete all child models before removing this Model Provider");
        }
        return Result.ok(service.removeById(id));
    }

    /**
     * 主动获取当前服务商的远端模型列表。
     *
     * @param providerId 服务商 ID
     * @return 已补全能力和本地添加状态的远端模型列表
     */
    @GetMapping("{providerId}/remoteModels")
    @SaCheckPermission("/api/v1/model/save")
    public Result<RemoteModelListResult> remoteModels(@PathVariable BigInteger providerId) {
        return Result.ok(remoteModelDiscoveryService.discover(providerId));
    }

    /**
     * 幂等添加单个远端模型。
     *
     * @param providerId 服务商 ID
     * @param request 一键添加请求
     * @return 创建或已存在结果
     */
    @PostMapping("{providerId}/remoteModels/import")
    @SaCheckPermission("/api/v1/model/save")
    public Result<RemoteModelImportResult> importRemoteModel(
            @PathVariable BigInteger providerId,
            @RequestBody RemoteModelImportRequest request) {
        LoginAccount account = SaTokenUtil.getLoginAccount();
        Model model = new Model();
        commonFiled(model, account.getId(), account.getTenantId(), account.getDeptId());
        String modelId = request == null ? null : request.getModelId();
        return Result.ok(remoteModelImportService.importModel(providerId, modelId, model));
    }
}
