package server

import (
	"log"
	"os"

	"github.com/gin-gonic/gin"
	"github.com/joho/godotenv"

	"sensor-server/internal/api"
	"sensor-server/internal/cache"
	"sensor-server/internal/database"
	"sensor-server/internal/websocket"
)

// Server 서버 구조체
type Server struct {
	router *gin.Engine
	hub    *websocket.Hub
}

// NewServer 새로운 서버 인스턴스 생성
func NewServer() *Server {
	// 환경변수 로드
	if err := godotenv.Load(); err != nil {
		log.Println("No .env file found, using environment variables")
	}

	// Gin 모드 설정
	if os.Getenv("GIN_MODE") == "release" {
		gin.SetMode(gin.ReleaseMode)
	}

	router := gin.New() // gin.Default() 대신 gin.New() 사용
	hub := websocket.NewHub()

	// 로깅 미들웨어 추가
	router.Use(gin.Logger())
	router.Use(gin.Recovery())

	// CORS 미들웨어 추가
	router.Use(func(c *gin.Context) {
		c.Header("Access-Control-Allow-Origin", "*")
		c.Header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
		c.Header("Access-Control-Allow-Headers", "Origin, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization")
		
		if c.Request.Method == "OPTIONS" {
			c.AbortWithStatus(204)
			return
		}
		
		c.Next()
	})

	return &Server{
		router: router,
		hub:    hub,
	}
}

// Initialize 서버 초기화
func (s *Server) Initialize() error {
	// 데이터베이스 초기화
	if err := database.InitDatabase(); err != nil {
		return err
	}

	// Redis 초기화
	if err := cache.InitRedis(); err != nil {
		return err
	}

	// 라우터 설정
	s.setupRoutes()

	// WebSocket 허브 시작
	go s.hub.Run()

	return nil
}

// setupRoutes 라우터 설정
func (s *Server) setupRoutes() {
	handler := api.NewHandler(s.hub)

	// WebSocket 엔드포인트 (가장 먼저 등록)
	s.router.GET("/ws", func(c *gin.Context) {
		log.Printf("WebSocket 요청 수신: %s", c.Request.URL.Path)
		websocket.ServeWs(s.hub, c.Writer, c.Request)
	})

	// API 그룹
	api := s.router.Group("/api")
	{
		// 헬스체크
		api.GET("/health", handler.HealthCheck)

		// 센서 데이터 수신
		api.POST("/sensor-data", handler.ReceiveSensorData)
		// 확장된 센서 데이터 수신
		api.POST("/sensor/extended-data", handler.ReceiveExtendedSensorData)

		// 디바이스 관련
		api.GET("/devices", handler.GetDevices)
		api.GET("/devices/:deviceId/latest", handler.GetLatestData)
		api.GET("/devices/:deviceId/history", handler.GetHistory)
	}

	// 정적 파일 서빙 (개발용)
	s.router.Static("/static", "./static")
}

// Run 서버 실행
func (s *Server) Run() error {
	port := os.Getenv("PORT")
	if port == "" {
		port = "8080"
	}

	log.Printf("Server starting on port %s", port)
	return s.router.Run(":" + port)
}

// GetRouter 라우터 반환 (테스트용)
func (s *Server) GetRouter() *gin.Engine {
	return s.router
} 