package server

import (
	"errors"
	"fmt"
	"github.com/gofiber/fiber/v2/log"
	"os"
	"strings"

	"github.com/goccy/go-json"

	"github.com/gofiber/fiber/v2"
	"github.com/gofiber/fiber/v2/middleware/cors"
	"github.com/gofiber/fiber/v2/middleware/logger"
	"github.com/gofiber/fiber/v2/middleware/recover"
	"github.com/gofiber/template/html/v2"

	"gitee.ltd/lxh/wechat-robot/internal/config"
	"gitee.ltd/lxh/wechat-robot/internal/handler"
	"gitee.ltd/lxh/wechat-robot/internal/middleware"
)

// Server 表示HTTP服务器
type Server struct {
	app    *fiber.App
	config *config.Config
}

// New 创建新的服务器实例
func New(cfg *config.Config) *Server {
	// 确保视图目录存在
	viewsDir := "./internal/view"
	if _, err := os.Stat(viewsDir); os.IsNotExist(err) {
		log.Fatalf("视图目录不存在: %s", viewsDir)
	}

	// 初始化模板引擎
	engine := html.New(viewsDir, ".html")
	engine.Reload(cfg.Server.Env == "development") // 开发环境下启用热重载
	engine.Debug(cfg.Server.Env == "development")  // 增加Debug输出

	// 添加自定义模板函数
	engine.AddFunc("sub", func(a, b int) int {
		return a - b
	})

	// 添加map函数，用于在模板中创建映射
	engine.AddFunc("map", func(values ...any) map[string]any {
		if len(values)%2 != 0 {
			return nil
		}

		m := make(map[string]any, len(values)/2)
		for i := 0; i < len(values); i += 2 {
			if key, ok := values[i].(string); ok {
				m[key] = values[i+1]
			}
		}

		return m
	})

	// 创建Fiber应用
	app := fiber.New(fiber.Config{
		Views:             engine,
		ViewsLayout:       "layouts/main", // 默认布局
		EnablePrintRoutes: cfg.Server.Env == "development",
		JSONEncoder:       json.Marshal,
		JSONDecoder:       json.Unmarshal,
		ErrorHandler: func(c *fiber.Ctx, err error) error {
			// 详细错误日志
			log.Errorf("错误: %+v\n请求路径: %s\n", err, c.Path())

			code := fiber.StatusInternalServerError
			var e *fiber.Error
			if errors.As(err, &e) {
				code = e.Code
			}

			// 对于API请求返回JSON响应
			if strings.HasPrefix(c.Path(), "/api/") {
				return c.Status(code).JSON(fiber.Map{
					"success": false,
					"message": err.Error(),
				})
			}

			// 对于页面请求渲染错误页面，但使用简化的布局以避免布局中的错误
			return c.Status(code).Render("error", fiber.Map{
				"Title":        fmt.Sprintf("Error %d", code),
				"StatusCode":   code,
				"ErrorMessage": err.Error(),
				"NoLayout":     true, // 不使用复杂布局，避免更多错误
			})
		},
	})

	// 注册中间件
	app.Use(recover.New())
	app.Use(logger.New(logger.Config{
		Format:     "[${time}] ${status} - ${ip} - ${latency} ${method} ${path}\n",
		TimeFormat: "2006-01-02 15:04:05",
	}))
	app.Use(cors.New())

	// 静态文件服务
	app.Static("/public", "./public")

	return &Server{
		app:    app,
		config: cfg,
	}
}

// SetupRoutes 设置路由
func (s *Server) SetupRoutes() {
	s.app.Get("/error", handler.ErrorPage)
	// 公共路由
	s.app.Get("/", handler.Home)
	s.app.Get("/login", handler.LoginPage)
	s.app.Post("/login", handler.LoginSubmit)
	s.app.Get("/logout", handler.Logout)

	// Logto认证路由
	s.app.Get("/auth/logto/login", handler.LogtoLogin)
	s.app.Get("/auth/logto/callback", handler.LogtoCallback)
	s.app.Get("/auth/logto/logout", handler.LogtoLogout)

	// 添加健康检查接口(保留此API，用于Docker健康检查)
	s.app.Get("/health", handler.HealthCheck)

	// 添加容器API接口
	s.app.Get("/api/v1/containers/:id/logs", handler.GetContainerLogs)
	s.app.Get("/api/v1/containers/:id/stats", handler.GetContainerStats)
	// 添加WebSocket API，实时获取容器日志
	s.app.Get("/api/v1/ws/containers/:id/logs", handler.ContainerLogsWebSocketMiddleware())

	// 受保护的路由 - 简化为仅保留必要功能
	auth := s.app.Group("/admin", middleware.Authenticate())

	// 机器人管理 - 核心功能
	auth.Get("/robots", handler.ListRobots)
	auth.Get("/robots/new", handler.NewRobotForm)
	auth.Post("/robots", handler.CreateRobot)
	auth.Get("/robots/:id", handler.ShowRobot)
	auth.Delete("/robots/:id", handler.DeleteRobot)
	auth.Get("/robots/:id/login", handler.RobotLogin)
	auth.Post("/robots/:id/logout", handler.RobotLogout)
	auth.Get("/robots/:id/check-qrcode", handler.CheckQRCodeStatus)

	// 联系人和消息 - 必要功能
	auth.Get("/robots/:id/contacts", handler.ListContacts)
	auth.Get("/robots/:id/contacts/:contactId", handler.ShowContact)
	auth.Get("/robots/:id/contacts/:contactId/messages", handler.ListMessages)
}

// Start 启动HTTP服务器
func (s *Server) Start() error {
	addr := s.config.Server.Address()
	fmt.Printf("Server starting on %s\n", addr)
	return s.app.Listen(addr)
}

// Shutdown 优雅地关闭服务器
func (s *Server) Shutdown() error {
	if s.app != nil {
		return s.app.Shutdown()
	}
	return nil
}
