package repository

import (
	"context"
	"errors"

	"gorm.io/gorm"

	"git.jabali-panel.com/shukivaknin/jabali2/panel-api/internal/models"
)

// MalwareSettingsRepository owns the malware_settings singleton row.
// Migration 000076 seeds id=1 with literal defaults; EnsureDefault is
// idempotent in case the row was deleted manually (operator footgun
// recovery — never silently broken).
type MalwareSettingsRepository interface {
	Get(ctx context.Context) (*models.MalwareSettings, error)
	Upsert(ctx context.Context, s *models.MalwareSettings) error
	EnsureDefault(ctx context.Context) error
}

type malwareSettingsRepo struct{ db *gorm.DB }

// NewMalwareSettingsRepository returns a GORM-backed singleton repo.
func NewMalwareSettingsRepository(db *gorm.DB) MalwareSettingsRepository {
	return &malwareSettingsRepo{db: db}
}

func (r *malwareSettingsRepo) Get(ctx context.Context) (*models.MalwareSettings, error) {
	var s models.MalwareSettings
	if err := r.db.WithContext(ctx).First(&s, 1).Error; err != nil {
		return nil, translate(err)
	}
	return &s, nil
}

func (r *malwareSettingsRepo) Upsert(ctx context.Context, s *models.MalwareSettings) error {
	s.ID = 1
	if err := r.db.WithContext(ctx).Save(s).Error; err != nil {
		return translate(err)
	}
	return nil
}

// EnsureDefault inserts id=1 with all defaults if missing. No-op when
// the row exists. Mirrors the migration seed for crash-recovery cases.
func (r *malwareSettingsRepo) EnsureDefault(ctx context.Context) error {
	var s models.MalwareSettings
	err := r.db.WithContext(ctx).First(&s, 1).Error
	if err == nil {
		return nil
	}
	if !errors.Is(err, gorm.ErrRecordNotFound) {
		return translate(err)
	}
	def := models.MalwareSettings{
		ID:                   1,
		ScheduleCron:         "0 3 * * *",
		QuarantineRetainDays: 30,
		MaxScanMB:            256,
		NotifyThreshold:      models.MalwareSeverityWarn,
		RealtimeEnabled:      false,
		// M33.2 mail-scan defaults — see ADR-0079.
		MailScanEnabled:         false,
		MailScanAllFolders:      false,
		MailScanSkipAddresses:   "",
		MailScanMaxAttachmentMB: 25,
		MailScanTimeoutSec:      10,
		MailScanPerTickBudget:   200,
	}
	if err := r.db.WithContext(ctx).Create(&def).Error; err != nil {
		return translate(err)
	}
	return nil
}
