package br

import (
	"fmt"
	"regexp"
	"strconv"
	"time"

	"github.com/tidbcloud/tidb-management-service/nextgen-global-service/infra/repoimpl/schema"
)

const (
	StandardRetentionDays      = 7
	StandardDailyRetentionDays = 33
	DefaultDailyBackupTimeUTC  = "00:00"
	MinFlexibleRetentionDays   = 3
	// MinOverrideFlexibleRetentionDays is only for the internal incident override.
	// Public backup-setting updates must use MinFlexibleRetentionDays.
	MinOverrideFlexibleRetentionDays    = 1
	MaxFlexibleRetentionDays            = 33
	EssentialV2MinFlexibleRetentionDays = 1
	EssentialV2MaxFlexibleRetentionDays = 30
	EssentialV2BackfillRetentionDays    = 30
)

var dailyBackupTimePattern = regexp.MustCompile(`^(?:[01]\d|2[0-3]):[0-5]\d$`)

func ParseDailyBackupTimeUTC(value string) (minuteOfDay int, err error) {
	if !dailyBackupTimePattern.MatchString(value) {
		return 0, fmt.Errorf("daily_backup_time_utc must be in HH:mm format")
	}
	hour, _ := strconv.Atoi(value[:2])
	minute, _ := strconv.Atoi(value[3:])
	return hour*60 + minute, nil
}

func IsDailyBackupTime(backupTime time.Time, schedule schema.AutoSchedule) bool {
	backupTime = backupTime.UTC()
	return backupTime.Hour()*60+backupTime.Minute() == schedule.DailyBackupMinuteOfDay
}

func ScheduleSlotForBackupTime(backupTime time.Time, schedule schema.AutoSchedule) time.Time {
	backupTime = backupTime.UTC()
	switch schedule.Type {
	case "per-day":
		slotTime := backupTime.Truncate(24 * time.Hour).Add(time.Duration(schedule.At) * time.Minute)
		if slotTime.After(backupTime) {
			return slotTime.Add(-24 * time.Hour)
		}
		return slotTime
	case "per-hour":
		slotTime := backupTime.Truncate(time.Hour).Add(time.Duration(schedule.At) * time.Minute)
		if slotTime.After(backupTime) {
			return slotTime.Add(-time.Hour)
		}
		return slotTime
	case "per-minute":
		return backupTime.Truncate(time.Minute)
	default:
		return backupTime
	}
}

func IsDailyBackupSlotForBackupTime(backupTime time.Time, schedule schema.AutoSchedule) bool {
	if schedule.Type == "per-day" {
		return true
	}
	return IsDailyBackupTime(ScheduleSlotForBackupTime(backupTime, schedule), schedule)
}
