package controllers

import (
	"ems-backend/models"
	"ems-backend/services"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"net/http"
	"strconv"
	"strings"
	"time"

	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
)

// GetAIConfig 获取AI配置
func GetAIConfig(c *gin.Context) {
	configs := make(map[string]string)
	keys := []string{"ai_api_url", "ai_api_key", "ai_model", "ai_alert_threshold", "ai_auto_ack"}
	
	for _, k := range keys {
		var config models.SysConfig
		if err := models.DB.Where("config_key = ?", k).First(&config).Error; err == nil {
			configs[k] = config.ConfigValue
		} else {
            // 默认值
            if k == "ai_alert_threshold" {
                configs[k] = "200"
            } else if k == "ai_auto_ack" {
                configs[k] = "false"
            } else if k == "ai_model" {
                configs[k] = "gpt-3.5-turbo"
            } else {
                configs[k] = ""
            }
        }
	}
	c.JSON(http.StatusOK, configs)
}

// UpdateAIConfig 更新AI配置
func UpdateAIConfig(c *gin.Context) {
	// 使用 interface{} 接收，防止前端传数字导致 BindJSON 失败
	var input map[string]interface{}
	if err := c.ShouldBindJSON(&input); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid JSON format: " + err.Error()})
		return
	}

	tx := models.DB.Begin()
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
		}
	}()

	for k, v := range input {
		// 强制转换为字符串
		valStr := fmt.Sprintf("%v", v)

		var config models.SysConfig
		err := tx.Where("config_key = ?", k).First(&config).Error
		
		if errors.Is(err, gorm.ErrRecordNotFound) {
			config = models.SysConfig{ConfigKey: k, ConfigValue: valStr, ConfigType: "Y"}
			if err := tx.Create(&config).Error; err != nil {
				tx.Rollback()
				c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create config " + k})
				return
			}
		} else if err != nil {
			tx.Rollback()
			c.JSON(http.StatusInternalServerError, gin.H{"error": "Database error checking " + k})
			return
		} else {
			config.ConfigValue = valStr
			if err := tx.Save(&config).Error; err != nil {
				tx.Rollback()
				c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to update config " + k})
				return
			}
		}
	}

	if err := tx.Commit().Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to commit transaction"})
		return
	}

	c.JSON(http.StatusOK, gin.H{"message": "配置已更新"})
}

// TestAIConnection 测试AI连接
func TestAIConnection(c *gin.Context) {
	var input struct {
		APIUrl string `json:"ai_api_url"`
		APIKey string `json:"ai_api_key"`
        Model  string `json:"ai_model"`
	}
	if err := c.ShouldBindJSON(&input); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	if input.APIUrl == "" || input.APIKey == "" {
		c.JSON(http.StatusBadRequest, gin.H{"error": "API URL和Key不能为空"})
		return
	}

    model := input.Model
    if model == "" {
        model = "gpt-3.5-turbo"
    }

    // 智能修正 URL
    chatUrl := services.NormalizeChatUrl(input.APIUrl)

	// 简单的 Ping 请求 (OpenAI 格式)
	if _, err := services.FetchAIResponse(chatUrl, input.APIKey, model, "Hello, are you there? Reply with 'Yes'."); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "连接失败: " + err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{"message": "连接成功"})
}

// GetRemoteModels 获取远程模型列表
func GetRemoteModels(c *gin.Context) {
	var input struct {
		APIUrl string `json:"ai_api_url"`
		APIKey string `json:"ai_api_key"`
	}
	if err := c.ShouldBindJSON(&input); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	if input.APIUrl == "" || input.APIKey == "" {
		c.JSON(http.StatusBadRequest, gin.H{"error": "API URL和Key不能为空"})
		return
	}

    // 推断 Models API 地址
    modelsUrl := normalizeModelsUrl(input.APIUrl)

    req, err := http.NewRequest("GET", modelsUrl, nil)
    if err != nil {
        c.JSON(http.StatusInternalServerError, gin.H{"error": "Request creation failed: " + err.Error()})
        return
    }
    
    req.Header.Set("Authorization", "Bearer "+input.APIKey)
    client := &http.Client{Timeout: 10 * time.Second}
    
    resp, err := client.Do(req)
    if err != nil {
        c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to fetch models: " + err.Error()})
        return
    }
    defer resp.Body.Close()
    
    bodyBytes, _ := io.ReadAll(resp.Body)
    if resp.StatusCode != 200 {
         c.JSON(http.StatusInternalServerError, gin.H{"error": fmt.Sprintf("API Error (%d): %s", resp.StatusCode, string(bodyBytes))})
         return
    }
    
    // 解析 OpenAI 格式的模型列表
    var result struct {
        Data []struct {
            ID string `json:"id"`
        } `json:"data"`
    }
    
    if err := json.Unmarshal(bodyBytes, &result); err != nil {
         c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to parse models response: " + err.Error()})
         return
    }
    
    var models []string
    for _, m := range result.Data {
        models = append(models, m.ID)
    }
    
    c.JSON(http.StatusOK, gin.H{"models": models})
}

// GenerateAIReport 生成AI报表
func GenerateAIReport(c *gin.Context) {
    // 1. 检查当前实时告警数量
    var count int64
    var alarms []models.AlarmLog
    models.DB.Model(&models.AlarmLog{}).Where("status = ?", "ACTIVE").Count(&count)
    // 获取部分告警内容用于生成 Prompt
    models.DB.Model(&models.AlarmLog{}).Where("status = ?", "ACTIVE").Limit(20).Order("start_time desc").Find(&alarms)
    
    // 2. 调用 Service 生成报表
    report, err := services.GenerateAIReportInternal(alarms, "实时告警分析报告 - " + time.Now().Format("2006-01-02 15:04:05"), "ALARM_ANALYSIS")
    if err != nil {
        c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
        return
    }

    c.JSON(http.StatusOK, report)
}

// GetAIReports 获取报表列表
func GetAIReports(c *gin.Context) {
    page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
    pageSize, _ := strconv.Atoi(c.DefaultQuery("pageSize", "10"))
    keyword := c.Query("keyword")

    query := models.DB.Model(&models.AIAnalysisReport{})
    if keyword != "" {
        query = query.Where("title LIKE ?", "%"+keyword+"%")
    }

    var total int64
    query.Count(&total)

    var reports []models.AIAnalysisReport
    offset := (page - 1) * pageSize
    query.Order("created_at desc").Limit(pageSize).Offset(offset).Find(&reports)

    c.JSON(http.StatusOK, gin.H{"data": reports, "total": total})
}

// GetAIReportDetail 获取报表详情
func GetAIReportDetail(c *gin.Context) {
    id := c.Param("id")
    var report models.AIAnalysisReport
    if err := models.DB.Where("id = ?", id).First(&report).Error; err != nil {
        c.JSON(http.StatusNotFound, gin.H{"error": "Report not found"})
        return
    }
    c.JSON(http.StatusOK, report)
}

// 内部辅助函数

// normalizeModelsUrl 规范化 Models 接口地址
func normalizeModelsUrl(inputUrl string) string {
    inputUrl = strings.TrimSpace(inputUrl)
    // 如果包含 /chat/completions，替换为 /models
    if strings.Contains(inputUrl, "/chat/completions") {
        return strings.Replace(inputUrl, "/chat/completions", "/models", 1)
    }
    // 如果是 /models 结尾，直接用
    if strings.HasSuffix(inputUrl, "/models") {
        return inputUrl
    }
    // 如果是 /v1 结尾
    if strings.HasSuffix(inputUrl, "/v1") {
        return strings.TrimRight(inputUrl, "/") + "/models"
    }
    // 默认追加
    return strings.TrimRight(inputUrl, "/") + "/models"
}
