import Foundation

class SuggestionManager {
    static let shared = SuggestionManager()

    // MARK: - UserDefaults keys

    private enum Keys {
        static let dismissed = "pommedoro.suggestions.dismissed"
        static let currentIndex = "pommedoro.suggestions.currentIndex"
        static let lastShown = "pommedoro.suggestions.lastShown"
    }

    private let defaults = UserDefaults.standard

    // MARK: - Data

    private let suggestions: [String] = [
        "Breathe for a few",
        "Get up and walk around a minute",
        "Do some pushups or something",
        "Bodyweight squats, let's go",
        "Maybe some crunches",
        "Drink some water",
        "Stretch your neck and shoulders",
        "Rest your eyes, look at something far away",
        "Stand up and touch your toes",
        "Roll your wrists and ankles",
        "Take a few deep breaths",
        "Go get some water",
        "Do some lunges",
        "Stretch your hip flexors",
        "Give your eyes a break",
        "Straighten your posture, your back will thank you",
        "Smile — it actually helps your mood",
        "Clear your desk, clear your mind",
        "Take a moment to appreciate how far you've come",
        "Eat something fresh and nourishing today",
        "Step outside for a minute of fresh air",
        "Unclench your jaw and relax your shoulders"
    ]

    private var dismissed: Set<Int> = []
    private var currentIndex: Int = 0
    private var lastShown: String = ""

    // MARK: - Init (restore persisted state)

    private init() {
        if let savedDismissed = defaults.array(forKey: Keys.dismissed) as? [Int] {
            dismissed = Set(savedDismissed)
        }
        currentIndex = defaults.integer(forKey: Keys.currentIndex)
        lastShown = defaults.string(forKey: Keys.lastShown) ?? ""
    }

    // MARK: - Persistence helpers

    private func persist() {
        defaults.set(Array(dismissed), forKey: Keys.dismissed)
        defaults.set(currentIndex, forKey: Keys.currentIndex)
        defaults.set(lastShown, forKey: Keys.lastShown)
    }

    // MARK: - Public API

    func next() -> String {
        let available = availableIndices()

        // If nothing is available after filtering, reset dismissed pool
        if available.isEmpty {
            dismissed.removeAll()
            return next()
        }

        // Pick the next available index that isn't the last-shown suggestion
        var chosen: Int? = nil
        var idx = currentIndex
        for _ in 0..<suggestions.count {
            if available.contains(idx) && suggestions[idx] != lastShown {
                chosen = idx
                break
            }
            idx = (idx + 1) % suggestions.count
        }

        // If every available suggestion equals lastShown (only 1 left), allow repeat
        if chosen == nil {
            chosen = available.first!
        }

        let suggestion = suggestions[chosen!]
        currentIndex = (chosen! + 1) % suggestions.count
        lastShown = suggestion
        persist()
        return suggestion
    }

    func dismiss(suggestion: String) {
        if let idx = suggestions.firstIndex(of: suggestion) {
            dismissed.insert(idx)
            persist()
        }
    }

    // MARK: - Helpers

    private func availableIndices() -> Set<Int> {
        let all = Set(0..<suggestions.count)
        return all.subtracting(dismissed)
    }
}
