package api

import (
	"daemonService/internal/handlers"
	"daemonService/internal/models"
	"daemonService/internal/models/obtencionCodigos"
	"fmt"
	"github.com/gorilla/mux"
	"log"
	"net/http"
	"time"
)

type Server struct {
	router       *mux.Router
	services     []models.SoapService
	servicesCuis []obtencionCodigos.CuisService
	isCron       bool
	port         int
}

func NewServer(port int, services []models.SoapService, servicesCuis []obtencionCodigos.CuisService, isCron bool) *Server {
	s := &Server{
		router:       mux.NewRouter(),
		services:     services,
		servicesCuis: servicesCuis,
		isCron:       isCron,
		port:         port,
	}

	s.setupRoutes()
	s.setupMiddleware()
	return s
}

func (s *Server) setupRoutes() {
	// Register service-related routes
	serviceHandler := handlers.NewServiceHandler(s.services, s.servicesCuis, s.isCron)
	s.router.HandleFunc("/api/services", serviceHandler.ListServices).Methods("GET")
	s.router.HandleFunc("/api/services/run-all", serviceHandler.RunAllServices).Methods("GET")
	s.router.HandleFunc("/api/services/{name}", serviceHandler.RunService).Methods("GET")
	//s.router.HandleFunc("/api/services/run-all", serviceHandler.RunAllServices).Methods("POST")
	//s.router.HandleFunc("/api/services/{name}", serviceHandler.RunService).Methods("POST")

	//serviceCuisHandler := obtencionCodigo.HandlerServiceCuis(s.services, s.isCron)
	s.router.HandleFunc("/api/services/get-code/{obtenerCodigo}", serviceHandler.RunGetCodeService).Methods("POST")

	healthHandler := handlers.NewHealthHandler()
	s.router.HandleFunc("/api/health", healthHandler.Check).Methods("GET")
}

func (s *Server) setupMiddleware() {
	s.router.Use(LoggingMiddleware)
}

func (s *Server) Start() *http.Server {
	srv := &http.Server{
		Addr:         fmt.Sprintf(":%d", s.port),
		Handler:      s.router,
		ReadTimeout:  15 * time.Second,
		WriteTimeout: 15 * time.Second,
		IdleTimeout:  60 * time.Second,
	}

	go func() {
		log.Printf("API HTTP started on port %d", s.port)
		if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
			log.Fatalf("HTTP server error: %v", err)
		}
	}()

	return srv
}

func LoggingMiddleware(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		start := time.Now()
		log.Printf("API Request: %s %s", r.Method, r.URL.Path)
		next.ServeHTTP(w, r)
		log.Printf("API Request: %s %s completed in %v", r.Method, r.URL.Path, time.Since(start))
	})
}

func StartAPIServer(port int, services []models.SoapService, serviceCuis []obtencionCodigos.CuisService, isCron bool) *http.Server {
	server := NewServer(port, services, serviceCuis, isCron)
	return server.Start()
}
