//
// WeightProgressionChartView.swift
// Workouts
//
// Created on 7/20/25.
//
// Copyright 2025 Rouslan Zenetl. All Rights Reserved.
//

import SwiftUI
import Charts
import SwiftData

struct WeightProgressionChartView: View {
    let exerciseName: String

    /// Completed logs for this exercise, oldest first.
    @Query private var logs: [WorkoutLog]

    init(exerciseName: String) {
        self.exerciseName = exerciseName
        let name = exerciseName
        // `completed` is derived (status == .completed); the predicate compares the
        // stored `statusRaw` column directly, since #Predicate can't call a computed
        // property. Capture the raw value in a local so the macro can embed it.
        let completedRaw = WorkoutStatus.completed.rawValue
        _logs = Query(
            filter: #Predicate<WorkoutLog> { $0.exerciseName == name && $0.statusRaw == completedRaw },
            sort: \WorkoutLog.date,
            order: .forward
        )
    }

    @AppStorage("weightUnit") private var weightUnit: WeightUnit = .lb

    private var weightData: [WeightDataPoint] {
        // Top-set *actual* weight per completed log; legacy logs without recorded
        // entries fall back to the planned weight (the old behavior).
        logs.map { log in
            let topSet = log.setEntries?.compactMap(\.weight).max()
            return WeightDataPoint(date: log.date, weight: topSet ?? log.weight)
        }
    }

    var body: some View {
        VStack(alignment: .leading) {
            if weightData.isEmpty {
                Text("No weight history available yet.")
                    .foregroundColor(.secondary)
                    .frame(maxWidth: .infinity, alignment: .center)
                    .padding()
            } else {
                Text("Weight Progression")
                    .font(.headline)
                    .padding(.bottom, 4)

                Chart {
                    ForEach(weightData) { dataPoint in
                        LineMark(
                            x: .value("Date", dataPoint.date),
                            y: .value("Weight", dataPoint.weight)
                        )
                        .foregroundStyle(Color.blue.gradient)
                        .interpolationMethod(.catmullRom)

                        PointMark(
                            x: .value("Date", dataPoint.date),
                            y: .value("Weight", dataPoint.weight)
                        )
                        .foregroundStyle(Color.blue)
                    }
                }
                .chartYScale(domain: .automatic(includesZero: false))
                .chartXAxis {
                    AxisMarks(values: .automatic) { _ in
                        AxisGridLine()
                        AxisValueLabel(format: .dateTime.month().day())
                    }
                }
                .frame(height: 200)
                .padding(.bottom, 8)

                if !motivationalMessage.isEmpty {
                    Text(motivationalMessage)
                        .font(.subheadline)
                        .foregroundColor(.primary)
                        .padding()
                        .background(Color.blue.opacity(0.1))
                        .cornerRadius(8)
                }
            }
        }
        .padding()
    }

    private var motivationalMessage: String {
        let data = weightData
        guard data.count >= 2 else {
            return "Complete more workouts to track your progress!"
        }

        let firstWeight = data.first?.weight ?? 0
        let currentWeight = data.last?.weight ?? 0
        let weightDifference = currentWeight - firstWeight

        if weightDifference > 0 {
            let percentIncrease = firstWeight > 0
                ? Int((weightDifference / firstWeight) * 100)
                : 0
            if percentIncrease >= 20 {
                return "Amazing progress! You've increased your weight by \(weightUnit.format(weightDifference)) (\(percentIncrease)%)!"
            } else if percentIncrease >= 10 {
                return "Great job! You've increased your weight by \(weightUnit.format(weightDifference)) (\(percentIncrease)%)!"
            } else {
                return "You're making progress! Weight increased by \(weightUnit.format(weightDifference)). Keep it up!"
            }
        } else if weightDifference == 0 {
            return "You're maintaining consistent weight. Focus on form and consider increasing when ready!"
        } else {
            return "Your current weight is lower than when you started. Adjust your training as needed and keep pushing!"
        }
    }
}

// Data structure for chart points
struct WeightDataPoint: Identifiable {
    let id = UUID()
    let date: Date
    let weight: Double
}
