package app

import (
	"fmt"
	"strings"

	"trustcontact/internal/config"
	"trustcontact/internal/db"
	apphttp "trustcontact/internal/http"

	"github.com/gofiber/fiber/v2"
	"github.com/gofiber/fiber/v2/middleware/cors"
	"github.com/gofiber/fiber/v2/middleware/session"
)

func NewApp(cfg *config.Config) (*fiber.App, error) {
	if cfg == nil {
		return nil, fmt.Errorf("config is nil")
	}

	app := fiber.New()

	app.Use(cors.New(cors.Config{
		AllowOrigins:     strings.Join(cfg.CORS.Origins, ","),
		AllowHeaders:     strings.Join(cfg.CORS.Headers, ","),
		AllowMethods:     strings.Join(cfg.CORS.Methods, ","),
		AllowCredentials: cfg.CORS.Credentials,
	}))

	store := session.New(session.Config{
		KeyLookup:      "cookie:" + cfg.SessionKey,
		CookieHTTPOnly: true,
		CookieSecure:   cfg.Env == config.EnvProd,
		CookieSameSite: fiber.CookieSameSiteLaxMode,
	})

	database, err := db.Open(cfg)
	if err != nil {
		return nil, fmt.Errorf("open db: %w", err)
	}

	if cfg.AutoMigrate {
		if err := db.Migrate(database); err != nil {
			return nil, fmt.Errorf("migrate db: %w", err)
		}
	}

	if cfg.SeedEnabled && cfg.Env == config.EnvDevelop {
		if err := db.Seed(database); err != nil {
			return nil, fmt.Errorf("seed db: %w", err)
		}
	}

	if err := apphttp.RegisterRoutes(app, store, database, cfg); err != nil {
		return nil, fmt.Errorf("register routes: %w", err)
	}

	return app, nil
}
