package authentik

import (
	"context"
	"errors"
	"time"

	"github.com/jackc/pgx/v5"
	"github.com/jackc/pgx/v5/pgxpool"
)

type ProvisionRecord struct {
	AppKey        string
	AuthentikSlug string
	ClientID      string
	ProviderID    *int
	ApplicationID *int
	ProvisionedAt time.Time
}

func IsProvisioned(ctx context.Context, pool *pgxpool.Pool, appKey string) (bool, error) {
	var exists bool
	err := pool.QueryRow(ctx,
		`SELECT EXISTS(SELECT 1 FROM suite_authentik_provisioned WHERE app_key = $1)`,
		appKey,
	).Scan(&exists)
	return exists, err
}

func SaveProvisioned(ctx context.Context, pool *pgxpool.Pool, rec ProvisionRecord) error {
	_, err := pool.Exec(ctx, `
		INSERT INTO suite_authentik_provisioned (app_key, authentik_slug, client_id, provider_id, application_id, provisioned_at)
		VALUES ($1, $2, $3, $4, $5, COALESCE($6, NOW()))
		ON CONFLICT (app_key) DO UPDATE SET
			authentik_slug = EXCLUDED.authentik_slug,
			client_id = EXCLUDED.client_id,
			provider_id = EXCLUDED.provider_id,
			application_id = EXCLUDED.application_id,
			provisioned_at = EXCLUDED.provisioned_at
	`, rec.AppKey, rec.AuthentikSlug, rec.ClientID, rec.ProviderID, rec.ApplicationID, rec.ProvisionedAt)
	return err
}

func GetProvisioned(ctx context.Context, pool *pgxpool.Pool, appKey string) (ProvisionRecord, error) {
	var rec ProvisionRecord
	err := pool.QueryRow(ctx, `
		SELECT app_key, authentik_slug, client_id, provider_id, application_id, provisioned_at
		FROM suite_authentik_provisioned WHERE app_key = $1
	`, appKey).Scan(&rec.AppKey, &rec.AuthentikSlug, &rec.ClientID, &rec.ProviderID, &rec.ApplicationID, &rec.ProvisionedAt)
	if errors.Is(err, pgx.ErrNoRows) {
		return rec, err
	}
	return rec, err
}
