package app

import (
	"net/http"

	"git.echol.cn/loser/ai_proxy/server/global"
	"git.echol.cn/loser/ai_proxy/server/model/app"
	"git.echol.cn/loser/ai_proxy/server/model/app/request"
	"git.echol.cn/loser/ai_proxy/server/model/common/response"
	"git.echol.cn/loser/ai_proxy/server/service"
	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
)

type AiProxyApi struct{}

var aiProxyService = service.ServiceGroupApp.AppServiceGroup.AiProxyService
var aiApiKeyService = service.ServiceGroupApp.AppServiceGroup.AiApiKeyService

// ChatCompletions OpenAI兼容的聊天补全接口
// @Tags AiProxy
// @Summary 聊天补全（OpenAI兼容）
// @accept application/json
// @Produce application/json
// @Param data body request.ChatCompletionRequest true "聊天请求"
// @Success 200 {object} response.ChatCompletionResponse "聊天响应"
// @Router /v1/chat/completions [post]
func (a *AiProxyApi) ChatCompletions(c *gin.Context) {
	var req request.ChatCompletionRequest
	err := c.ShouldBindJSON(&req)
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}

	// 获取 API Key 信息
	apiKeyInfo, exists := c.Get("ai_api_key")
	if !exists {
		c.JSON(http.StatusUnauthorized, gin.H{"error": "未找到API密钥信息"})
		return
	}
	apiKey := apiKeyInfo.(*app.AiApiKey)

	// 验证模型权限
	if req.Model != "" && !aiApiKeyService.CheckModelPermission(apiKey, req.Model) {
		c.JSON(http.StatusForbidden, gin.H{
			"error": gin.H{
				"message": "该API密钥无权使用此模型: " + req.Model,
				"type":    "invalid_request_error",
				"code":    "model_not_allowed",
			},
		})
		return
	}

	// 验证预设权限
	if req.PresetName != "" && !aiApiKeyService.CheckPresetPermission(apiKey, req.PresetName) {
		c.JSON(http.StatusForbidden, gin.H{
			"error": gin.H{
				"message": "该API密钥无权使用此预设: " + req.PresetName,
				"type":    "invalid_request_error",
				"code":    "preset_not_allowed",
			},
		})
		return
	}

	// 处理流式响应
	if req.Stream {
		aiProxyService.ProcessChatCompletionStream(c, &req)
		return
	}

	// 处理普通响应
	resp, err := aiProxyService.ProcessChatCompletion(c.Request.Context(), &req)
	if err != nil {
		global.GVA_LOG.Error("处理聊天请求失败!", zap.Error(err))
		response.FailWithMessage(err.Error(), c)
		return
	}

	c.JSON(200, resp)
}

// ListModels 获取可用模型列表
// @Tags AiProxy
// @Summary 获取可用模型列表（OpenAI兼容）
// @accept application/json
// @Produce application/json
// @Success 200 {object} response.ModelListResponse "模型列表"
// @Router /v1/models [get]
func (a *AiProxyApi) ListModels(c *gin.Context) {
	// 获取 API Key 信息
	apiKeyInfo, exists := c.Get("ai_api_key")
	if !exists {
		c.JSON(http.StatusUnauthorized, gin.H{"error": "未找到API密钥信息"})
		return
	}
	apiKey := apiKeyInfo.(*app.AiApiKey)

	// 获取可用模型列表
	models, err := aiProxyService.GetAvailableModels(apiKey)
	if err != nil {
		global.GVA_LOG.Error("获取模型列表失败!", zap.Error(err))
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(200, models)
}

// ClaudeMessages Claude API兼容的消息接口
// @Tags AiProxy
// @Summary 消息接口（Claude兼容）
// @accept application/json
// @Produce application/json
// @Param data body request.ClaudeMessageRequest true "消息请求"
// @Success 200 {object} response.ClaudeMessageResponse "消息响应"
// @Router /v1/messages [post]
func (a *AiProxyApi) ClaudeMessages(c *gin.Context) {
	var req request.ClaudeMessageRequest
	err := c.ShouldBindJSON(&req)
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}

	// 获取 API Key 信息
	apiKeyInfo, exists := c.Get("ai_api_key")
	if !exists {
		c.JSON(http.StatusUnauthorized, gin.H{"error": "未找到API密钥信息"})
		return
	}
	apiKey := apiKeyInfo.(*app.AiApiKey)

	// 验证模型权限
	if req.Model != "" && !aiApiKeyService.CheckModelPermission(apiKey, req.Model) {
		c.JSON(http.StatusForbidden, gin.H{
			"error": gin.H{
				"message": "该API密钥无权使用此模型: " + req.Model,
				"type":    "invalid_request_error",
				"code":    "model_not_allowed",
			},
		})
		return
	}

	// 验证预设权限
	if req.PresetName != "" && !aiApiKeyService.CheckPresetPermission(apiKey, req.PresetName) {
		c.JSON(http.StatusForbidden, gin.H{
			"error": gin.H{
				"message": "该API密钥无权使用此预设: " + req.PresetName,
				"type":    "invalid_request_error",
				"code":    "preset_not_allowed",
			},
		})
		return
	}

	// 处理流式响应
	if req.Stream {
		aiProxyService.ProcessClaudeMessageStream(c, &req)
		return
	}

	// 处理普通响应
	resp, err := aiProxyService.ProcessClaudeMessage(c.Request.Context(), &req)
	if err != nil {
		global.GVA_LOG.Error("处理Claude消息请求失败!", zap.Error(err))
		response.FailWithMessage(err.Error(), c)
		return
	}

	c.JSON(200, resp)
}
