//
//  MoonImageDisk.swift
//  Shared moon disk view used by both the app and widget.
//
//  Renders the bundled "Moon" image masked to a circle, applies the
//  geometric phase shadow (multiplied for soft Earthshine), a subtle
//  spherical limb darkening, and a crisp limb stroke.
//

import SwiftUI

public struct MoonImageDisk: View {
    public var normalizedPhase: Double
    /// Mirror horizontally for southern hemisphere observers.
    public var southernHemisphere: Bool
    /// Scale the moon photo inside the circle (e.g. if the source has
    /// a small black border around the disk).
    public var imageScale: CGFloat

    public init(
        normalizedPhase: Double,
        southernHemisphere: Bool = false,
        imageScale: CGFloat = 1.30
    ) {
        self.normalizedPhase = normalizedPhase
        self.southernHemisphere = southernHemisphere
        self.imageScale = imageScale
    }

    public var body: some View {
        GeometryReader { geo in
            let side = min(geo.size.width, geo.size.height)

            ZStack {
                Image("Moon", bundle: .main)
                    .resizable()
                    .interpolation(.high)
                    .aspectRatio(contentMode: .fill)
                    .frame(width: side, height: side)
                    .scaleEffect(imageScale)

                MoonShadowShape(phaseFraction: normalizedPhase)
                    .fill(
                        RadialGradient(
                            colors: [
                                Color(red: 0.04, green: 0.04, blue: 0.10),
                                Color(red: 0.01, green: 0.01, blue: 0.04),
                            ],
                            center: .center,
                            startRadius: 0,
                            endRadius: side * 0.6
                        )
                    )
                    .blur(radius: max(1.0, side * 0.018))
                    .blendMode(.multiply)
            }
            .frame(width: side, height: side)
            .compositingGroup()
            .clipShape(Circle())
            .scaleEffect(x: southernHemisphere ? -1 : 1, y: 1)
            .overlay {
                Circle()
                    .strokeBorder(
                        LinearGradient(
                            colors: [
                                Color.white.opacity(0.40),
                                Color.white.opacity(0.05),
                                Color.black.opacity(0.30),
                            ],
                            startPoint: .topLeading,
                            endPoint: .bottomTrailing
                        ),
                        lineWidth: max(0.6, side * 0.005)
                    )
                    .frame(width: side, height: side)
            }
            .frame(maxWidth: .infinity, maxHeight: .infinity)
        }
        .aspectRatio(1, contentMode: .fit)
    }
}

#Preview("Waxing Crescent") {
    ZStack {
        Color(red: 0.04, green: 0.05, blue: 0.12).ignoresSafeArea()
        MoonImageDisk(normalizedPhase: 0.12)
            .frame(width: 280, height: 280)
    }
}

#Preview("Waxing Gibbous") {
    ZStack {
        Color(red: 0.04, green: 0.05, blue: 0.12).ignoresSafeArea()
        MoonImageDisk(normalizedPhase: 0.35)
            .frame(width: 280, height: 280)
    }
}

#Preview("Full") {
    ZStack {
        Color(red: 0.04, green: 0.05, blue: 0.12).ignoresSafeArea()
        MoonImageDisk(normalizedPhase: 0.50)
            .frame(width: 280, height: 280)
    }
}
