//
//  StarFieldView.swift
//  MoonWatch
//

import SwiftUI

struct StarFieldView: View {
    var starCount: Int = 160

    @State private var stars: [Star] = []

    private struct Star: Identifiable {
        let id = UUID()
        let position: CGPoint   // 0...1 normalized
        let radius: CGFloat
        let baseOpacity: Double
        let twinklePhase: Double
        let twinkleSpeed: Double
        let warm: Bool
    }

    var body: some View {
        GeometryReader { geo in
            TimelineView(.animation(minimumInterval: 1.0 / 12.0)) { ctx in
                Canvas { context, size in
                    let t = ctx.date.timeIntervalSinceReferenceDate
                    for star in stars {
                        let twinkle = (sin(t * star.twinkleSpeed + star.twinklePhase) + 1) / 2
                        let alpha = star.baseOpacity * (0.35 + 0.65 * twinkle)
                        let center = CGPoint(
                            x: star.position.x * size.width,
                            y: star.position.y * size.height
                        )
                        let rect = CGRect(
                            x: center.x - star.radius,
                            y: center.y - star.radius,
                            width: star.radius * 2,
                            height: star.radius * 2
                        )
                        let color: Color = star.warm
                            ? Color(red: 1.0, green: 0.92, blue: 0.78).opacity(alpha)
                            : Color(red: 0.92, green: 0.95, blue: 1.0).opacity(alpha)
                        context.fill(Path(ellipseIn: rect), with: .color(color))
                        if star.radius > 1.1 {
                            // Soft halo for the larger stars.
                            let halo = rect.insetBy(dx: -star.radius * 1.6, dy: -star.radius * 1.6)
                            context.fill(
                                Path(ellipseIn: halo),
                                with: .color(color.opacity(0.20))
                            )
                        }
                    }
                }
            }
            .onAppear {
                if stars.isEmpty {
                    stars = Self.generate(count: starCount)
                }
            }
        }
        .ignoresSafeArea()
        .allowsHitTesting(false)
    }

    private static func generate(count: Int) -> [Star] {
        var rng = SystemRandomNumberGenerator()
        return (0..<count).map { _ in
            let big = Double.random(in: 0...1, using: &rng) > 0.88
            return Star(
                position: CGPoint(
                    x: CGFloat.random(in: 0...1, using: &rng),
                    y: CGFloat.random(in: 0...1, using: &rng)
                ),
                radius: big
                    ? CGFloat.random(in: 1.4...2.2, using: &rng)
                    : CGFloat.random(in: 0.4...1.1, using: &rng),
                baseOpacity: Double.random(in: 0.35...0.95, using: &rng),
                twinklePhase: Double.random(in: 0...(2 * .pi), using: &rng),
                twinkleSpeed: Double.random(in: 0.5...1.7, using: &rng),
                warm: Double.random(in: 0...1, using: &rng) > 0.75
            )
        }
    }
}

#Preview {
    ZStack {
        Color(red: 0.03, green: 0.04, blue: 0.10).ignoresSafeArea()
        StarFieldView()
    }
}
