package cn.iocoder.yudao.module.llm.controller.admin.modelservice;

import cn.iocoder.yudao.module.llm.controller.admin.conversation.vo.ChatApiReqVO;
import cn.iocoder.yudao.module.llm.controller.admin.conversation.vo.ChatReqVO;
import cn.iocoder.yudao.module.llm.controller.admin.conversation.vo.ChatRespVO;
import cn.iocoder.yudao.module.llm.controller.admin.finetuningtask.vo.FineTuningTaskRespVO;
import cn.iocoder.yudao.module.llm.dal.dataobject.application.ApplicationDO;
import cn.iocoder.yudao.module.llm.service.conversation.ConversationService;
import cn.iocoder.yudao.module.llm.service.finetuningtask.FineTuningTaskService;
import org.springframework.context.annotation.Lazy;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;

import javax.annotation.security.PermitAll;
import javax.validation.constraints.*;
import javax.validation.*;
import javax.servlet.http.*;
import java.util.*;
import java.io.IOException;

import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;

import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;

import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;

import cn.iocoder.yudao.module.llm.controller.admin.modelservice.vo.*;
import cn.iocoder.yudao.module.llm.dal.dataobject.modelservice.ModelServiceDO;
import cn.iocoder.yudao.module.llm.service.modelservice.ModelServiceService;

@Tag(name = "管理后台 - 模型服务")
@RestController
@RequestMapping("/llm/model-service")
@Validated
public class ModelServiceController {

    @Lazy
    @Resource
    private ModelServiceService modelServiceService;

    @Lazy
    @Resource
    private FineTuningTaskService fineTuningTaskService;

    @Resource
    private ConversationService conversationService;

    @PostMapping("/create")
    @Operation(summary = "创建模型服务")
//    @PreAuthorize("@ss.hasPermission('llm:model-service:create')")
    public CommonResult<Long> createModelService(@Valid @RequestBody ModelServiceSaveReqVO createReqVO) {
        return success(modelServiceService.createModelService(createReqVO));
    }

    @PutMapping("/update")
    @Operation(summary = "更新模型服务")
//    @PreAuthorize("@ss.hasPermission('llm:model-service:update')")
    public CommonResult<Boolean> updateModelService(@Valid @RequestBody ModelServiceSaveReqVO updateReqVO) {
        modelServiceService.updateModelService(updateReqVO);
        return success(true);
    }

    @PutMapping("/active")
    @Operation(summary = "开启模型服务")
//    @PreAuthorize("@ss.hasPermission('llm:model-service:update')")
    public CommonResult<Boolean> activeModelService(@Valid @RequestBody ModelServiceSaveReqVO updateReqVO) {
        modelServiceService.active(updateReqVO);
        return success(true);
    }

    @PutMapping("/unactive")
    @Operation(summary = "关闭模型服务")
//    @PreAuthorize("@ss.hasPermission('llm:model-service:update')")
    public CommonResult<Boolean> unactiveModelService(@Valid @RequestBody ModelServiceSaveReqVO updateReqVO) {
        modelServiceService.unactive(updateReqVO);
        return success(true);
    }

    @GetMapping("/all")
    @Operation(summary = "查询所有模型服务")
//    @PreAuthorize("@ss.hasPermission('llm:model-service:query')")
    public CommonResult<List<ModelServiceRespVO>> getModelServiceList() {
        List<ModelServiceDO> list = modelServiceService.getModelServiceList();
        return success(BeanUtils.toBean(list, ModelServiceRespVO.class));
    }

    @DeleteMapping("/delete")
    @Operation(summary = "删除模型服务")
    @Parameter(name = "id", description = "编号", required = true)
//    @PreAuthorize("@ss.hasPermission('llm:model-service:delete')")
    public CommonResult<Boolean> deleteModelService(@RequestParam("id") Long id) {

        modelServiceService.deleteModelService(id);
        return success(true);
    }

    @GetMapping("/get")
    @Operation(summary = "获得模型服务")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
//    @PreAuthorize("@ss.hasPermission('llm:model-service:query')")
    public CommonResult<ModelServiceRespVO> getModelService(@RequestParam("id") Long id) {
        ModelServiceDO modelService = modelServiceService.getModelService(id);
        return success(BeanUtils.toBean(modelService, ModelServiceRespVO.class));
    }

    @GetMapping("/page")
    @Operation(summary = "获得模型服务分页")
//    @PreAuthorize("@ss.hasPermission('llm:model-service:query')")
    public CommonResult<PageResult<ModelServiceRespVO>> getModelServicePage(@Valid ModelServicePageReqVO pageReqVO) {
        PageResult<ModelServiceRespVO> pageResult = modelServiceService.getModelServicePage1(pageReqVO);
        return success(pageResult);
    }

    @GetMapping("/export-excel")
    @Operation(summary = "导出模型服务 Excel")
//    @PreAuthorize("@ss.hasPermission('llm:model-service:export')")
    @ApiAccessLog(operateType = EXPORT)
    public void exportModelServiceExcel(@Valid ModelServicePageReqVO pageReqVO,
              HttpServletResponse response) throws IOException {
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        List<ModelServiceDO> list = modelServiceService.getModelServicePage(pageReqVO).getList();
        // 导出 Excel
        ExcelUtils.write(response, "模型服务.xls", "数据", ModelServiceRespVO.class,
                        BeanUtils.toBean(list, ModelServiceRespVO.class));
    }

    @PermitAll
    @PostMapping("/api/{apiKey}/chat")
    @Operation(summary = "api对话接口")
    public CommonResult<ChatRespVO> apiChat(@PathVariable("apiKey") String apiKey, @RequestBody ChatApiReqVO chatReqVO){
        ModelServiceDO byApiKey = modelServiceService.getByApiKey(apiKey);
        Long fineTuningTaskId = byApiKey.getFineTuningTask();
        FineTuningTaskRespVO fineTuningTask = fineTuningTaskService.getFineTuningTask(fineTuningTaskId);
        chatReqVO.setModelId(fineTuningTask.getBaseModelId());
        chatReqVO.setModelType(0);
        ChatReqVO bean = BeanUtils.toBean(chatReqVO, ChatReqVO.class);
        ChatRespVO chat = conversationService.chat(bean);
        return success(chat);
    }

    @GetMapping("/download")
    @Operation(summary = "下载模型")
    @ApiAccessLog(operateType = EXPORT)
    public CommonResult<List<String>> download(@RequestParam("id") Long id){
        return success(modelServiceService.getDownLoadList(id));
    }

}
