package main

import (
	"context"
	"log"
	"net/http"
	"time"

	"github.com/gin-contrib/cors"
	"github.com/gin-gonic/gin"

	"mengyastore-backend/internal/auth"
	"mengyastore-backend/internal/config"
	"mengyastore-backend/internal/database"
	"mengyastore-backend/internal/handlers"
	"mengyastore-backend/internal/mq"
	"mengyastore-backend/internal/storage"
)

func main() {
	cfg, err := config.Load()
	if err != nil {
		log.Fatalf("加载配置失败: %v", err)
	}
	startedAt := time.Now()

	// 初始化数据库连接
	db, err := database.Open(cfg.DatabaseDSN)
	if err != nil {
		log.Fatalf("初始化数据库失败: %v", err)
	}

	store, err := storage.NewProductStore(db)
	if err != nil {
		log.Fatalf("初始化商品存储失败: %v", err)
	}
	orderStore, err := storage.NewOrderStore(db)
	if err != nil {
		log.Fatalf("初始化订单存储失败: %v", err)
	}
	siteStore, err := storage.NewSiteStore(db)
	if err != nil {
		log.Fatalf("初始化站点存储失败: %v", err)
	}
	wishlistStore, err := storage.NewWishlistStore(db)
	if err != nil {
		log.Fatalf("初始化收藏夹存储失败: %v", err)
	}
	chatStore, err := storage.NewChatStore(db)
	if err != nil {
		log.Fatalf("初始化聊天存储失败: %v", err)
	}

	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()

	var mqClient *mq.Client
	if cfg.RabbitMQEnabled {
		if cfg.RabbitMQURL == "" {
			log.Println("[MQ] 已启用但未配置连接串：请设置 RABBITMQ_URL，或设置 RABBITMQ_PASSWORD（及可选 RABBITMQ_HOST/RABBITMQ_VHOST）")
		} else {
			c, err := mq.New(cfg.RabbitMQURL, cfg.RabbitMQEnv)
			if err != nil {
				log.Printf("[MQ] 连接失败，将仅用直发邮件降级: %v", err)
			} else {
				mqClient = c
				defer mqClient.Close()
				go mqClient.StartConsumer(ctx, siteStore)
				log.Printf("[MQ] 已连接 env=%s exchange=%s", cfg.RabbitMQEnv, mq.ExchangeName(cfg.RabbitMQEnv))
			}
		}
	}

	r := gin.Default()
	r.Use(cors.New(cors.Config{
		AllowOrigins:     []string{"*"},
		AllowMethods:     []string{"GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"},
		AllowHeaders:     []string{"Origin", "Content-Type", "Accept", "Authorization", "X-Admin-Token"},
		ExposeHeaders:    []string{"Content-Length"},
		AllowCredentials: false,
		MaxAge:           12 * time.Hour,
	}))

	r.GET("/api/health", func(c *gin.Context) {
		resp := gin.H{"status": "ok", "rabbitmq": "disabled"}
		if mqClient != nil {
			if err := mqClient.Ping(); err != nil {
				resp["rabbitmq"] = "error: " + err.Error()
			} else {
				resp["rabbitmq"] = "ok"
			}
		}
		c.JSON(http.StatusOK, resp)
	})

	authClient := auth.NewSproutGateClient(cfg.AuthAPIURL)

	publicHandler := handlers.NewPublicHandler(store)
	adminHandler := handlers.NewAdminHandler(store, cfg, siteStore, orderStore, chatStore)
	orderHandler := handlers.NewOrderHandler(store, orderStore, siteStore, authClient, mqClient)
	statsHandler := handlers.NewStatsHandler(orderStore, siteStore)
	wishlistHandler := handlers.NewWishlistHandler(wishlistStore, authClient)
	chatHandler := handlers.NewChatHandler(chatStore, authClient)
	statusHandler := handlers.NewSystemStatusHandler(cfg, db, mqClient, startedAt)

	r.GET("/api/products", publicHandler.ListProducts)
	r.POST("/api/checkout", orderHandler.CreateOrder)
	r.POST("/api/products/:id/view", publicHandler.RecordProductView)
	r.GET("/api/stats", statsHandler.GetStats)
	r.POST("/api/site/visit", statsHandler.RecordVisit)
	r.GET("/api/site/maintenance", statsHandler.GetMaintenance)
	r.GET("/api/orders", orderHandler.ListMyOrders)
	r.POST("/api/orders/:id/confirm", orderHandler.ConfirmOrder)

	r.POST("/api/admin/verify", adminHandler.VerifyAdminToken)
	r.GET("/api/admin/products", adminHandler.ListAllProducts)
	r.POST("/api/admin/products", adminHandler.CreateProduct)
	r.PUT("/api/admin/products/:id", adminHandler.UpdateProduct)
	r.PATCH("/api/admin/products/:id/status", adminHandler.ToggleProduct)
	r.DELETE("/api/admin/products/:id", adminHandler.DeleteProduct)
	r.POST("/api/admin/site/maintenance", adminHandler.SetMaintenance)
	r.GET("/api/admin/site/smtp", adminHandler.GetSMTPConfig)
	r.POST("/api/admin/site/smtp", adminHandler.SetSMTPConfig)
	r.GET("/api/admin/orders", adminHandler.ListAllOrders)
	r.DELETE("/api/admin/orders/:id", adminHandler.DeleteOrder)
	r.GET("/api/admin/system-status", statusHandler.GetSystemStatus)

	r.GET("/api/wishlist", wishlistHandler.GetWishlist)
	r.POST("/api/wishlist", wishlistHandler.AddToWishlist)
	r.DELETE("/api/wishlist/:id", wishlistHandler.RemoveFromWishlist)

	// 用户聊天路由
	r.GET("/api/chat/messages", chatHandler.GetMyMessages)
	r.POST("/api/chat/messages", chatHandler.SendMyMessage)

	// 管理员聊天路由
	r.GET("/api/admin/chat", adminHandler.GetAllConversations)
	r.GET("/api/admin/chat/:account", adminHandler.GetConversation)
	r.POST("/api/admin/chat/:account", adminHandler.AdminReply)
	r.DELETE("/api/admin/chat/:account", adminHandler.ClearConversation)

	log.Println("萌芽小店后端启动于 http://localhost:8080")
	if err := r.Run(":8080"); err != nil {
		log.Fatalf("服务器启动失败: %v", err)
	}
}
