package pocketbase

import (
	"fmt"

	"github.com/pocketbase/pocketbase/core"
)

// ProviderName — имя провайдера у коллекции пользователей. Библиотека знает его
// как обобщённый OIDC и по нему же ищет настройку при обмене кода.
const ProviderName = "oidc"

// SessionDuration — сколько живёт сессия вошедшего, семь суток. Число выбрано
// решением владельца от 2026-08-12; умолчание библиотеки в пять суток не
// применяется, потому что оно никем не выбрано.
//
// Применяется оно не шагом схемы, а при каждом подъёме — вместе с настройками
// провайдера, и потому живёт здесь, а не в каталоге шагов. Причина та же:
// применённый шаг не переписывается, и число, положенное туда, разошлось бы со
// сроком жизни куки при первой же правке — браузер получил бы новый срок, а
// хранилище продолжило выдавать прежний.
const SessionDuration = 7 * 24 * 60 * 60

// ProviderSettings — то, что приезжает из конфига и приводится к настройкам
// коллекции.
type ProviderSettings struct {
	AuthURL      string
	TokenURL     string
	UserInfoURL  string
	ClientID     string
	ClientSecret string
}

// ApplyProviderSettings приводит настройки провайдера у коллекции пользователей
// к значениям конфига.
//
// Делается это при каждом подъёме, а не однажды шагом схемы, и причина в
// инварианте: применённый шаг не переписывается. Секрет, положенный шагом, не
// пережил бы ротации — смена значения в конфиге до хранилища не доехала бы
// вовсе, и вход сломался бы после смены ключа, а починить это можно было бы
// только руками в панели.
//
// Секрет здесь не логируется и в текст ошибки не попадает: сообщение называет
// имя коллекции, а не значения.
func ApplyProviderSettings(app core.App, settings ProviderSettings) error {
	users, err := app.FindCollectionByNameOrId("users")
	if err != nil {
		return fmt.Errorf("failed to find users collection: %w", err)
	}

	// Срок жизни сессии живёт здесь, а не в шаге схемы: применённый шаг не
	// переписывается, и правка числа не доехала бы до хранилища, разойдясь со
	// сроком жизни куки.
	users.AuthToken.Duration = SessionDuration

	users.OAuth2.Enabled = true
	users.OAuth2.Providers = []core.OAuth2ProviderConfig{{
		Name:         ProviderName,
		ClientId:     settings.ClientID,
		ClientSecret: settings.ClientSecret,
		AuthURL:      settings.AuthURL,
		TokenURL:     settings.TokenURL,
		UserInfoURL:  settings.UserInfoURL,
		DisplayName:  "Authelia",
	}}

	if err := app.Save(users); err != nil {
		return fmt.Errorf("failed to apply provider settings to users collection: %w", err)
	}

	return nil
}
