package config

import (
	"encoding/json"
	"fmt"
	"os"
)

type ServerConfig struct {
	AppName               string     `json:"app_name"`
	ReadTimeoutSeconds    int        `json:"read_timeout_seconds"`
	WriteTimeoutSeconds   int        `json:"write_timeout_seconds"`
	IdleTimeoutSeconds    int        `json:"idle_timeout_seconds"`
	DisableStartupMessage bool       `json:"disable_startup_message"`
	Auth                  AuthConfig `json:"auth"`
	Mail                  MailConfig `json:"mail"`
	RolesConfigPath       string     `json:"roles_config_path"`
}

type AuthConfig struct {
	Secret                    string `json:"secret"`
	Issuer                    string `json:"issuer"`
	AccessTokenExpiryMinutes  int    `json:"access_token_expiry_minutes"`
	RefreshTokenExpiryMinutes int    `json:"refresh_token_expiry_minutes"`
}

type MailConfig struct {
	Mode              string         `json:"mode"`
	From              string         `json:"from"`
	DebugDir          string         `json:"debug_dir"`
	TemplatesDir      string         `json:"templates_dir"`
	FrontendBaseURL   string         `json:"frontend_base_url"`
	ResetPasswordPath string         `json:"reset_password_path"`
	SMTP              SMTPMailConfig `json:"smtp"`
}

type SMTPMailConfig struct {
	Host     string `json:"host"`
	Port     int    `json:"port"`
	Username string `json:"username"`
	Password string `json:"password"`
}

func LoadConfig(path string) (ServerConfig, error) {
	data, err := os.ReadFile(path)
	if err != nil {
		return ServerConfig{}, fmt.Errorf("read config: %w", err)
	}
	var cfg ServerConfig
	if err := json.Unmarshal(data, &cfg); err != nil {
		return ServerConfig{}, fmt.Errorf("parse config: %w", err)
	}
	if cfg.Auth.Secret == "" {
		return ServerConfig{}, fmt.Errorf("auth.secret must be set")
	}
	if cfg.Auth.AccessTokenExpiryMinutes <= 0 {
		return ServerConfig{}, fmt.Errorf("auth.access_token_expiry_minutes must be greater than zero")
	}
	if cfg.Auth.RefreshTokenExpiryMinutes <= 0 {
		return ServerConfig{}, fmt.Errorf("auth.refresh_token_expiry_minutes must be greater than zero")
	}
	if cfg.Mail.Mode == "" {
		cfg.Mail.Mode = "file"
	}
	if cfg.Mail.TemplatesDir == "" {
		cfg.Mail.TemplatesDir = "internal/http/templates"
	}
	if cfg.Mail.ResetPasswordPath == "" {
		cfg.Mail.ResetPasswordPath = "/#reset-password"
	}
	if cfg.Mail.Mode != "smtp" && cfg.Mail.Mode != "file" {
		return ServerConfig{}, fmt.Errorf("mail.mode must be either smtp or file")
	}
	if cfg.Mail.From == "" {
		return ServerConfig{}, fmt.Errorf("mail.from must be set")
	}
	if cfg.Mail.Mode == "smtp" {
		if cfg.Mail.SMTP.Host == "" {
			return ServerConfig{}, fmt.Errorf("mail.smtp.host must be set when mail.mode=smtp")
		}
		if cfg.Mail.SMTP.Port <= 0 {
			return ServerConfig{}, fmt.Errorf("mail.smtp.port must be greater than zero when mail.mode=smtp")
		}
	} else if cfg.Mail.DebugDir == "" {
		cfg.Mail.DebugDir = "data/mail-debug"
	}

	return cfg, nil
}
