//
//  MoonWatchWidget.swift
//  MoonWatchWidget
//
//  Home Screen + Lock Screen widget showing the current moon phase.
//  Pulls phase math + the photographic moon disk from the Shared module.
//

import SwiftUI
import WidgetKit

struct MoonPhaseEntry: TimelineEntry, Sendable {
    let date: Date
    let snapshot: MoonPhaseSnapshot
}

struct MoonPhaseProvider: TimelineProvider {
    func placeholder(in context: Context) -> MoonPhaseEntry {
        let now = Date()
        return MoonPhaseEntry(date: now, snapshot: MoonPhaseCalculator.snapshot(for: now))
    }

    func getSnapshot(
        in context: Context,
        completion: @escaping @Sendable (MoonPhaseEntry) -> Void
    ) {
        let now = Date()
        completion(MoonPhaseEntry(date: now, snapshot: MoonPhaseCalculator.snapshot(for: now)))
    }

    func getTimeline(
        in context: Context,
        completion: @escaping @Sendable (Timeline<MoonPhaseEntry>) -> Void
    ) {
        var entries: [MoonPhaseEntry] = []
        let now = Date()
        let cal = Calendar.current
        // 48 hourly entries covers two full days; .atEnd triggers a fresh
        // reload once the last entry is consumed, so the widget is always current.
        for hourOffset in 0..<48 {
            let date = cal.date(byAdding: .hour, value: hourOffset, to: now) ?? now
            let snap = MoonPhaseCalculator.snapshot(for: date)
            entries.append(MoonPhaseEntry(date: date, snapshot: snap))
        }
        completion(Timeline(entries: entries, policy: .atEnd))
    }
}

struct MoonWatchWidgetEntryView: View {
    var entry: MoonPhaseEntry
    @Environment(\.widgetFamily) private var family

    var body: some View {
        switch family {
        case .systemSmall:
            smallView
        case .systemMedium:
            mediumView
        case .systemLarge:
            largeView
        case .accessoryCircular:
            circularAccessory
        case .accessoryRectangular:
            rectangularAccessory
        case .accessoryInline:
            Text("\(Image(systemName: "moon.fill")) \(entry.snapshot.namedPhase.rawValue)")
        default:
            smallView
        }
    }

    private var smallView: some View {
        VStack(spacing: 6) {
            MoonImageDisk(normalizedPhase: entry.snapshot.normalizedPhase)
                .frame(maxWidth: .infinity, maxHeight: .infinity)
            Text(entry.snapshot.namedPhase.rawValue)
                .font(.caption2.weight(.semibold))
                .foregroundStyle(.white)
                .lineLimit(1)
                .minimumScaleFactor(0.7)
            Text("\(Int((entry.snapshot.illuminatedFraction * 100).rounded()))% lit")
                .font(.caption2)
                .foregroundStyle(.white.opacity(0.7))
        }
    }

    private var mediumView: some View {
        HStack(spacing: 14) {
            MoonImageDisk(normalizedPhase: entry.snapshot.normalizedPhase)
                .frame(maxWidth: .infinity, maxHeight: .infinity)
                .frame(maxWidth: 130)
            VStack(alignment: .leading, spacing: 6) {
                Text(entry.snapshot.namedPhase.rawValue)
                    .font(.headline.weight(.semibold))
                    .foregroundStyle(.white)
                Text("\(Int((entry.snapshot.illuminatedFraction * 100).rounded()))% illuminated")
                    .font(.subheadline)
                    .foregroundStyle(.white.opacity(0.75))
                Text("Age: \(String(format: "%.1f", entry.snapshot.moonAgeDays)) days")
                    .font(.subheadline)
                    .foregroundStyle(.white.opacity(0.6))
            }
            .frame(maxWidth: .infinity, alignment: .leading)
        }
    }

    private var largeView: some View {
        VStack(spacing: 12) {
            MoonImageDisk(normalizedPhase: entry.snapshot.normalizedPhase)
                .frame(maxWidth: .infinity, maxHeight: .infinity)
            VStack(spacing: 4) {
                Text(entry.snapshot.namedPhase.rawValue)
                    .font(.title3.weight(.semibold))
                    .foregroundStyle(.white)
                Text(
                    "\(Int((entry.snapshot.illuminatedFraction * 100).rounded()))% lit  ·  age \(String(format: "%.1f", entry.snapshot.moonAgeDays)) days"
                )
                .font(.subheadline)
                .foregroundStyle(.white.opacity(0.7))
            }
        }
    }

    private var circularAccessory: some View {
        ZStack {
            AccessoryWidgetBackground()
            MoonImageDisk(normalizedPhase: entry.snapshot.normalizedPhase)
                .padding(2)
        }
    }

    private var rectangularAccessory: some View {
        HStack(spacing: 8) {
            MoonImageDisk(normalizedPhase: entry.snapshot.normalizedPhase)
                .frame(width: 32, height: 32)
            VStack(alignment: .leading, spacing: 1) {
                Text(entry.snapshot.namedPhase.rawValue)
                    .font(.caption.weight(.semibold))
                Text(
                    "\(Int((entry.snapshot.illuminatedFraction * 100).rounded()))% · \(String(format: "%.1f", entry.snapshot.moonAgeDays))d"
                )
                .font(.caption2)
                .foregroundStyle(.secondary)
            }
        }
    }
}

struct MoonWatchWidget: Widget {
    let kind: String = "MoonWatchWidget"

    var body: some WidgetConfiguration {
        StaticConfiguration(kind: kind, provider: MoonPhaseProvider()) { entry in
            MoonWatchWidgetEntryView(entry: entry)
                .containerBackground(for: .widget) {
                    LinearGradient(
                        colors: [
                            Color(red: 0.04, green: 0.04, blue: 0.14),
                            Color(red: 0.06, green: 0.04, blue: 0.18),
                            Color(red: 0.01, green: 0.02, blue: 0.06),
                        ],
                        startPoint: .top,
                        endPoint: .bottom
                    )
                }
        }
        .configurationDisplayName("Moon Phase")
        .description("See the current phase of the moon at a glance.")
        .supportedFamilies([
            .systemSmall,
            .systemMedium,
            .systemLarge,
            .accessoryCircular,
            .accessoryRectangular,
            .accessoryInline,
        ])
    }
}

@main
struct MoonWatchWidgetBundle: WidgetBundle {
    var body: some Widget {
        MoonWatchWidget()
    }
}

#Preview(as: .systemSmall) {
    MoonWatchWidget()
} timeline: {
    MoonPhaseEntry(date: .now, snapshot: MoonPhaseCalculator.snapshot(for: .now))
}

#Preview(as: .systemMedium) {
    MoonWatchWidget()
} timeline: {
    MoonPhaseEntry(date: .now, snapshot: MoonPhaseCalculator.snapshot(for: .now))
}

#Preview(as: .accessoryRectangular) {
    MoonWatchWidget()
} timeline: {
    MoonPhaseEntry(date: .now, snapshot: MoonPhaseCalculator.snapshot(for: .now))
}
