//
//  Countdown+Extension.swift
//  LeCountdown
//
//  Created by Laurent Morvillier on 25/01/2023.
//

import Foundation
import SwiftUI
import CoreData

extension AbstractSoundTimer {
    
    var sounds: Set<Sound> {
        if let soundList {
            return Set(soundList.enumItems())
        }
        return []
    }
        
    func setSounds(_ sounds: Set<Sound>) {
        self.soundList = sounds.stringRepresentation
    }
    
    var someSound: Sound {
        var sounds = self.sounds
        
        // remove last played sound if the playlist has at least 3 sounds
        if sounds.count > 2,
            let lastSoundId = Preferences.lastSelectedSound[self.stringId],
            let lastSound = Sound(rawValue: lastSoundId) {
            sounds.remove(lastSound)
        }
        
        if let random = sounds.randomElement() {
            Preferences.lastSelectedSound[self.stringId] = random.id
            return random
        }
        
        return Sound.default
    }
    
    var soundName: String {
        return self.someSound.fileName
    }
    
}

extension Stopwatch {
    
    var coolSound: Sound? {
        return Sound(rawValue: Int(self.sound)) ?? nil
    }

    static func fake(context: NSManagedObjectContext) -> Stopwatch {
        let stopwatch = Stopwatch(context: context)
        let activity = Activity(context: context)
        activity.name = "Running"
        stopwatch.activity = activity
        return stopwatch
    }

}

extension Record {
    
    var count: Double { return 1.0 }

    public override func didChangeValue(forKey key: String) {
        super.didChangeValue(forKey: key)
        
        switch key {
        case "start", "end":
            self.preCompute()
        default:
            break
        }
    }
    
    func preCompute() {
        if let start {
            self.year = Int16(start.year)
            self.month = Int16(start.month)
            if let end {
                self.duration = end.timeIntervalSince(start)
            }
        }
    }
    
    var formattedDay: String {
        if let start {
            return start.formatted(date: .abbreviated, time: .omitted)
        }
        return ""
    }
    
    var details: String {
        if let start, let end {
            return "\(start.formatted()) - \(end.formatted())"
        } else {
            return "no details"
        }
    }
    
}

extension Activity {
    
    fileprivate static var formatter: NumberFormatter = NumberFormatter()
    
    var recordCount: String {
        let count: Int = self.records?.count ?? 0
        return Activity.formatter.string(from: NSNumber(value: count)) ?? "--"
    }
    
}

extension CustomSound : Localized {
    
    var localizedString: String {
        return self.text ?? ""
    }
    
}


// MARK: - Storage convenience

fileprivate let separator = "|"
fileprivate let formatter: NumberFormatter = NumberFormatter()

extension String {
    
    func enumItems<T : RawRepresentable<Int>>() -> [T] {
        let ids: [String] = self.components(separatedBy: separator)
        let intIds: [Int] = ids.compactMap { formatter.number(from: $0)?.intValue }
        return intIds.compactMap { T(rawValue: $0) }
    }
    
}

extension Sequence where Element : RawRepresentable<Int> {
    
    var stringRepresentation: String {
        let ids = self.compactMap { formatter.string(from: NSNumber(value: $0.rawValue)) }
        return ids.joined(separator: separator)
    }
    
}
