//
//  GraphView.swift
//  Weight Display WatchKit Extension
//
//  Created by David Lara on 9/21/22.
//

import SwiftUI
import Charts

// MARK: - MODELS
struct WeightData : Identifiable, Comparable {
    let id = UUID()
    let date: Date
    let weight: Int
    
    init(year: Int, month: Int, day: Int, hour: Int, minute: Int, weight: Int) {
        self.date = Calendar.current.date(from: .init(year: year, month: month, day: day, hour: hour, minute: minute)) ?? Date()
        self.weight = weight
    }
    
    static func < (lhs: Self, rhs: Self) -> Bool {
        return lhs.date.timeIntervalSince1970 < rhs.date.timeIntervalSince1970
    }

    static func <= (lhs: Self, rhs: Self) -> Bool {
        return lhs.date.timeIntervalSince1970 <= rhs.date.timeIntervalSince1970
    }

    static func >= (lhs: Self, rhs: Self) -> Bool {
        return lhs.date.timeIntervalSince1970 >= rhs.date.timeIntervalSince1970
    }

    static func > (lhs: Self, rhs: Self) -> Bool {
        return lhs.date.timeIntervalSince1970 > rhs.date.timeIntervalSince1970
    }
}

// MARK: - VIEW

struct DailyGraphView: View {
    var userWeightData : [WeightData];
    var dateDomain : ClosedRange<Date>;
    
    init() {
        // Obtain user weight data
        userWeightData = [
            WeightData(year: 2022, month: 11, day: 29, hour: 1, minute: 40, weight: 180),
            WeightData(year: 2022, month: 11, day: 29, hour: 4, minute: 30, weight: 175),
            WeightData(year: 2022, month: 11, day: 28, hour: 21, minute: 55, weight: 171),
            WeightData(year: 2022, month: 11, day: 29, hour: 8, minute: 12, weight: 173),
            WeightData(year: 2022, month: 11, day: 29, hour: 13, minute: 20, weight: 178),
            WeightData(year: 2022, month: 11, day: 29, hour: 16, minute: 10, weight: 172),
            WeightData(year: 2022, month: 11, day: 29, hour: 18, minute: 30, weight: 168)
        ]
        
        // Create closed range representing the last 24 hours
        let today = Date.now;
        let yesterday = (NSCalendar.current.date(byAdding: Calendar.Component.hour, value: -24, to: today) ?? Date.now) as Date;
        dateDomain = yesterday...today;
        
        // Filter out any dates not in the last 24 hours
        userWeightData = userWeightData.filter { dateDomain.contains($0.date) };
        
        // Sort the dates
        userWeightData.sort(by: { $0.date.timeIntervalSince1970 < $1.date.timeIntervalSince1970 });
    }
    
    var body: some View {
        if #available(watchOSApplicationExtension 9.0, *) {
            if (!userWeightData.isEmpty) {
                VStack {
                    Text("Last 24 Hours")
                    Chart {
                        ForEach(userWeightData.sorted(by: { $0.date.timeIntervalSince1970 < $1.date.timeIntervalSince1970 })) {
                            item in LineMark(
                                x: .value("Time", item.date),
                                y: .value("Weight", item.weight)
                            )
                            .foregroundStyle(.green)
                            .symbol(BasicChartSymbolShape.circle)
                        }
                    }
                    .chartXAxis {
                        AxisMarks(values: .stride(by: .hour, count: 4)) {
                            values in AxisGridLine()
                            AxisValueLabel(format: .dateTime.hour())
                        }
                    }
                    .chartYAxis {
                        AxisMarks(position: .leading)
                    }
                    .chartXScale(domain: dateDomain)
                    .scaledToFit()
                }
            }
            else {
                Text("No weight entries in the last 24 hours")
                    .padding()
                    .multilineTextAlignment(.center)
            }
        }
        else {
            Text("watchOS 9.0 or newer is needed for graph view")
                .padding()
                .multilineTextAlignment(.center)
        }
    }
}

// MARK: - PREVIEW

struct DailyGraphView_Previews: PreviewProvider {
    static var previews: some View {
        DailyGraphView()
    }
}
