package cn.iocoder.byzs.module.web.controller.admin.ai;

import cn.hutool.core.util.ObjUtil;
import cn.iocoder.byzs.framework.common.enums.CommonStatusEnum;
import cn.iocoder.byzs.framework.common.pojo.CommonResult;
import cn.iocoder.byzs.framework.common.pojo.PageParam;
import cn.iocoder.byzs.framework.common.pojo.PageResult;
import cn.iocoder.byzs.framework.common.util.object.BeanUtils;
import cn.iocoder.byzs.framework.tenant.core.aop.TenantIgnore;
import cn.iocoder.byzs.module.ai.controller.admin.chat.vo.conversation.AiChatConversationCreateMyReqVO;
import cn.iocoder.byzs.module.ai.controller.admin.chat.vo.message.AiChatMessageSendReqVO;
import cn.iocoder.byzs.module.ai.controller.admin.chat.vo.message.AiChatMessageSendRespVO;
import cn.iocoder.byzs.module.ai.controller.admin.image.vo.AiImageDrawReqVO;
import cn.iocoder.byzs.module.ai.controller.admin.image.vo.AiImageRespVO;
import cn.iocoder.byzs.module.ai.controller.admin.mapgame.vo.MapGamePageReqVO;
import cn.iocoder.byzs.module.ai.controller.admin.mapgame.vo.MapGameRespVO;
import cn.iocoder.byzs.module.ai.controller.admin.model.vo.chatRole.AiChatRolePageReqVO;
import cn.iocoder.byzs.module.ai.controller.admin.video.vo.AiVideoDrawReqVO;
import cn.iocoder.byzs.module.ai.controller.admin.video.vo.AiVideoRespVO;
import cn.iocoder.byzs.module.ai.controller.admin.virtualdevice.vo.VirtualDevicePageReqVO;
import cn.iocoder.byzs.module.ai.controller.admin.virtualdevice.vo.VirtualDeviceRespVO;
import cn.iocoder.byzs.module.ai.controller.admin.vision.vo.AiVisionThinkReqVO;
import cn.iocoder.byzs.module.ai.controller.admin.vision.vo.AiVisionThinkRespVO;
import cn.iocoder.byzs.module.ai.dal.dataobject.image.AiImageDO;
import cn.iocoder.byzs.module.ai.dal.dataobject.mapgame.MapGameDO;
import cn.iocoder.byzs.module.ai.dal.dataobject.model.AiChatRoleDO;
import cn.iocoder.byzs.module.ai.dal.dataobject.model.AiModelDO;
import cn.iocoder.byzs.module.ai.dal.dataobject.video.AiVideoDO;
import cn.iocoder.byzs.module.ai.dal.dataobject.virtualdevice.VirtualDeviceDO;
import cn.iocoder.byzs.module.ai.service.chat.AiChatConversationService;
import cn.iocoder.byzs.module.ai.service.chat.AiChatMessageService;
import cn.iocoder.byzs.module.ai.service.image.AiImageService;
import cn.iocoder.byzs.module.ai.service.mapgame.MapGameService;
import cn.iocoder.byzs.module.ai.service.model.AiChatRoleService;
import cn.iocoder.byzs.module.ai.service.model.AiModelService;
import cn.iocoder.byzs.module.ai.service.tts.AiTtsService;
import cn.iocoder.byzs.module.ai.service.video.AiVideoService;
import cn.iocoder.byzs.module.ai.service.virtualdevice.VirtualDeviceService;
import cn.iocoder.byzs.module.web.controller.admin.ai.vo.MapGameVO;
import cn.iocoder.byzs.module.web.controller.admin.ai.vo.TtsVo;
import cn.iocoder.byzs.module.web.controller.admin.ai.vo.WebAiChatRoleVO;
import cn.iocoder.byzs.module.web.service.ai.WebAiServiceImpl;
import com.volcengine.ark.runtime.model.responses.constant.ResponsesConstants;
import com.volcengine.ark.runtime.model.responses.content.InputContentItemImage;
import com.volcengine.ark.runtime.model.responses.content.InputContentItemText;
import com.volcengine.ark.runtime.model.responses.content.OutputContentItemText;
import com.volcengine.ark.runtime.model.responses.item.BaseItem;
import com.volcengine.ark.runtime.model.responses.item.ItemEasyMessage;
import com.volcengine.ark.runtime.model.responses.item.ItemOutputMessage;
import com.volcengine.ark.runtime.model.responses.item.MessageContent;
import com.volcengine.ark.runtime.model.responses.request.CreateResponsesRequest;
import com.volcengine.ark.runtime.model.responses.request.ResponsesInput;
import com.volcengine.ark.runtime.model.responses.response.ResponseObject;
import com.volcengine.ark.runtime.service.ArkService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.annotation.security.PermitAll;
import jakarta.validation.Valid;
import jodd.util.StringUtil;
import org.springframework.http.MediaType;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;

import java.util.List;
import java.util.Optional;

import static cn.iocoder.byzs.framework.common.pojo.CommonResult.success;
import static cn.iocoder.byzs.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;

@Tag(name = "Web-前端接口")
@RestController
@RequestMapping("/bjdxWeb/ai")
@Validated
public class WebAiController {

    @Resource
    private AiChatConversationService chatConversationService;
    @Resource
    private AiChatMessageService chatMessageService;
    @Resource
    private AiImageService imageService;
    @Resource
    private AiVideoService videoService;
    @Resource
    private AiChatRoleService chatRoleService;
    @Resource
    private AiModelService modelService;
    @Resource
    private WebAiServiceImpl webAiService;
    @Resource
    private VirtualDeviceService virtualDeviceService;
    @Resource
    private MapGameService mapGameService;
    @Resource
    private AiTtsService ttsService;


    // ================ 模型数据 ================

    @GetMapping("/selectRoleModel")
    @Operation(summary = "获得聊天角色分页")
    public CommonResult<PageResult<WebAiChatRoleVO>> selectRoleModel(@Valid AiChatRolePageReqVO pageReqVO) {
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        pageReqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
        PageResult<AiChatRoleDO> pageResult = chatRoleService.getChatRoleMyPage(pageReqVO, getLoginUserId());
        return success(BeanUtils.toBean(pageResult, WebAiChatRoleVO.class));
    }

    @PermitAll
    @TenantIgnore
    @GetMapping("/getModelIdByType")
    @Operation(summary = "获得模型列表")
    public CommonResult<Long> getModelIdByType(
            @RequestParam("type") Integer type,
            @RequestParam(value = "platform", required = false) String platform) {
        List<AiModelDO> list = modelService.getModelListByStatusAndType(
                CommonStatusEnum.ENABLE.getStatus(), type, platform);
        if (ObjUtil.isEmpty(list)) {
            return success(null);
        }
        return success(list.get(0).getId());
    }

    @PostMapping("/textToSpeech")
    @Operation(summary = "文本转语音")
    public CommonResult<String> convertTextToSpeech(@RequestBody @Valid TtsVo ttsVo) {
        // 执行文本转语音
        String audioUrl = ttsService.convertTextToSpeech(ttsVo.getRoleId(), ttsVo.getContent());
        // 返回结果
        return success(audioUrl);
    }
    
    // ================ 智能问答 ================

    @Operation(summary = "创建智能问答")
    @PostMapping("/create-dialogue")
    public CommonResult<Long> createChatConversationMy(@RequestBody @Valid AiChatConversationCreateMyReqVO createReqVO) {
        return success(chatConversationService.createChatConversationMy(createReqVO, getLoginUserId()));
    }

//    @Operation(summary = "智能问答-获得智能问答列表")
//    @GetMapping("/dialogue-list")
//    public CommonResult<List<AiChatConversationRespVO>> getChatConversationMyList() {
//        List<AiChatConversationDO> list = chatConversationService.getChatConversationListByUserId(getLoginUserId());
//        return success(BeanUtils.toBean(list, AiChatConversationRespVO.class));
//    }

    @Operation(summary = "智能问答-发送消息（流式）", description = "流式返回，响应较快")
    @PostMapping(value = "/dialogue-send-stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<CommonResult<AiChatMessageSendRespVO>> sendChatMessageStream(@Valid @RequestBody AiChatMessageSendReqVO sendReqVO) {
        if (StringUtil.isNotEmpty(sendReqVO.getContentAnswer())) {
            return webAiService.sendSpecifiedAnswerStream(sendReqVO, getLoginUserId());
        }else{
            return chatMessageService.sendChatMessageStream(sendReqVO, getLoginUserId());
        }
    }

    // ================ 绘图管理 ================

    @Operation(summary = "生成图片")
    @PostMapping("/create-painting")
    public CommonResult<Long> drawImage(@Valid @RequestBody AiImageDrawReqVO drawReqVO) {
        return success(imageService.drawImage(getLoginUserId(), drawReqVO));
    }

    @GetMapping("/painting-get-my")
    @Operation(summary = "绘画-获取绘图记录")
    public CommonResult<AiImageRespVO> getImageMy(@RequestParam("id") Long id) {
        AiImageDO image = imageService.getImage(id);
        if (image == null || ObjUtil.notEqual(getLoginUserId(), image.getUserId())) {
            return success(null);
        }
        return success(BeanUtils.toBean(image, AiImageRespVO.class));
    }

    @GetMapping("/painting-get-mys")
    @Operation(summary = "获取【我的】绘图记录列表")
    @Parameter(name = "ids", required = true, description = "绘画编号数组", example = "1024,2048")
    public CommonResult<List<AiImageRespVO>> getImageListMyByIds(@RequestParam("ids") List<Long> ids) {
        List<AiImageDO> imageList = imageService.getImageList(ids);
//        imageList.removeIf(item -> !ObjUtil.equal(getLoginUserId(), item.getUserId()));
        return success(BeanUtils.toBean(imageList, AiImageRespVO.class));
    }

    // ================ 视频管理 ================

    @Operation(summary = "生成视频")
    @PostMapping("/create-video")
    public CommonResult<Long> drawVideo(@Valid @RequestBody AiVideoDrawReqVO drawReqVO) {
        return success(videoService.drawVideo(getLoginUserId(), drawReqVO));
    }

    @GetMapping("/video-get-my")
    @Operation(summary = "绘画-获取视频记录")
    public CommonResult<AiVideoRespVO> getVideoMy(@RequestParam("id") Long id) {
        AiVideoDO video = videoService.getVideo(id);
        if (video == null || ObjUtil.notEqual(getLoginUserId(), video.getUserId())) {
            return success(null);
        }
        return success(BeanUtils.toBean(video, AiVideoRespVO.class));
    }

    @GetMapping("/video-get-mys")
    @Operation(summary = "获取【我的】视频记录列表")
    @Parameter(name = "ids", required = true, description = "视频编号数组", example = "1024,2048")
    public CommonResult<List<AiVideoRespVO>> getVideoListMyByIds(@RequestParam("ids") List<Long> ids) {
        List<AiVideoDO> videoList = videoService.getVideoList(ids);
        return success(BeanUtils.toBean(videoList, AiVideoRespVO.class));
    }


    // ================ 视觉理解 ================

    @Operation(summary = "视觉理解-思考")
    @PostMapping("/vision-think")
    public CommonResult<AiVisionThinkRespVO> thinkVideo(@Valid @RequestBody AiVisionThinkReqVO visionThinkReqVO) {

        String apiKey = "4bb6060f-b4a1-4e0a-bf7b-71dcaa6311cb";
        // 创建ArkService实例
        ArkService arkService = ArkService.builder().apiKey(apiKey).baseUrl("https://ark.cn-beijing.volces.com/api/v3").build();

        List<String> promptImages = visionThinkReqVO.getPromptImage();
        String prompt = visionThinkReqVO.getPrompt();

        // 构建消息内容
        MessageContent.Builder messageContentBuilder = MessageContent.builder();

        // 添加所有图片
        if (promptImages != null && !promptImages.isEmpty()) {
            for (String imageUrl : promptImages) {
                messageContentBuilder.addListItem(
                        InputContentItemImage.builder().imageUrl(imageUrl).build()
                );
            }
        }

        // 添加文本提示
        if (prompt != null && !prompt.isEmpty()) {
            messageContentBuilder.addListItem(
                    InputContentItemText.builder().text(prompt).build()
            );
        }

        CreateResponsesRequest request = CreateResponsesRequest.builder()
                .model("doubao-seed-1-8-251228")
                .input(ResponsesInput.builder().addListItem(
                        ItemEasyMessage.builder().role(ResponsesConstants.MESSAGE_ROLE_USER).content(
                                messageContentBuilder.build()
                        ).build()
                ).build())
                .build();
        ResponseObject resp = arkService.createResponse(request);
        String text = extractTextFromResponse(resp);

        AiVisionThinkRespVO response = new AiVisionThinkRespVO();
        response.setResult(text);

        arkService.shutdownExecutor();
        return success(response);
    }

    public static String extractTextFromResponse(ResponseObject resp) {
        // 1. 先获取output列表
        if (resp == null || resp.getOutput() == null) {
            return "";
        }
        List<BaseItem> outputList = (List<BaseItem>) resp.getOutput();

        // 2. 遍历output找到ItemOutputMessage类型的项
        ItemOutputMessage messageItem = null;
        for (BaseItem item : outputList) {
            if (item instanceof ItemOutputMessage && "message".equals(item.getType())) {
                messageItem = (ItemOutputMessage) item;
                break;
            }
        }

        // 3. 如果没找到message项，返回空
        if (messageItem == null || messageItem.getContent() == null) {
            return "";
        }
        List<?> contentList = (List<?>) messageItem.getContent();

        // 4. 遍历content找到OutputContentItemText类型的项
        for (Object content : contentList) {
            if (content instanceof OutputContentItemText) {
                OutputContentItemText textItem = (OutputContentItemText) content;
                return textItem.getText(); // 直接返回提取到的text
            }
        }

        // 兜底返回空字符串
        return "";
    }

    // ================ 虚拟实验室 ================

    @GetMapping("/selectVirtualDevice")
    @Operation(summary = "获得虚拟设备分页")
    public CommonResult<PageResult<VirtualDeviceRespVO>> selectVirtualDevice(@Valid VirtualDevicePageReqVO pageReqVO) {
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        pageReqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
        PageResult<VirtualDeviceDO> pageResult = virtualDeviceService.getVirtualDevicePage(pageReqVO);
        return success(BeanUtils.toBean(pageResult, VirtualDeviceRespVO.class));
    }


    // ================ blockly 地图编辑游戏================

    @GetMapping("/selectMapGame")
    @Operation(summary = "获得AI-blockly地图编程游戏分页")
    public CommonResult<PageResult<MapGameVO>> selectMapGame(@Valid MapGamePageReqVO pageReqVO) {
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        pageReqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());

        PageResult<MapGameDO> pageResult = mapGameService.getMapGamePage(pageReqVO);
        return success(BeanUtils.toBean(pageResult, MapGameVO.class));
    }
    @GetMapping("/getMapGameById")
    @Operation(summary = "获得AI-blockly地图编程游戏详情")
    public CommonResult<MapGameRespVO> getMapGameById(@RequestParam("id") Integer id) {
        MapGameDO mapGame = mapGameService.getMapGame(id);
        if (mapGame == null) {
            return success(null);
        }
        return success(BeanUtils.toBean(mapGame, MapGameRespVO.class));
    }



}