import Foundation

struct Prediction: Codable, Identifiable {
    let id: UUID
    let date: Date
    let predictedValue: Decimal
    let algorithm: PredictionAlgorithm
    let confidenceInterval: ConfidenceInterval

    init(
        id: UUID = UUID(),
        date: Date,
        predictedValue: Decimal,
        algorithm: PredictionAlgorithm,
        confidenceInterval: ConfidenceInterval
    ) {
        self.id = id
        self.date = date
        self.predictedValue = predictedValue
        self.algorithm = algorithm
        self.confidenceInterval = confidenceInterval
    }

    struct ConfidenceInterval: Codable {
        let lower: Decimal
        let upper: Decimal

        var range: Decimal {
            upper - lower
        }

        var percentageWidth: Decimal {
            guard upper != 0 else { return 0 }
            return (range / upper) * 100
        }
    }
}

// MARK: - Prediction Algorithm Codable

extension PredictionAlgorithm: Codable {}

// MARK: - Prediction Helpers

extension Prediction {
    var formattedValue: String {
        CurrencyFormatter.format(predictedValue, style: .currency, maximumFractionDigits: 0)
    }

    var formattedDate: String {
        let formatter = DateFormatter()
        formatter.dateFormat = "MMM yyyy"
        return formatter.string(from: date)
    }

    var formattedConfidenceRange: String {
        let lower = CurrencyFormatter.format(
            confidenceInterval.lower,
            style: .currency,
            maximumFractionDigits: 0
        )
        let upper = CurrencyFormatter.format(
            confidenceInterval.upper,
            style: .currency,
            maximumFractionDigits: 0
        )

        return "\(lower) - \(upper)"
    }
}

// MARK: - Prediction Result

struct PredictionResult {
    let predictions: [Prediction]
    let algorithm: PredictionAlgorithm
    let accuracy: Double // R-squared or similar metric
    let volatility: Double

    var isHighConfidence: Bool {
        accuracy >= 0.7
    }

    var confidenceLevel: ConfidenceLevel {
        switch accuracy {
        case 0.8...: return .high
        case 0.5..<0.8: return .medium
        default: return .low
        }
    }

    enum ConfidenceLevel: String {
        case high = "High"
        case medium = "Medium"
        case low = "Low"

        var color: String {
            switch self {
            case .high: return "#10B981"
            case .medium: return "#F59E0B"
            case .low: return "#EF4444"
            }
        }
    }
}
