/*
 * Copyright (c) 2024 LangChat. TyCoding All Rights Reserved.
 *
 * Licensed under the GNU Affero General Public License, Version 3 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.gnu.org/licenses/agpl-3.0.html
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package cn.iocoder.yudao.module.langchat.controller.admin.aigc;

import cn.hutool.core.lang.Dict;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
import cn.iocoder.yudao.module.langchat.entity.AigcApp;
import cn.iocoder.yudao.module.langchat.entity.AigcAppApi;
import cn.iocoder.yudao.module.langchat.entity.AigcKnowledge;
import cn.iocoder.yudao.module.langchat.service.aigc.AigcAppApiService;
import cn.iocoder.yudao.module.langchat.service.aigc.AigcAppService;
import cn.iocoder.yudao.module.langchat.service.aigc.AigcKnowledgeService;
import cn.iocoder.yudao.module.langchat.store.AppStore;
import cn.iocoder.yudao.module.langchat.utils.MybatisUtil;
import cn.iocoder.yudao.module.langchat.utils.QueryPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpStatus;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@RestController
@RequiredArgsConstructor
@RequestMapping("/aigc/app")
public class AigcAppController {

    private final AigcAppService aigcAppService;
    private final AigcAppApiService aigcAppApiService;
    private final AppStore appStore;
    private final AigcKnowledgeService knowledgeService;

    @GetMapping("/channel/api/{appId}")
    @TenantIgnore
    public CommonResult<AigcAppApi> getApiChanel(@PathVariable String appId) {
        List<AigcAppApi> list = aigcAppApiService.list(Wrappers.<AigcAppApi>lambdaQuery().eq(AigcAppApi::getAppId, appId));
        return CommonResult.success(list.isEmpty() ? null : list.get(0));
    }

    @GetMapping("/list")
    @TenantIgnore
    public CommonResult<List<AigcApp>> list(AigcApp data) {
        return CommonResult.success(aigcAppService.list(data));
    }

    @GetMapping("/page")
    @TenantIgnore
    public CommonResult<Dict> page(AigcApp data, QueryPage queryPage) {
        return CommonResult.success(MybatisUtil.getData(aigcAppService.page(MybatisUtil.wrap(data, queryPage),
                Wrappers.<AigcApp>lambdaQuery()
                        .like(StringUtils.isNotEmpty(data.getName()), AigcApp::getName, data.getName())
        )));
    }

    @GetMapping("/{id}")
    @TenantIgnore
    public CommonResult<AigcApp> findById(@PathVariable String id) {
        AigcApp app = aigcAppService.getById(id);
        return CommonResult.success(app);
    }

    @PostMapping
    @TenantIgnore
    @PreAuthorize("@ss.hasPermission('aigc:app:add')")
    public CommonResult add(@RequestBody AigcApp data) {
        data.setCreateTime(new Date());
        data.setSaveTime(new Date());
        aigcAppService.save(data);
        appStore.init();
        return CommonResult.success(null);
    }

    @PutMapping
    @TenantIgnore
    @PreAuthorize("@ss.hasPermission('aigc:app:update')")
    public CommonResult update(@RequestBody AigcApp data) {
        // 校验知识库是否是同纬度
        List<String> knowledgeIds = data.getKnowledgeIds();
        if (knowledgeIds != null && !knowledgeIds.isEmpty()) {
            List<AigcKnowledge> list = knowledgeService.list(Wrappers.<AigcKnowledge>lambdaQuery().in(AigcKnowledge::getId, knowledgeIds));
            Set<String> modelIds = new HashSet<>();
            Set<String> storeIds = new HashSet<>();
            list.forEach(know -> {
                modelIds.add(know.getEmbedModelId());
                storeIds.add(know.getEmbedStoreId());
            });
            if (modelIds.size() > 1) {
                return CommonResult.error(HttpStatus.SC_INTERNAL_SERVER_ERROR, "请选择相同向量库数据源配置的知识库");
            }
            if (storeIds.size() > 1) {
                return CommonResult.error(HttpStatus.SC_INTERNAL_SERVER_ERROR, "请选择相同向量模型配置的知识库");
//                throw new ServiceException("请选择相同向量模型配置的知识库");
            }
        }

        data.setSaveTime(new Date());
        aigcAppService.updateById(data);
        appStore.init();
        return CommonResult.success(null);
    }

    @DeleteMapping("/{id}")
    @TenantIgnore
    @PreAuthorize("@ss.hasPermission('aigc:app:delete')")
    public CommonResult delete(@PathVariable String id) {
        aigcAppService.removeById(id);
        appStore.init();
        return CommonResult.success(null);
    }
}