//
//  ActivityView.swift
//  LeCountdown
//
//  Created by Laurent Morvillier on 20/02/2023.
//

import SwiftUI
import CoreData

struct ActivityView: View {
    
    @Environment(\.managedObjectContext) private var viewContext

    let activity: Activity
    
    @State var selectedTimeFrame: TimeFrame = .all
    
    var body: some View {
        
        VStack {
            Picker("Time", selection: $selectedTimeFrame) {
                ForEach(TimeFrame.allCases) { timeFrame in
                    Text(timeFrame.localizedString).tag(timeFrame)
                }
            }
            .pickerStyle(.segmented)
            .padding(.horizontal)
            
            List {
                
                GraphsView(activity: self.activity,
                          timeFrame: self.selectedTimeFrame)
                .environment(\.managedObjectContext, viewContext)
                
                let filters = self.selectedTimeFrame.filters(context: viewContext, activity: activity)
                RecordsView(activity: self.activity, filters: filters)
                    .environment(\.managedObjectContext, viewContext)
            }
            
        }
    }
    
}

enum TimeFrame: Int, Identifiable, CaseIterable {
    
    var id: Int { return self.rawValue }
    
    case all
    case year
    case month
    
    var localizedString: String {
        switch self {
        case .all: return NSLocalizedString("All", comment: "")
        case .year: return NSLocalizedString("Year", comment: "")
        case .month: return NSLocalizedString("Month", comment: "")
        }
    }
    
    func filters(context: NSManagedObjectContext, activity: Activity) -> [Filter] {
        
        let predicate = NSPredicate(format: "activity = %@", activity)
        
        do {
            switch self {
            case .all:
                return [.none]
            case .year:
                let distinct = try context.distinct(entityName: "Record", attributes: ["year"], predicate: predicate)
                if let yearsMap = distinct as? [[String : Int]] {
                    let years = yearsMap.compactMap { $0.first?.value }
                    return years.map { Filter.year($0) }
                } else {
                    Logger.w("Could not cast \(distinct) as [Int]")
                }
            case .month:
                let distinct = try context.distinct(entityName: "Record", attributes: ["year", "month"], predicate: predicate)
                if let distinctMonths = distinct as? [[String : Int]] {
                    
                    let months = distinctMonths.compactMap {
                        if let month = $0["month"],
                           let year = $0["year"] {
                            return Month(month: month, year: year)
                        } else {
                            Logger.w("issue with dictionary \($0)")
                            return nil
                        }
                    }
                    return months.map { Filter.month($0) }
                } else {
                    Logger.w("Could not cast \(distinct) as [Int]")
                }
            }
        } catch {
            Logger.error(error)
        }
        return []
    }
    
}

struct ActivityView_Previews: PreviewProvider {
    static var previews: some View {
        ActivityView(activity: Activity.fake(context: PersistenceController.preview.container.viewContext), selectedTimeFrame: .all)
            .environment(\.managedObjectContext, PersistenceController.preview.container.viewContext)
    }
}
