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

import SwiftUI
import UIKit

/// The calendar toolbar button's sheet: jumps the Today board to any day. Days with
/// at least one logged workout carry a small dot. Built on `UICalendarView` rather
/// than the SwiftUI graphical `DatePicker` solely because only the UIKit calendar
/// supports per-day decorations. Picking a day (or "Today") dismisses immediately —
/// this is navigation, not a form, so there's nothing to confirm.
struct DayPickerSheet: View {
    @Binding var selectedDate: Date
    /// Day-precision (year/month/day) components of the days to decorate.
    let workoutDays: Set<DateComponents>

    @Environment(\.dismiss) private var dismiss

    var body: some View {
        NavigationStack {
            DayCalendarView(selectedDate: $selectedDate, workoutDays: workoutDays) {
                dismiss()
            }
            .padding(.horizontal)
            .navigationTitle("Go to Day")
            .navigationBarTitleDisplayMode(.inline)
            .toolbar {
                ToolbarItem(placement: .topBarLeading) {
                    Button("Today") {
                        selectedDate = Date()
                        dismiss()
                    }
                }
                ToolbarItem(placement: .topBarTrailing) {
                    Button("Done") { dismiss() }
                }
            }
        }
        .presentationDetents([.medium, .large])
    }
}

/// `UICalendarView` wrapper: single-date selection plus a dot decoration on each
/// day in `workoutDays`.
private struct DayCalendarView: UIViewRepresentable {
    @Binding var selectedDate: Date
    let workoutDays: Set<DateComponents>
    /// Called after a day is picked — the sheet dismisses itself here.
    var onPick: () -> Void

    func makeCoordinator() -> Coordinator { Coordinator(self) }

    func makeUIView(context: Context) -> UICalendarView {
        let view = UICalendarView()
        view.calendar = Calendar.current
        view.delegate = context.coordinator
        let selection = UICalendarSelectionSingleDate(delegate: context.coordinator)
        selection.setSelected(
            Calendar.current.dateComponents([.year, .month, .day], from: selectedDate),
            animated: false
        )
        view.selectionBehavior = selection
        return view
    }

    func updateUIView(_ uiView: UICalendarView, context: Context) {
        context.coordinator.parent = self
    }

    @MainActor
    final class Coordinator: NSObject, UICalendarViewDelegate, UICalendarSelectionSingleDateDelegate {
        var parent: DayCalendarView

        init(_ parent: DayCalendarView) { self.parent = parent }

        func calendarView(_ calendarView: UICalendarView,
                          decorationFor dateComponents: DateComponents) -> UICalendarView.Decoration? {
            // The view hands back components richer than year/month/day (era, calendar,
            // …) — reduce to day precision so set membership compares equal.
            var day = DateComponents()
            day.year = dateComponents.year
            day.month = dateComponents.month
            day.day = dateComponents.day
            return parent.workoutDays.contains(day) ? .default(color: .systemGreen, size: .small) : nil
        }

        func dateSelection(_ selection: UICalendarSelectionSingleDate,
                           didSelectDate dateComponents: DateComponents?) {
            guard let dateComponents, let date = Calendar.current.date(from: dateComponents) else { return }
            parent.selectedDate = date
            parent.onPick()
        }
    }
}
