//
//  FilterView.swift
//  Feels
//
//  Created by Trey Tartt on 1/12/22.
//

import SwiftUI
import CoreData

struct YearView: View {
    let months = [(0, "J"), (1, "F"), (2,"M"), (3,"A"), (4,"M"), (5, "J"), (6,"J"), (7,"A"), (8,"S"), (9,"O"), (10, "N"), (11,"D")]
    
    @State private var toggle = true
    
    @FetchRequest(
        sortDescriptors: [NSSortDescriptor(keyPath: \MoodEntry.forDate, ascending: false)],
        animation: .spring())
    private var items: FetchedResults<MoodEntry>
    
    @AppStorage(UserDefaultsStore.Keys.theme.rawValue, store: GroupUserDefaults.groupDefaults) private var theme: Theme = .system
    @AppStorage(UserDefaultsStore.Keys.moodTint.rawValue, store: GroupUserDefaults.groupDefaults) private var moodTint: MoodTints = .Default
    @AppStorage(UserDefaultsStore.Keys.textColor.rawValue, store: GroupUserDefaults.groupDefaults) private var textColor: Color = DefaultTextColor.textColor

    @StateObject public var viewModel: YearViewModel
    @StateObject private var filteredDays = DaysFilterClass.shared
    //[
    //  2001: [0: [], 1: [], 2: []],
    //  2002: [0: [], 1: [], 2: []]
    // ]
    let columns = [
        GridItem(.flexible(minimum: 5, maximum: 50)),
        GridItem(.flexible(minimum: 5, maximum: 50)),
        GridItem(.flexible(minimum: 5, maximum: 50)),
        GridItem(.flexible(minimum: 5, maximum: 50)),
        GridItem(.flexible(minimum: 5, maximum: 50)),
        GridItem(.flexible(minimum: 5, maximum: 50)),
        GridItem(.flexible(minimum: 5, maximum: 50)),
        GridItem(.flexible(minimum: 5, maximum: 50)),
        GridItem(.flexible(minimum: 5, maximum: 50)),
        GridItem(.flexible(minimum: 5, maximum: 50)),
        GridItem(.flexible(minimum: 5, maximum: 50)),
        GridItem(.flexible(minimum: 5, maximum: 50)),
    ]
    
    var body: some View {
        ScrollView {
            gridView
                .onAppear(perform: {
                    self.viewModel.filterEntries(startDate: Date(timeIntervalSince1970: 0), endDate: Date())
                })
        }
        .padding(.bottom, 5)
        .background(
            theme.currentTheme.bg
                .edgesIgnoringSafeArea(.all)
        )
    }

    private var monthsHeader: some View {
        LazyVGrid(columns: columns, spacing: 0) {
            ForEach(months, id: \.self.0) { item in
                Text(item.1)
                    .textCase(.uppercase)
                    .foregroundColor(textColor)
            }
        }.padding([.leading, .trailing, .top])
    }
    
    private var gridView: some View {
        VStack {
           VStack {
                ForEach(Array(self.viewModel.data.keys.sorted(by: >)), id: \.self) { yearKey in
                    let yearData = self.viewModel.data[yearKey]!
                    
                    let firstOfYear = Calendar.current.date(from: DateComponents(year: Int(yearKey), month: 1, day: 1))!
                    let lastOfYear = Calendar.current.date(from: DateComponents(year: Int(yearKey)+1, month: 1, day: 1))!
                
                    let yearEntries = PersistenceController.shared.getData(startDate: firstOfYear,
                                                                           endDate: lastOfYear,
                                                                           includedDays: filteredDays.currentFilters)
                    Text(String(yearKey))
                        .font(.title)
                        .foregroundColor(textColor)
                    
                    ZStack {
                        theme.currentTheme.secondaryBGColor
                        
                        HStack {
                            Spacer()
                            ForEach(Mood.allValues, id: \.self) { mood in
                                VStack {
                                    Text(String(Stats.getCountFor(moodType: mood,
                                                                  inData: yearEntries)))
                                    .font(.title)
                                    .foregroundColor(textColor)
                                    Text(mood.strValue)
                                        .foregroundColor(moodTint.color(forMood: mood))
                                }
                                Spacer()
                            }
                        }
                    }
                    .cornerRadius(10)
                    .frame(minWidth: 0, maxWidth: .infinity, minHeight: 90, maxHeight: 90)
                    .cornerRadius(10)
                    .padding()
                    
                    Text(String(localized: "filter_view_total") + ":  \(yearEntries.count)")
                        .font(.title2)
                        .foregroundColor(textColor)
                    monthsHeader
                        .cornerRadius(10)
                    yearGridView(yearData: yearData, columns: columns)
                        .background(
                            theme.currentTheme.secondaryBGColor
                        )
                        .cornerRadius(10)
                }
                .padding([.top, .leading, .trailing])
            }
        }
    }
    
    private struct yearGridView: View {
        let yearData: [Int: [DayChartView]]
        let columns: [GridItem]
        
        var body: some View {
            VStack {
                LazyVGrid(columns: columns, spacing: 0) {
                    ForEach(Array(yearData.keys.sorted(by: <)), id: \.self) { monthKey in
                        let monthData = yearData[monthKey]!
                        VStack {
                            monthGridView(monthData: monthData)
                        }
                    }
                }
                .padding([.leading, .trailing, .top, .bottom])
            }
            .cornerRadius(10)
        }
    }
    
    private struct monthGridView: View {
        @StateObject private var filteredDays = DaysFilterClass.shared
        
        let monthData: [DayChartView]
        
        var body: some View {
            VStack {
                ForEach(monthData, id: \.self) { view in
                    if filteredDays.currentFilters.contains(view.weekDay) {
                        view
                    } else {
                        view.filteredDaysView
                    }
                }
            }
        }
    }
}

struct YearView_Previews: PreviewProvider {
    static var previews: some View {
        Group {
            YearView(viewModel: YearViewModel())
            
            YearView(viewModel: YearViewModel())
                .preferredColorScheme(.dark)
        }
    }
}
