package main

import (
	"bytes"
	"io"
	"log"
	"os"
	"path/filepath"
	"time"
	"x-agents/server/internal/config"
	"x-agents/server/internal/handler"
	"x-agents/server/internal/model"
	"x-agents/server/internal/repository"
	"x-agents/server/internal/service"

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

// Logger 日志记录器
type Logger struct {
	successLog *log.Logger
	errorLog   *log.Logger
}

func NewLogger() *Logger {
	// 创建日志目录
	today := time.Now().Format("2006-01-02")
	logDir := filepath.Join("logs", today)
	os.MkdirAll(logDir, 0755)

	// 成功日志
	successFile, _ := os.OpenFile(filepath.Join(logDir, "success.log"), os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
	successLogger := log.New(successFile, "", log.Ldate|log.Ltime|log.Lshortfile)

	// 错误日志
	errorFile, _ := os.OpenFile(filepath.Join(logDir, "failure.log"), os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
	errorLogger := log.New(errorFile, "", log.Ldate|log.Ltime|log.Lshortfile)

	return &Logger{
		successLog: successLogger,
		errorLog:   errorLogger,
	}
}

// LogRequest 记录请求
func (l *Logger) LogRequest(method, path, body string, status int, duration time.Duration) {
	entry := "[%s] %s %s %d %v"

	if status >= 400 {
		l.errorLog.Printf(entry, method, path, body, status, duration)
	} else {
		l.successLog.Printf(entry, method, path, body, status, duration)
	}
}

var logger *Logger

func main() {
	// 初始化日志
	logger = NewLogger()

	// 1. 加载配置
	cfg := config.Load()
	log.Printf("=== Server starting, port=%s ===", cfg.Port)

	// 2. 初始化数据库
	db, err := config.InitDB(cfg)
	if err != nil {
		log.Fatalf("Failed to connect database: %v", err)
	}

	// 3. 自动迁移表
	db.AutoMigrate(&model.DatabaseInfo{}, &model.SubTableInfo{}, &model.ModelInfo{})

	// 4. 初始化 Repository
	dbRepo := repository.NewDatabaseRepository(db)
	subTableRepo := repository.NewSubTableRepository(db)
	modelRepo := repository.NewModelRepository(db)

	// 5. 初始化 Service
	dbService := service.NewDatabaseService(dbRepo, subTableRepo)
	subTableService := service.NewSubTableService(subTableRepo, dbRepo)
	neo4jService := service.NewNeo4jService(dbRepo)
	modelService := service.NewModelService(modelRepo)
	uploadService, err := service.NewUploadService(cfg)
	if err != nil {
		log.Printf("Warning: Failed to initialize upload service: %v (files will not be available)", err)
	}

	// 6. 初始化 Handler
	dbHandler := handler.NewDatabaseHandler(dbService)
	subTableHandler := handler.NewSubTableHandler(subTableService)
	neo4jHandler := handler.NewNeo4jHandler(neo4jService)
	modelHandler := handler.NewModelHandler(modelService)
	systemHandler := handler.NewSystemHandler()
	var uploadHandler *handler.UploadHandler
	if uploadService != nil {
		uploadHandler = handler.NewUploadHandler(uploadService)
	}

	// 7. 设置路由
	r := gin.New()

	// 添加日志和恢复中间件
	r.Use(gin.Logger())
	r.Use(gin.Recovery())

	// 请求日志中间件
	r.Use(func(c *gin.Context) {
		start := time.Now()
		path := c.Request.URL.Path

		// 记录请求体
		var requestBody []byte
		if c.Request.Method == "POST" || c.Request.Method == "PUT" {
			requestBody, _ = io.ReadAll(c.Request.Body)
			c.Request.Body = io.NopCloser(bytes.NewBuffer(requestBody))
		}

		c.Next()

		// 记录响应日志
		latency := time.Since(start)
		status := c.Writer.Status()

		// 使用日志系统记录
		logger.LogRequest(c.Request.Method, path, string(requestBody), status, latency)
	})

	// CORS 中间件
	r.Use(func(c *gin.Context) {
		c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
		c.Writer.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
		c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")

		if c.Request.Method == "OPTIONS" {
			c.AbortWithStatus(204)
			return
		}

		c.Next()
	})

	// 数据库管理模块
	databaseGroup := r.Group("/database")
	{
		databaseGroup.GET("/list", dbHandler.List)
		databaseGroup.GET("/:id", dbHandler.GetByID)
		databaseGroup.POST("/check", dbHandler.Check)
		databaseGroup.POST("/add", dbHandler.Create)
		databaseGroup.PUT("/:id", dbHandler.Update)
		databaseGroup.DELETE("/:id", dbHandler.Delete)
		databaseGroup.POST("/graph/save", dbHandler.SaveGraph)
	}

	// 子表映射管理模块
	subTableGroup := r.Group("/sub-table")
	{
		subTableGroup.POST("/add", subTableHandler.Create)
		subTableGroup.GET("/:id", subTableHandler.GetByID)
		subTableGroup.GET("/database/:database_id", subTableHandler.ListByDatabase)
		subTableGroup.GET("/mapping/:database_id", subTableHandler.GetMappingFromFile)
		subTableGroup.GET("/ddl/:database_id", subTableHandler.GetTablesDDL)
		subTableGroup.PUT("/:id", subTableHandler.Update)
		subTableGroup.DELETE("/:id", subTableHandler.Delete)
	}

	// Neo4j 连接管理模块
	neo4jGroup := r.Group("/neo4j")
	{
		neo4jGroup.POST("/check", neo4jHandler.Check)
		neo4jGroup.POST("/graphs", neo4jHandler.GetGraphs)
		neo4jGroup.POST("/nodes", neo4jHandler.GetNodes)
		neo4jGroup.POST("/relationships", neo4jHandler.GetRelationships)
	}

	// Model 管理模块
	modelGroup := r.Group("/model")
	{
		modelGroup.GET("/list", modelHandler.List)
		modelGroup.POST("/test", modelHandler.Test)
		modelGroup.POST("/add", modelHandler.Create)
		modelGroup.GET("/:id", modelHandler.GetByID)
		modelGroup.PUT("/:id", modelHandler.Update)
		modelGroup.DELETE("/:id", modelHandler.Delete)
	}

	// 系统信息模块
	r.GET("/system/info", systemHandler.GetSystemInfo)

	// 文件上传模块
	if uploadHandler != nil {
		// 本地文件静态服务
		if cfg.UploadMode == "local" {
			r.Static("/files", cfg.UploadLocalPath)
		}
		// 上传路由
		r.POST("/upload", uploadHandler.Upload)
		r.DELETE("/upload/:filename", uploadHandler.Delete)
	}

	// 8. 启动服务
	log.Printf("Server starting on :%s", cfg.Port)
	if err := r.Run(":" + cfg.Port); err != nil {
		log.Fatalf("Failed to start server: %v", err)
	}
}
