import Foundation

enum ReviewQuality: Int, Sendable {
    case again = 0      // Complete failure
    case hard = 1       // Significant difficulty
    case good = 3       // Correct with some effort
    case easy = 5       // Perfect recall
}

struct SRSEngine: Sendable {
    /// Apply SM-2 algorithm. Returns updated (easeFactor, interval, repetitions).
    static func review(
        quality: ReviewQuality,
        currentEase: Double,
        currentInterval: Int,
        currentReps: Int
    ) -> (easeFactor: Double, interval: Int, repetitions: Int) {
        let q = Double(quality.rawValue)

        // Calculate new ease factor
        var newEase = currentEase + (0.1 - (5.0 - q) * (0.08 + (5.0 - q) * 0.02))
        newEase = max(1.3, newEase)

        var newInterval: Int
        var newReps: Int

        if quality.rawValue < 2 {
            // Failed — reset
            newReps = 0
            newInterval = 0
        } else {
            newReps = currentReps + 1
            switch newReps {
            case 1: newInterval = 1
            case 2: newInterval = 6
            default: newInterval = Int(round(Double(currentInterval) * newEase))
            }
        }

        return (newEase, newInterval, newReps)
    }

    /// Calculate next due date from today
    static func nextDueDate(interval: Int) -> Date {
        Calendar.current.date(byAdding: .day, value: max(interval, 0), to: Date()) ?? Date()
    }

    /// Check if a card is due for review
    static func isDue(_ card: some ReviewCardProtocol) -> Bool {
        card.dueDate <= Date()
    }
}

// Protocol so SRSEngine doesn't depend on SwiftData
protocol ReviewCardProtocol {
    var dueDate: Date { get }
    var easeFactor: Double { get }
    var interval: Int { get }
    var repetitions: Int { get }
}

// MARK: - ReviewCard conformance

extension ReviewCard: ReviewCardProtocol {}
