package app

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"net/http"
	"time"

	"git.echol.cn/loser/st/server/global"
	"git.echol.cn/loser/st/server/model/app"
	"git.echol.cn/loser/st/server/model/app/request"
	"git.echol.cn/loser/st/server/model/app/response"
	"gorm.io/datatypes"
	"gorm.io/gorm"
)

type AIConfigService struct{}

// CreateAIConfig 创建AI配置
func (s *AIConfigService) CreateAIConfig(req *request.CreateAIConfigRequest) (*response.AIConfigResponse, error) {
	// 序列化 JSON 字段
	settingsJSON, _ := json.Marshal(req.Settings)

	config := app.AIConfig{
		Name:         req.Name,
		Provider:     req.Provider,
		BaseURL:      req.BaseURL,
		APIKey:       req.APIKey,
		DefaultModel: req.DefaultModel,
		Settings:     datatypes.JSON(settingsJSON),
		Models:       datatypes.JSON("[]"),
		IsActive:     true,
		IsDefault:    false,
	}

	err := global.GVA_DB.Create(&config).Error
	if err != nil {
		return nil, err
	}

	resp := response.ToAIConfigResponse(&config)
	return &resp, nil
}

// GetAIConfigList 获取AI配置列表
func (s *AIConfigService) GetAIConfigList() (*response.AIConfigListResponse, error) {
	var configs []app.AIConfig
	var total int64

	db := global.GVA_DB.Model(&app.AIConfig{})

	err := db.Count(&total).Error
	if err != nil {
		return nil, err
	}

	err = db.Order("is_default DESC, created_at DESC").Find(&configs).Error
	if err != nil {
		return nil, err
	}

	list := make([]response.AIConfigResponse, len(configs))
	for i, config := range configs {
		list[i] = response.ToAIConfigResponse(&config)
	}

	return &response.AIConfigListResponse{
		List:  list,
		Total: total,
	}, nil
}

// UpdateAIConfig 更新AI配置
func (s *AIConfigService) UpdateAIConfig(id uint, req *request.UpdateAIConfigRequest) error {
	var config app.AIConfig

	err := global.GVA_DB.First(&config, id).Error
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return errors.New("配置不存在")
		}
		return err
	}

	updates := map[string]interface{}{}

	if req.Name != "" {
		updates["name"] = req.Name
	}
	if req.BaseURL != "" {
		updates["base_url"] = req.BaseURL
	}
	// 只有当 API Key 不是脱敏格式时才更新
	// 脱敏格式: xxxx****xxxx
	if req.APIKey != "" && !isMaskedAPIKey(req.APIKey) {
		updates["api_key"] = req.APIKey
	}
	if req.DefaultModel != "" {
		updates["default_model"] = req.DefaultModel
	}
	if req.Settings != nil {
		settingsJSON, _ := json.Marshal(req.Settings)
		updates["settings"] = datatypes.JSON(settingsJSON)
	}
	if req.IsActive != nil {
		updates["is_active"] = *req.IsActive
	}
	if req.IsDefault != nil && *req.IsDefault {
		// 如果设置为默认，先取消其他配置的默认状态
		global.GVA_DB.Model(&app.AIConfig{}).Where("id != ?", id).Update("is_default", false)
		updates["is_default"] = true
	}

	return global.GVA_DB.Model(&config).Updates(updates).Error
}

// DeleteAIConfig 删除AI配置
func (s *AIConfigService) DeleteAIConfig(id uint) error {
	result := global.GVA_DB.Delete(&app.AIConfig{}, id)
	if result.Error != nil {
		return result.Error
	}
	if result.RowsAffected == 0 {
		return errors.New("配置不存在")
	}
	return nil
}

// GetModels 获取可用模型列表
func (s *AIConfigService) GetModels(req *request.GetModelsRequest) (*response.GetModelsResponse, error) {
	client := &http.Client{Timeout: 20 * time.Second}

	// 构建请求
	modelsURL := req.BaseURL + "/models"
	httpReq, err := http.NewRequest("GET", modelsURL, nil)
	if err != nil {
		return nil, err
	}

	// 设置认证头
	if req.Provider == "openai" || req.Provider == "custom" {
		httpReq.Header.Set("Authorization", "Bearer "+req.APIKey)
	} else if req.Provider == "anthropic" {
		httpReq.Header.Set("x-api-key", req.APIKey)
		httpReq.Header.Set("anthropic-version", "2023-06-01")
	}

	// 发送请求
	resp, err := client.Do(httpReq)
	if err != nil {
		return nil, fmt.Errorf("请求失败: %v", err)
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		body, _ := io.ReadAll(resp.Body)
		return nil, fmt.Errorf("API返回错误 %d: %s", resp.StatusCode, string(body))
	}

	// 解析响应
	var result struct {
		Data []struct {
			ID      string `json:"id"`
			Object  string `json:"object"`
			OwnedBy string `json:"owned_by"`
		} `json:"data"`
	}

	err = json.NewDecoder(resp.Body).Decode(&result)
	if err != nil {
		return nil, fmt.Errorf("解析响应失败: %v", err)
	}

	// 转换为模型信息
	models := make([]response.ModelInfo, 0, len(result.Data))
	for _, model := range result.Data {
		models = append(models, response.ModelInfo{
			ID:      model.ID,
			Name:    model.ID,
			OwnedBy: model.OwnedBy,
		})
	}

	return &response.GetModelsResponse{Models: models}, nil
}

// GetModelsByID 通过配置ID获取模型列表（使用数据库中的完整API Key）
func (s *AIConfigService) GetModelsByID(id uint) (*response.GetModelsResponse, error) {
	var config app.AIConfig
	err := global.GVA_DB.First(&config, id).Error
	if err != nil {
		return nil, errors.New("配置不存在")
	}

	// 使用数据库中的完整 API Key
	req := &request.GetModelsRequest{
		Provider: config.Provider,
		BaseURL:  config.BaseURL,
		APIKey:   config.APIKey,
	}

	return s.GetModels(req)
}

// TestAIConfig 测试AI配置
func (s *AIConfigService) TestAIConfig(req *request.TestAIConfigRequest) (*response.TestAIConfigResponse, error) {
	startTime := time.Now()
	client := &http.Client{Timeout: 60 * time.Second}

	// 构建测试请求
	var requestBody map[string]interface{}
	var endpoint string

	if req.Provider == "openai" || req.Provider == "custom" {
		endpoint = req.BaseURL + "/chat/completions"
		model := req.Model
		if model == "" {
			model = "gpt-3.5-turbo"
		}
		requestBody = map[string]interface{}{
			"model": model,
			"messages": []map[string]string{
				{"role": "user", "content": "Hello"},
			},
			"max_tokens": 10,
		}
	} else if req.Provider == "anthropic" {
		endpoint = req.BaseURL + "/messages"
		model := req.Model
		if model == "" {
			model = "claude-3-haiku-20240307"
		}
		requestBody = map[string]interface{}{
			"model": model,
			"messages": []map[string]string{
				{"role": "user", "content": "Hello"},
			},
			"max_tokens": 10,
		}
	}

	bodyBytes, _ := json.Marshal(requestBody)
	httpReq, err := http.NewRequest("POST", endpoint, bytes.NewBuffer(bodyBytes))
	if err != nil {
		return &response.TestAIConfigResponse{
			Success: false,
			Message: fmt.Sprintf("创建请求失败: %v", err),
		}, nil
	}

	// 设置请求头
	httpReq.Header.Set("Content-Type", "application/json")
	if req.Provider == "openai" || req.Provider == "custom" {
		httpReq.Header.Set("Authorization", "Bearer "+req.APIKey)
	} else if req.Provider == "anthropic" {
		httpReq.Header.Set("x-api-key", req.APIKey)
		httpReq.Header.Set("anthropic-version", "2023-06-01")
	}

	// 发送请求
	resp, err := client.Do(httpReq)
	latency := time.Since(startTime).Milliseconds()

	if err != nil {
		return &response.TestAIConfigResponse{
			Success: false,
			Message: fmt.Sprintf("连接失败: %v", err),
			Latency: latency,
		}, nil
	}
	defer resp.Body.Close()

	body, _ := io.ReadAll(resp.Body)

	if resp.StatusCode != http.StatusOK {
		return &response.TestAIConfigResponse{
			Success: false,
			Message: fmt.Sprintf("API返回错误 %d: %s", resp.StatusCode, string(body)),
			Latency: latency,
		}, nil
	}

	return &response.TestAIConfigResponse{
		Success: true,
		Message: "连接成功，AI响应正常",
		Latency: latency,
	}, nil
}

// TestAIConfigByID 通过ID测试AI配置（使用数据库中的完整API Key）
func (s *AIConfigService) TestAIConfigByID(id uint) (*response.TestAIConfigResponse, error) {
	var config app.AIConfig
	err := global.GVA_DB.First(&config, id).Error
	if err != nil {
		return nil, errors.New("配置不存在")
	}

	// 使用数据库中的完整 API Key 进行测试
	req := &request.TestAIConfigRequest{
		Provider: config.Provider,
		BaseURL:  config.BaseURL,
		APIKey:   config.APIKey, // 使用完整的 API Key，而不是脱敏后的
		Model:    config.DefaultModel,
	}

	return s.TestAIConfig(req)
}

// isMaskedAPIKey 检查是否是脱敏的 API Key
func isMaskedAPIKey(apiKey string) bool {
	// 脱敏格式: xxxx****xxxx 或 ****
	return len(apiKey) > 0 && (apiKey == "****" || (len(apiKey) > 8 && apiKey[4:len(apiKey)-4] == "****"))
}
