package router

import (
	"api_yal/internal/config"
	"api_yal/internal/domain/account"
	"api_yal/internal/domain/auth"
	"api_yal/internal/domain/comment"
	"api_yal/internal/domain/feetback"
	"api_yal/internal/domain/object"
	"api_yal/internal/logger"
	"time"

	"encoding/json"
	"net/http"

	"github.com/go-chi/chi/v5"
	ChiMiddleware "github.com/go-chi/chi/v5/middleware"
	"github.com/go-chi/cors"
	"go.uber.org/zap"
	"gorm.io/gorm"
)

// SetupRouter инициализирует и настраивает основной маршрутизатор приложения
func SetupRouter(db *gorm.DB, config *config.Config) http.Handler {
	zapLogger := logger.Get()
	zapLogger.Info("Начало настройки маршрутов")

	r := chi.NewRouter()

	// ВСЕ middleware должны быть определены ДО маршрутов
	// 1. Сначала добавляем production middleware
	addProductionMiddleware(r, config)

	// 2. Затем добавляем middleware аутентификации (он тоже применяется ко всем маршрутам)
	zapLogger.Debug("Auth middleware применён")

	// 3. И только потом регистрируем маршруты
	// Health check (не требует аутентификации, поэтому должен быть выше AuthMiddleware)
	r.Get("/health", func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "application/json")
		w.WriteHeader(http.StatusOK)

		if err := json.NewEncoder(w).Encode(map[string]string{"status": "healthy"}); err != nil {
			zapLogger.Error("Ошибка при отправке health check ответа",
				zap.String("path", r.URL.Path),
				zap.Error(err),
			)
		}
	})
	zapLogger.Debug("Health check маршрут зарегистрирован")

	// Группируем API маршруты под /api/v1
	r.Route("/api/v1", func(r chi.Router) {
		// Регистрируем маршруты аутентификации
		auth.RegisterRoutes(r, db, config.JWTSecret)

		// Регистрируем маршруты аккаунтов
		account.RegisterRoutes(r, db, config.JWTSecret)

		// Регистрируем маршруты объектов
		object.RegisterRoutes(r, db, config.JWTSecret)

		// Регистрируем маршруты отзывов
		feetback.RegisterRoutes(r, db, config.JWTSecret)

		// Регистрируем маршруты комментариев
		comment.RegisterRoutes(r, db, config.JWTSecret)
	})

	zapLogger.Info("Настройка маршрутов завершена")

	// Логируем маршруты (опционально)
	routeLogger := logger.NewRouteLogger(logger.NewWrapper(zapLogger))
	routeLogger.LogRoutes(r)

	return r
}

// addProductionMiddleware добавляет все middleware для production
func addProductionMiddleware(r *chi.Mux, config *config.Config) {
	// Базовые middleware
	r.Use(ChiMiddleware.RequestID)
	r.Use(ChiMiddleware.RealIP)
	r.Use(ChiMiddleware.Logger)
	r.Use(ChiMiddleware.Recoverer)
	r.Use(ChiMiddleware.Timeout(30 * time.Second))
	r.Use(ChiMiddleware.Compress(5, "gzip"))
	r.Use(ChiMiddleware.StripSlashes)

	// CORS
	r.Use(cors.Handler(cors.Options{
		AllowedOrigins:   config.CORS.AllowedOrigins,
		AllowedMethods:   []string{"GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH"},
		AllowedHeaders:   []string{"Accept", "Authorization", "Content-Type", "X-CSRF-Token", "X-Request-ID"},
		ExposedHeaders:   []string{"Link", "X-Request-ID"},
		AllowCredentials: true,
		MaxAge:           300,
	}))

	// Content-Type проверка
	r.Use(ChiMiddleware.AllowContentType("application/json", "application/xml"))

	// Rate limiting
	if config.RateLimit.Enabled {
		r.Use(ChiMiddleware.Throttle(config.RateLimit.RequestsPerSecond))
	}

	// Security headers
	r.Use(func(next http.Handler) http.Handler {
		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			w.Header().Set("X-Content-Type-Options", "nosniff")
			w.Header().Set("X-Frame-Options", "DENY")
			w.Header().Set("X-XSS-Protection", "1; mode=block")
			w.Header().Set("Referrer-Policy", "strict-origin-when-cross-origin")

			if config.Environment == "production" {
				w.Header().Set("Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload")
			}

			next.ServeHTTP(w, r)
		})
	})
}
