package handlers

import (
	"fmt"
	"net/http"
	"strings"

	"software-download-center/database"
	"software-download-center/utils"

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

// GetDatabaseInfo 获取数据库信息
func GetDatabaseInfo(c *gin.Context) {
	dbType := database.GetDBType()
	osInfo := utils.GetOSInfo()

	var dbInfo gin.H
	if dbType == "mysql" {
		dbInfo = gin.H{
			"type":   "MySQL",
			"status": "connected",
		}
	} else {
		dbInfo = gin.H{
			"type":        "SQLite",
			"status":      "connected",
			"file":        "data/app.db",
			"cgo_support": osInfo.IsCGO,
		}
	}

	c.JSON(http.StatusOK, gin.H{
		"database": dbInfo,
		"os": gin.H{
			"os":   osInfo.OS,
			"arch": osInfo.Arch,
		},
	})
}

// ConvertDatabaseRequest 数据库转换请求
type ConvertDatabaseRequest struct {
	TargetType string `json:"target_type" binding:"required,oneof=sqlite mysql"`
}

// ConvertDatabase 转换数据库
func ConvertDatabase(c *gin.Context) {
	var req ConvertDatabaseRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"error": "请求参数错误: " + err.Error(),
		})
		return
	}

	logger := utils.NewLogger()

	if err := database.ConvertDatabase(req.TargetType, logger); err != nil {
		AddLog("ERROR", fmt.Sprintf("数据库转换失败: %s", err.Error()))
		c.JSON(http.StatusInternalServerError, gin.H{
			"error": "数据库转换失败: " + err.Error(),
		})
		return
	}

	AddLog("INFO", fmt.Sprintf("数据库转换成功: %s", req.TargetType))
	c.JSON(http.StatusOK, gin.H{
		"message": fmt.Sprintf("数据库已成功转换为 %s", strings.ToUpper(req.TargetType)),
		"type":    req.TargetType,
	})
}

// UpdateDatabasePasswordRequest 更新数据库密码请求
type UpdateDatabasePasswordRequest struct {
	CurrentPassword string `json:"current_password" binding:"required"`
	NewPassword     string `json:"new_password" binding:"required,min=1"`
	ConfirmPassword string `json:"confirm_password" binding:"required"`
}

// UpdateDatabasePassword 更新数据库 root 密码
func UpdateDatabasePassword(c *gin.Context) {
	var req UpdateDatabasePasswordRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		AddLog("WARN", fmt.Sprintf("更新数据库密码请求参数错误: %s (IP: %s)", err.Error(), c.ClientIP()))
		c.JSON(http.StatusBadRequest, gin.H{
			"error": "请求参数错误: " + err.Error(),
		})
		return
	}

	// 验证新密码和确认密码是否一致
	if req.NewPassword != req.ConfirmPassword {
		AddLog("WARN", fmt.Sprintf("更新数据库密码失败（密码不一致）(IP: %s)", c.ClientIP()))
		c.JSON(http.StatusBadRequest, gin.H{
			"error": "新密码和确认密码不一致",
		})
		return
	}

	// 检查当前数据库类型
	dbType := database.GetDBType()
	if dbType != "mysql" {
		AddLog("WARN", fmt.Sprintf("更新数据库密码失败（当前数据库不是 MySQL）(IP: %s)", c.ClientIP()))
		c.JSON(http.StatusBadRequest, gin.H{
			"error": "当前数据库类型不是 MySQL，无法修改密码",
		})
		return
	}

	// 验证当前密码
	if err := database.VerifyMySQLPassword(req.CurrentPassword); err != nil {
		AddLog("WARN", fmt.Sprintf("更新数据库密码失败（当前密码验证失败）(IP: %s)", c.ClientIP()))
		c.JSON(http.StatusUnauthorized, gin.H{
			"error": "当前密码错误",
		})
		return
	}

	// 更新密码
	if err := database.UpdateMySQLPassword(req.NewPassword); err != nil {
		AddLog("ERROR", fmt.Sprintf("更新数据库密码失败: %s (IP: %s)", err.Error(), c.ClientIP()))
		c.JSON(http.StatusInternalServerError, gin.H{
			"error": "更新密码失败: " + err.Error(),
		})
		return
	}

	AddLog("INFO", fmt.Sprintf("数据库 root 密码更新成功 (IP: %s)", c.ClientIP()))
	c.JSON(http.StatusOK, gin.H{
		"message": "数据库密码更新成功！请更新环境变量 DB_PASSWORD 并重启服务器以使新密码生效。",
	})
}

// GetDatabaseConfig 获取数据库配置信息（不包含敏感信息）
func GetDatabaseConfig(c *gin.Context) {
	config := database.GetDatabaseConfig()

	// 隐藏敏感信息
	safeConfig := gin.H{
		"type":         config.Type,
		"host":         config.Host,
		"port":         config.Port,
		"user":         config.User,
		"database":     config.Database,
		"table_prefix": config.TablePrefix,
		"has_password": config.Password != "",
	}

	c.JSON(http.StatusOK, gin.H{
		"config": safeConfig,
	})
}

// UpdateDatabaseConfigRequest 更新数据库配置请求
type UpdateDatabaseConfigRequest struct {
	Type        string `json:"type" binding:"required,oneof=sqlite mysql"`
	Host        string `json:"host"`
	Port        string `json:"port"`
	User        string `json:"user"`
	Password    string `json:"password"`
	Database    string `json:"database"`
	TablePrefix string `json:"table_prefix"`
	DSN         string `json:"dsn"`
}

// UpdateDatabaseConfig 更新数据库配置（需要重新连接）
func UpdateDatabaseConfig(c *gin.Context) {
	var req UpdateDatabaseConfigRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"error": "请求参数错误: " + err.Error(),
		})
		return
	}

	// 验证必填字段
	if req.Type == "mysql" {
		if req.Host == "" || req.Port == "" || req.User == "" || req.Database == "" {
			c.JSON(http.StatusBadRequest, gin.H{
				"error": "MySQL 配置不完整：需要 host, port, user, database",
			})
			return
		}
	} else if req.Type == "sqlite" {
		if req.DSN == "" {
			req.DSN = "data"
		}
	}

	// 构建数据库配置
	config := &database.DatabaseConfig{
		Type:        req.Type,
		Host:        req.Host,
		Port:        req.Port,
		User:        req.User,
		Password:    req.Password,
		Database:    req.Database,
		TablePrefix: req.TablePrefix,
		DSN:         req.DSN,
	}

	// 测试连接
	if err := database.InitDBWithConfig(config); err != nil {
		AddLog("ERROR", fmt.Sprintf("数据库配置更新失败: %s (IP: %s)", err.Error(), c.ClientIP()))
		c.JSON(http.StatusInternalServerError, gin.H{
			"error": "数据库连接失败: " + err.Error(),
		})
		return
	}

	AddLog("INFO", fmt.Sprintf("数据库配置更新成功: 类型=%s (IP: %s)", req.Type, c.ClientIP()))

	c.JSON(http.StatusOK, gin.H{
		"message": "数据库配置已更新，请重启服务器以应用更改",
		"type":    req.Type,
	})
}
