package main

import (
	"log"
	"net/http"

	"api_yal/internal/config"
	"api_yal/internal/database"
	"api_yal/internal/logger"
	"api_yal/internal/router"
	"api_yal/internal/server"

	"go.uber.org/zap"
)

// main — точка входа в приложение api_yal.
// Инициализирует конфигурацию, логгер, подключение к базе данных,
// настраивает маршруты и запускает HTTP-сервер.
//
// Процесс инициализации:
//  1. Загружает конфигурацию из переменных окружения или конфигурационных файлов.
//  2. Инициализирует логгер с уровнем и окружением из конфигурации.
//  3. Подключается к PostgreSQL через GORM.
//  4. Настраивает маршрутизацию с помощью библиотеки Chi.
//  5. Запускает HTTP-сервер на порту 8787.
//
// Если возникает ошибка при подключении к базе данных, приложение завершается с паникой.
// При ошибках запуска сервера (кроме ErrServerClosed) приложение завершается с фатальной ошибкой.
func main() {

	// Загрузка конфигурации приложения из файлов окружения или конфигурационных файлов
	// Конфигурация включает параметры БД, уровень логирования, порт приложения и т.д.
	cfg := config.Load()

	// Инициализация логгера с указанным уровнем логирования и окружением (dev/prod)
	// Логгер будет настроен соответствующим образом для заданного окружения
	logger.Init(cfg.LogLevel, cfg.Environment)

	// Получение инстанса логгера для использования во всем приложении
	zapLogger := logger.Get()

	// Логирование полученных значений из конфигурации
	zapLogger.Info("Configuration loaded",
		zap.String("Environment", cfg.Environment),
		zap.String("LogLevel", cfg.LogLevel),
		// zap.String("DatabaseURL", cfg.DatabaseURL),
		zap.String("AppPort", cfg.AppPort),
	)

	// Логирование старта приложения с указанием используемого стека технологий
	zapLogger.Info("Start api_yal REST API on stack Golang (gorm, chi) and PostgresDB connect")

	// Инициализация подключения к базе данных PostgreSQL с использованием параметров из конфигурации
	// Возвращается объект gorm.DB для работы с ORM
	db, err := database.NewPostgresConnection(cfg)
	if err != nil {
		// Критическая ошибка подключения к БД - приложение не может работать без БД
		zapLogger.Panic("Failed to connect to database:", zap.Error(err))
	}

	// setup routes
	// Создаем маршрутизатор
	r := router.SetupRouter(db, cfg)

	// Создаем и запускаем сервер
	strServerPort := ":" + cfg.AppPort
	srv := server.NewServer(strServerPort, r)

	log.Printf("Server starting on port %s", strServerPort)
	if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
		log.Fatalf("Server failed to start: %v", err)
	}
}
