package main

import (
	"context"
	"log"
	"net/http"
	"os/signal"
	"syscall"
	"time"

	"vkfc1-new-go/internal/config"
	httpapi "vkfc1-new-go/internal/http"
	"vkfc1-new-go/internal/queue"
	mysqlrepo "vkfc1-new-go/internal/repository/mysql"
	"vkfc1-new-go/internal/service"
	s3storage "vkfc1-new-go/internal/storage/s3"
	"vkfc1-new-go/internal/vk"
)

func main() {
	cfg, err := config.Load()
	if err != nil {
		log.Fatalf("config load error: %v", err)
	}

	ctx, cancel := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
	defer cancel()

	db, err := mysqlrepo.New(ctx, cfg.MySQLDSN(), cfg.DB.PoolMax)
	if err != nil {
		log.Fatalf("db init error: %v", err)
	}
	defer db.Close()

	vkClient := vk.New(cfg.VK)
	s3Client, err := s3storage.New(cfg.S3)
	if err != nil {
		log.Fatalf("s3 init error: %v", err)
	}

	svc := service.New(cfg, db, vkClient, s3Client)
	router := httpapi.NewRouter(cfg, svc)

	worker := queue.NewWorker(db, svc)
	worker.Start(ctx)

	srv := &http.Server{
		Addr:         cfg.HTTPAddr(),
		Handler:      router,
		ReadTimeout:  20 * time.Second,
		WriteTimeout: 40 * time.Second,
		IdleTimeout:  60 * time.Second,
	}

	go func() {
		log.Printf("api listening on %s", cfg.HTTPAddr())
		if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
			log.Fatalf("http server error: %v", err)
		}
	}()

	<-ctx.Done()
	shutdownCtx, shutdownCancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer shutdownCancel()
	_ = srv.Shutdown(shutdownCtx)
}
