package logger

import (
	"net/http"
	"sort"
	"strings"

	"github.com/go-chi/chi/v5"
	"go.uber.org/zap"
)

type RouteLogger struct {
	logger LoggerInterface
}

func NewRouteLogger(log LoggerInterface) *RouteLogger {
	return &RouteLogger{
		logger: log,
	}
}

func (rl *RouteLogger) LogRoutes(router *chi.Mux) {
	routes := rl.extractRoutes(router)
	rl.printFormattedRoutes(routes)
}

func (rl *RouteLogger) extractRoutes(router *chi.Mux) []RouteInfo {
	var routes []RouteInfo

	walkFunc := func(method string, route string, handler http.Handler, middlewares ...func(http.Handler) http.Handler) error {
		if route != "" {
			routes = append(routes, RouteInfo{
				Method: method,
				Path:   route,
			})
		}
		return nil
	}

	if err := chi.Walk(router, walkFunc); err != nil {
		rl.logger.Error("Failed to walk routes", zap.Error(err))
	}

	return routes
}

func (rl *RouteLogger) printFormattedRoutes(routes []RouteInfo) {
	if len(routes) == 0 {
		rl.logger.Info("No routes found")
		return
	}

	// Группируем по пути
	routesByPath := make(map[string][]string)
	for _, route := range routes {
		routesByPath[route.Path] = append(routesByPath[route.Path], route.Method)
	}

	// Сортируем пути
	var paths []string
	for path := range routesByPath {
		paths = append(paths, path)
	}
	sort.Strings(paths)

	rl.logger.Info("📋 Registered API Routes:")
	rl.logger.Info("┌──────────────────────────────────────────────────────────────┐")

	for _, path := range paths {
		methods := routesByPath[path]
		sort.Strings(methods)
		methodsStr := strings.Join(methods, ", ")

		if len(methodsStr) > 12 {
			methodsStr = methodsStr[:9] + "..."
		}

		methodField := methodsStr
		if len(methodField) < 12 {
			methodField = methodField + strings.Repeat(" ", 12-len(methodField))
		}

		pathField := path
		if len(pathField) > 45 {
			pathField = pathField[:42] + "..."
		} else {
			pathField = pathField + strings.Repeat(" ", 45-len(pathField))
		}

		rl.logger.Info("│ " + methodField + " " + pathField + " │")
	}

	rl.logger.Info("└──────────────────────────────────────────────────────────────┘")
	rl.logger.Info("Total routes registered: %d", zap.Int("count", len(routes)))
}

type RouteInfo struct {
	Method string
	Path   string
}