package api

import (
	"net/http"

	"git.kirlllll.ru/volontery/backend/internal/api/handlers"
	"git.kirlllll.ru/volontery/backend/internal/api/middleware"
	"git.kirlllll.ru/volontery/backend/internal/config"
	"git.kirlllll.ru/volontery/backend/internal/pkg/jwt"
	"git.kirlllll.ru/volontery/backend/internal/service"
	"github.com/go-chi/chi/v5"
	chiMiddleware "github.com/go-chi/chi/v5/middleware"
)

// Server представляет HTTP сервер
type Server struct {
	router         *chi.Mux
	authHandler    *handlers.AuthHandler
	adminHandler   *handlers.AdminHandler
	userHandler    *handlers.UserHandler
	requestHandler *handlers.RequestHandler
	jwtManager     *jwt.Manager
	userService    *service.UserService
	config         *config.Config
}

// NewServer создает новый HTTP сервер
func NewServer(
	cfg *config.Config,
	authService *service.AuthService,
	userService *service.UserService,
	requestService *service.RequestService,
	jwtManager *jwt.Manager,
) *Server {
	s := &Server{
		router:         chi.NewRouter(),
		authHandler:    handlers.NewAuthHandler(authService),
		adminHandler:   handlers.NewAdminHandler(userService),
		userHandler:    handlers.NewUserHandler(userService),
		requestHandler: handlers.NewRequestHandler(requestService),
		jwtManager:     jwtManager,
		userService:    userService,
		config:         cfg,
	}

	s.setupRoutes()
	return s
}

// setupRoutes настраивает маршруты
func (s *Server) setupRoutes() {
	r := s.router

	// Глобальные middleware
	r.Use(chiMiddleware.RequestID)
	r.Use(chiMiddleware.RealIP)
	r.Use(middleware.Logger)
	r.Use(middleware.Recovery)
	r.Use(middleware.CORS(s.config.CORSAllowedOrigins))

	// Health check
	r.Get("/health", func(w http.ResponseWriter, r *http.Request) {
		w.WriteHeader(http.StatusOK)
		w.Write([]byte("OK"))
	})

	// API v1
	r.Route("/api/v1", func(r chi.Router) {
		// Публичные маршруты (без аутентификации)
		r.Group(func(r chi.Router) {
			r.Post("/auth/register", s.authHandler.Register)
			r.Post("/auth/login", s.authHandler.Login)
			r.Post("/auth/refresh", s.authHandler.RefreshToken)

			// Типы заявок (публичные)
			r.Get("/request-types", s.requestHandler.ListRequestTypes)
		})

		// Защищенные маршруты (требуют аутентификации)
		r.Group(func(r chi.Router) {
			r.Use(middleware.AuthMiddleware(s.jwtManager))

			// Auth
			r.Get("/auth/me", s.authHandler.Me)
			r.Post("/auth/logout", s.authHandler.Logout)

			// Users
			r.Get("/users/me", s.userHandler.GetMyProfile)
			r.Patch("/users/me", s.userHandler.UpdateProfile)
			r.Post("/users/me/location", s.userHandler.UpdateLocation)
			r.Post("/users/me/verify-email", s.userHandler.VerifyEmail)
			r.Get("/users/me/roles", s.userHandler.GetMyRoles)
			r.Get("/users/me/permissions", s.userHandler.GetMyPermissions)
			r.Get("/users/{id}", s.userHandler.GetProfile)

			// Requests
			r.Post("/requests", s.requestHandler.CreateRequest)
			r.Get("/requests/my", s.requestHandler.GetMyRequests)
			r.Get("/requests/nearby", s.requestHandler.FindNearbyRequests)
			r.Get("/requests/bounds", s.requestHandler.FindRequestsInBounds)
			r.Get("/requests/{id}", s.requestHandler.GetRequest)
			r.Post("/requests/{id}/responses", s.requestHandler.CreateVolunteerResponse)
			r.Get("/requests/{id}/responses", s.requestHandler.GetRequestResponses)
			r.Post("/requests/{id}/responses/{response_id}/accept", s.requestHandler.AcceptVolunteerResponseHandler)
			r.Post("/requests/{id}/complete", s.requestHandler.CompleteRequestWithRatingHandler)
		})

		// Маршруты для модераторов (требуют роль moderator или admin)
		r.Group(func(r chi.Router) {
			r.Use(middleware.AuthMiddleware(s.jwtManager))
			r.Use(middleware.RequireAnyRole(s.userService, "moderator", "admin"))

			// Модерация заявок
			r.Get("/moderation/requests/pending", s.requestHandler.GetPendingModerationRequests)
			r.Get("/moderation/requests/my", s.requestHandler.GetMyModeratedRequests)
			r.Post("/moderation/requests/{id}/approve", s.requestHandler.ApproveRequest)
			r.Post("/moderation/requests/{id}/reject", s.requestHandler.RejectRequest)
			r.Post("/moderation/requests/{id}/moderate", s.requestHandler.ModerateRequestProcedure)
		})

		// Маршруты для администраторов (требуют роль admin)
		r.Group(func(r chi.Router) {
			r.Use(middleware.AuthMiddleware(s.jwtManager))
			r.Use(middleware.RequireRole(s.userService, "admin"))

			// Админские маршруты можно добавить позже
			r.Get("/admin/users/{id}/roles/{role_id}", s.adminHandler.AssignRole)
		})
	})
}

// ServeHTTP реализует интерфейс http.Handler
func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	s.router.ServeHTTP(w, r)
}

// Router возвращает роутер Chi
func (s *Server) Router() *chi.Mux {
	return s.router
}
