package api

import (
	"context"
	"database/sql"
	"net/http"

	"erp-mvp/core-service/internal/api/handlers"
	"erp-mvp/core-service/internal/api/middleware"
	"erp-mvp/core-service/internal/auth"
	"erp-mvp/core-service/internal/config"
	"erp-mvp/core-service/internal/logger"
	"erp-mvp/core-service/internal/repository"
	"erp-mvp/core-service/internal/service"

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

type Server struct {
	config *config.Config
	db     *sql.DB
	logger logger.Logger
	router *gin.Engine

	// Services
	authService       service.AuthService
	locationService   service.LocationService
	itemService       service.ItemService
	operationsService service.OperationsService

	// Handlers
	authHandler       *handlers.AuthHandler
	locationHandler   *handlers.LocationHandler
	itemHandler       *handlers.ItemHandler
	operationsHandler *handlers.OperationsHandler

	// Middleware
	authMiddleware *middleware.AuthMiddleware
}

func NewServer(cfg *config.Config, db *sql.DB, log logger.Logger) *Server {
	// Инициализируем JWT сервис
	jwtService := auth.NewJWTService(cfg.JWT.Secret, cfg.JWT.TTL)

	// Инициализируем репозитории
	orgRepo := repository.NewOrganizationRepository(db)
	userRepo := repository.NewUserRepository(db)
	locationRepo := repository.NewLocationRepository(db)
	itemRepo := repository.NewItemRepository(db)
	operationsRepo := repository.NewOperationsRepository(db)

	// Инициализируем сервисы
	authService := service.NewAuthService(orgRepo, userRepo, jwtService)
	locationService := service.NewLocationService(locationRepo)
	itemService := service.NewItemService(itemRepo)
	operationsService := service.NewOperationsService(operationsRepo, itemRepo, locationRepo)

	// Инициализируем handlers
	authHandler := handlers.NewAuthHandler(authService)
	locationHandler := handlers.NewLocationHandler(locationService)
	itemHandler := handlers.NewItemHandler(itemService)
	operationsHandler := handlers.NewOperationsHandler(operationsService)

	// Инициализируем middleware
	authMiddleware := middleware.NewAuthMiddleware(jwtService)

	server := &Server{
		config:            cfg,
		db:                db,
		logger:            log,
		router:            gin.Default(),
		authService:       authService,
		locationService:   locationService,
		itemService:       itemService,
		operationsService: operationsService,
		authHandler:       authHandler,
		locationHandler:   locationHandler,
		itemHandler:       itemHandler,
		operationsHandler: operationsHandler,
		authMiddleware:    authMiddleware,
	}

	server.setupRoutes()
	return server
}

func (s *Server) setupRoutes() {
	// Health check
	s.router.GET("/health", s.healthCheck)

	// API routes
	api := s.router.Group("/api")
	{
		// Auth routes
		auth := api.Group("/auth")
		{
			auth.POST("/register", s.authHandler.Register)
			auth.POST("/login", s.authHandler.Login)
		}

		// Protected routes
		protected := api.Group("/")
		protected.Use(s.authMiddleware.AuthRequired())
		{
			// Organizations
			protected.GET("/organizations/:id", s.getOrganization)
			protected.PUT("/organizations/:id", s.updateOrganization)

			// Locations
			protected.GET("/locations", s.locationHandler.GetLocations)
			protected.POST("/locations", s.locationHandler.CreateLocation)
			protected.GET("/locations/:id", s.locationHandler.GetLocation)
			protected.PUT("/locations/:id", s.locationHandler.UpdateLocation)
			protected.DELETE("/locations/:id", s.locationHandler.DeleteLocation)
			protected.GET("/locations/:id/children", s.locationHandler.GetChildren)

			// Items
			protected.GET("/items", s.itemHandler.GetItems)
			protected.POST("/items", s.itemHandler.CreateItem)
			protected.GET("/items/:id", s.itemHandler.GetItem)
			protected.PUT("/items/:id", s.itemHandler.UpdateItem)
			protected.DELETE("/items/:id", s.itemHandler.DeleteItem)
			protected.GET("/items/search", s.itemHandler.SearchItems)

			// Operations
			protected.POST("/operations/place-item", s.operationsHandler.PlaceItem)
			protected.POST("/operations/move-item/:id", s.operationsHandler.MoveItem)
			protected.GET("/operations/search", s.operationsHandler.Search)
			protected.GET("/operations/items/:item_id/placements", s.operationsHandler.GetItemPlacements)
			protected.GET("/operations/locations/:location_id/placements", s.operationsHandler.GetLocationPlacements)
			protected.PUT("/operations/placements/:id/quantity", s.operationsHandler.UpdateQuantity)
			protected.DELETE("/operations/placements/:id", s.operationsHandler.DeletePlacement)

			// Templates
			protected.GET("/templates", s.getTemplates)
			protected.POST("/templates/:id/apply", s.applyTemplate)
		}
	}
}

func (s *Server) healthCheck(c *gin.Context) {
	c.JSON(http.StatusOK, gin.H{
		"status":  "ok",
		"service": "erp-mvp-core",
	})
}

// Placeholder handlers - will be implemented in next stages
func (s *Server) getOrganization(c *gin.Context) {
	c.JSON(http.StatusNotImplemented, gin.H{"error": "Not implemented yet"})
}

func (s *Server) updateOrganization(c *gin.Context) {
	c.JSON(http.StatusNotImplemented, gin.H{"error": "Not implemented yet"})
}

func (s *Server) getTemplates(c *gin.Context) {
	c.JSON(http.StatusNotImplemented, gin.H{"error": "Not implemented yet"})
}

func (s *Server) applyTemplate(c *gin.Context) {
	c.JSON(http.StatusNotImplemented, gin.H{"error": "Not implemented yet"})
}

func (s *Server) Start() error {
	return s.router.Run(s.config.Server.Host + ":" + s.config.Server.Port)
}

func (s *Server) Shutdown(ctx context.Context) error {
	// Graceful shutdown logic will be added later
	return nil
}
