//
// AchievementsSection.swift
// Workouts
//
// Copyright 2026 Rouslan Zenetl. All Rights Reserved.
//

import SwiftUI

/// The achievements badge grid. Every badge is a pure derivation of history
/// (`ProgressPlanner.achievements`) — earned ones glow in their color, locked ones
/// wear a progress ring showing how close they are. Tapping pushes the badge's
/// detail screen with the how-to-earn rule and its story.
struct AchievementsSection: View {
    let achievements: [Achievement]

    private var earnedCount: Int { achievements.filter(\.earned).count }

    var body: some View {
        VStack(alignment: .leading, spacing: 16) {
            HStack {
                Text("Achievements")
                    .font(.headline)
                Spacer()
                Text("\(earnedCount) of \(achievements.count)")
                    .font(.subheadline)
                    .foregroundStyle(.secondary)
                    .monospacedDigit()
            }

            LazyVGrid(columns: Array(repeating: GridItem(.flexible(), spacing: 12), count: 4),
                      spacing: 16) {
                ForEach(achievements) { achievement in
                    NavigationLink {
                        AchievementDetailView(achievement: achievement)
                    } label: {
                        AchievementBadge(achievement: achievement)
                    }
                    .buttonStyle(.plain)
                }
            }
        }
        .progressCard()
    }
}

/// One badge: a tinted circle with the symbol, the title beneath. Locked badges are
/// desaturated with a thin progress arc around the circle.
struct AchievementBadge: View {
    let achievement: Achievement

    private var color: Color { Color.color(from: achievement.colorName) }

    var body: some View {
        VStack(spacing: 6) {
            ZStack {
                Circle()
                    .fill(achievement.earned ? color.opacity(0.18) : Color(.systemFill))
                Image(systemName: achievement.systemImage)
                    .font(.title3)
                    .foregroundStyle(achievement.earned ? color : Color(.tertiaryLabel))
            }
            .frame(width: 52, height: 52)
            .overlay {
                if !achievement.earned, achievement.progress > 0 {
                    Circle()
                        .trim(from: 0, to: achievement.progress)
                        .stroke(color.opacity(0.6),
                                style: StrokeStyle(lineWidth: 3, lineCap: .round))
                        .rotationEffect(.degrees(-90))
                }
            }

            Text(achievement.title)
                .font(.caption2)
                .multilineTextAlignment(.center)
                .lineLimit(2, reservesSpace: true)
                .foregroundStyle(achievement.earned ? .primary : .secondary)
        }
        .frame(maxWidth: .infinity)
        .accessibilityElement(children: .ignore)
        .accessibilityLabel(
            "\(achievement.title), \(achievement.earned ? "earned" : "locked"): \(achievement.detail)")
    }
}

/// One achievement's full-screen read: the badge writ large, its earned/locked state,
/// the how-to-earn rule, and the story of why the milestone matters.
struct AchievementDetailView: View {
    let achievement: Achievement

    private var color: Color { Color.color(from: achievement.colorName) }

    var body: some View {
        ScrollView {
            VStack(spacing: 24) {
                ZStack {
                    Circle()
                        .fill(achievement.earned ? color.opacity(0.18) : Color(.systemFill))
                    Image(systemName: achievement.systemImage)
                        .font(.system(size: 44))
                        .foregroundStyle(achievement.earned ? color : Color(.tertiaryLabel))
                }
                .frame(width: 120, height: 120)
                .overlay {
                    if !achievement.earned, achievement.progress > 0 {
                        Circle()
                            .trim(from: 0, to: achievement.progress)
                            .stroke(color.opacity(0.6),
                                    style: StrokeStyle(lineWidth: 5, lineCap: .round))
                            .rotationEffect(.degrees(-90))
                    }
                }
                .padding(.top, 16)

                VStack(spacing: 8) {
                    Text(achievement.title)
                        .font(.title2.bold())
                        .multilineTextAlignment(.center)
                    if achievement.earned {
                        Label("Earned", systemImage: "checkmark.circle.fill")
                            .font(.subheadline.weight(.semibold))
                            .foregroundStyle(color)
                    } else {
                        Text("\(Int((achievement.progress * 100).rounded()))% there")
                            .font(.subheadline.weight(.semibold))
                            .foregroundStyle(.secondary)
                            .monospacedDigit()
                    }
                }

                VStack(alignment: .leading, spacing: 6) {
                    Text("How to Earn")
                        .font(.footnote.weight(.semibold))
                        .foregroundStyle(.secondary)
                        .textCase(.uppercase)
                    Text(achievement.detail)
                        .font(.body)
                }
                .progressCard()

                VStack(alignment: .leading, spacing: 6) {
                    Text("Why It Matters")
                        .font(.footnote.weight(.semibold))
                        .foregroundStyle(.secondary)
                        .textCase(.uppercase)
                    Text(achievement.story)
                        .font(.body)
                }
                .progressCard()
            }
            .padding(.horizontal)
            .padding(.bottom, 24)
        }
        .background(Color(.systemGroupedBackground))
        .navigationTitle(achievement.title)
        .navigationBarTitleDisplayMode(.inline)
    }
}
