package publishschedule

import (
	"sort"
	"strings"
	"time"
)

type Slot struct {
	Weekday int
	Time    string
}

func BuildSchedule(startAt int64, timezone string, slots []Slot, count int) []int64 {
	if count <= 0 {
		return nil
	}
	loc := time.UTC
	if strings.TrimSpace(timezone) != "" {
		if loaded, err := time.LoadLocation(strings.TrimSpace(timezone)); err == nil {
			loc = loaded
		}
	}
	start := time.Now().In(loc)
	if startAt > 0 {
		start = time.Unix(0, startAt).In(loc)
	}
	normalized := normalizeSlots(slots)
	if len(normalized) == 0 {
		out := make([]int64, 0, count)
		for i := 0; i < count; i++ {
			out = append(out, start.Add(time.Duration(i)*2*time.Hour).UTC().UnixNano())
		}
		return out
	}
	out := make([]int64, 0, count)
	day := time.Date(start.Year(), start.Month(), start.Day(), 0, 0, 0, 0, loc)
	for len(out) < count {
		for _, slot := range normalized {
			if int(day.Weekday()) != slot.Weekday {
				continue
			}
			hour, minute, ok := parseHHMM(slot.Time)
			if !ok {
				continue
			}
			candidate := time.Date(day.Year(), day.Month(), day.Day(), hour, minute, 0, 0, loc)
			if candidate.Before(start) {
				continue
			}
			out = append(out, candidate.UTC().UnixNano())
			if len(out) >= count {
				break
			}
		}
		day = day.AddDate(0, 0, 1)
	}
	return out
}

func normalizeSlots(slots []Slot) []Slot {
	out := make([]Slot, 0, len(slots))
	for _, slot := range slots {
		if strings.TrimSpace(slot.Time) == "" {
			continue
		}
		weekday := slot.Weekday
		if weekday < 0 || weekday > 6 {
			weekday = ((weekday % 7) + 7) % 7
		}
		out = append(out, Slot{Weekday: weekday, Time: strings.TrimSpace(slot.Time)})
	}
	sort.Slice(out, func(i, j int) bool {
		if out[i].Weekday == out[j].Weekday {
			return out[i].Time < out[j].Time
		}
		return out[i].Weekday < out[j].Weekday
	})
	return out
}

func parseHHMM(value string) (int, int, bool) {
	parsed, err := time.Parse("15:04", strings.TrimSpace(value))
	if err != nil {
		return 0, 0, false
	}
	return parsed.Hour(), parsed.Minute(), true
}
