import Foundation
import CoreData

@objc(Snapshot)
public class Snapshot: NSManagedObject, Identifiable {
    @nonobjc public class func fetchRequest() -> NSFetchRequest<Snapshot> {
        return NSFetchRequest<Snapshot>(entityName: "Snapshot")
    }

    @NSManaged public var id: UUID
    @NSManaged public var date: Date
    @NSManaged public var value: NSDecimalNumber?
    @NSManaged public var contribution: NSDecimalNumber?
    @NSManaged public var notes: String?
    @NSManaged public var createdAt: Date
    @NSManaged public var source: InvestmentSource?

    public override func awakeFromInsert() {
        super.awakeFromInsert()
        id = UUID()
        date = Date()
        createdAt = Date()
    }

    public override func awakeFromFetch() {
        super.awakeFromFetch()
        // Defensive: ensure id exists for legacy rows where id may be nil.
        if value(forKey: "id") == nil {
            setValue(UUID(), forKey: "id")
        }
    }
}

// MARK: - Computed Properties

extension Snapshot {
    var safeId: UUID {
        if let existing = primitiveValue(forKey: "id") as? UUID {
            return existing
        }
        let newId = UUID()
        setPrimitiveValue(newId, forKey: "id")
        return newId    
    }

    var safeDate: Date {
        if let dateValue = primitiveValue(forKey: "date") as? Date {
            return dateValue
        }
        return Date()
    }

    var decimalValue: Decimal {
        value?.decimalValue ?? Decimal.zero
    }

    var decimalContribution: Decimal {
        contribution?.decimalValue ?? Decimal.zero
    }

    var formattedValue: String {
        CurrencyFormatter.format(value?.decimalValue ?? Decimal.zero, style: .currency, maximumFractionDigits: 2)
    }

    var formattedDate: String {
        let formatter = DateFormatter()
        formatter.dateStyle = .medium
        formatter.timeStyle = .none
        return formatter.string(from: date)
    }

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

// MARK: - Comparison with Previous

extension Snapshot {
    func change(from previousSnapshot: Snapshot?) -> Decimal {
        guard let previous = previousSnapshot,
              let previousValue = previous.value?.decimalValue,
              previousValue != Decimal.zero else {
            return Decimal.zero
        }

        let currentValue = value?.decimalValue ?? Decimal.zero
        return currentValue - previousValue
    }

    func percentageChange(from previousSnapshot: Snapshot?) -> Decimal {
        guard let previous = previousSnapshot,
              let previousValue = previous.value?.decimalValue,
              previousValue != Decimal.zero else {
            return Decimal.zero
        }

        let currentValue = value?.decimalValue ?? Decimal.zero
        return ((currentValue - previousValue) / previousValue) * 100
    }
}
