import SwiftUI

/// SVG viewBox dimensions for coordinate conversion
private let svgSize: CGFloat = 512

/// Optical center adjustment (checkmark visual weight is left-heavy)
private let opticalCenterOffset: CGFloat = 8

/// Animatable house roof path (right side)
struct HouseRightPath: Shape {
    var trimEnd: CGFloat = 1.0

    var animatableData: CGFloat {
        get { trimEnd }
        set { trimEnd = newValue }
    }

    func path(in rect: CGRect) -> Path {
        let scale = min(rect.width, rect.height) / svgSize
        let ox = opticalCenterOffset * scale  // optical offset

        var path = Path()
        // M256 108 L375 200 Q392 212 392 235 L392 345 Q392 375 362 375 L335 375
        path.move(to: CGPoint(x: 256 * scale + ox, y: 108 * scale))
        path.addLine(to: CGPoint(x: 375 * scale + ox, y: 200 * scale))
        path.addQuadCurve(
            to: CGPoint(x: 392 * scale + ox, y: 235 * scale),
            control: CGPoint(x: 392 * scale + ox, y: 212 * scale)
        )
        path.addLine(to: CGPoint(x: 392 * scale + ox, y: 345 * scale))
        path.addQuadCurve(
            to: CGPoint(x: 362 * scale + ox, y: 375 * scale),
            control: CGPoint(x: 392 * scale + ox, y: 375 * scale)
        )
        path.addLine(to: CGPoint(x: 335 * scale + ox, y: 375 * scale))

        return path.trimmedPath(from: 0, to: trimEnd)
    }
}

/// Animatable house roof path (left side)
struct HouseLeftPath: Shape {
    var trimEnd: CGFloat = 1.0

    var animatableData: CGFloat {
        get { trimEnd }
        set { trimEnd = newValue }
    }

    func path(in rect: CGRect) -> Path {
        let scale = min(rect.width, rect.height) / svgSize
        let ox = opticalCenterOffset * scale  // optical offset

        var path = Path()
        // M256 108 L137 200 Q120 212 120 235 L120 345 Q120 375 150 375 L177 375
        path.move(to: CGPoint(x: 256 * scale + ox, y: 108 * scale))
        path.addLine(to: CGPoint(x: 137 * scale + ox, y: 200 * scale))
        path.addQuadCurve(
            to: CGPoint(x: 120 * scale + ox, y: 235 * scale),
            control: CGPoint(x: 120 * scale + ox, y: 212 * scale)
        )
        path.addLine(to: CGPoint(x: 120 * scale + ox, y: 345 * scale))
        path.addQuadCurve(
            to: CGPoint(x: 150 * scale + ox, y: 375 * scale),
            control: CGPoint(x: 120 * scale + ox, y: 375 * scale)
        )
        path.addLine(to: CGPoint(x: 177 * scale + ox, y: 375 * scale))

        return path.trimmedPath(from: 0, to: trimEnd)
    }
}

/// Animatable checkmark path
struct CheckmarkPath: Shape {
    var trimEnd: CGFloat = 1.0

    var animatableData: CGFloat {
        get { trimEnd }
        set { trimEnd = newValue }
    }

    func path(in rect: CGRect) -> Path {
        let scale = min(rect.width, rect.height) / svgSize
        let ox = opticalCenterOffset * scale  // optical offset

        var path = Path()
        // M175 320 L235 380 L355 250
        path.move(to: CGPoint(x: 175 * scale + ox, y: 320 * scale))
        path.addLine(to: CGPoint(x: 235 * scale + ox, y: 380 * scale))
        path.addLine(to: CGPoint(x: 355 * scale + ox, y: 250 * scale))

        return path.trimmedPath(from: 0, to: trimEnd)
    }
}

/// Animatable window (rounded rectangle)
struct WindowShape: Shape {
    var scale: CGFloat = 1.0

    var animatableData: CGFloat {
        get { scale }
        set { scale = newValue }
    }

    func path(in rect: CGRect) -> Path {
        let viewScale = min(rect.width, rect.height) / svgSize
        let ox = opticalCenterOffset * viewScale  // optical offset

        // Window at (230, 175) with size 52x52 and corner radius 12
        let windowX: CGFloat = 230
        let windowY: CGFloat = 175
        let windowSize: CGFloat = 52
        let cornerRadius: CGFloat = 12

        // Center point of window (with optical offset)
        let centerX = (windowX + windowSize / 2) * viewScale + ox
        let centerY = (windowY + windowSize / 2) * viewScale

        // Scaled dimensions
        let scaledSize = windowSize * viewScale * scale
        let scaledRadius = cornerRadius * viewScale * scale

        let windowRect = CGRect(
            x: centerX - scaledSize / 2,
            y: centerY - scaledSize / 2,
            width: scaledSize,
            height: scaledSize
        )

        return Path(roundedRect: windowRect, cornerRadius: scaledRadius)
    }
}

/// Background rounded rectangle shape
struct BackgroundShape: Shape {
    func path(in rect: CGRect) -> Path {
        let scale = min(rect.width, rect.height) / svgSize

        // rect at (24, 24) with 464x464 size and rx/ry=100
        let bgRect = CGRect(
            x: 24 * scale,
            y: 24 * scale,
            width: 464 * scale,
            height: 464 * scale
        )

        return Path(roundedRect: bgRect, cornerRadius: 100 * scale)
    }
}

/// HoneyDue icon view with all paths for animation
struct HoneyDueIconView: View {
    // Animation progress values (0 to 1)
    var houseLeftProgress: CGFloat = 1.0
    var houseRightProgress: CGFloat = 1.0
    var windowScale: CGFloat = 1.0
    var checkmarkProgress: CGFloat = 1.0
    var showBackground: Bool = true
    var backgroundOpacity: Double = 1.0

    // Colors
    var backgroundColor: Color = Color(red: 0.96, green: 0.55, blue: 0.24) // #F58D3D
    var foregroundColor: Color = Color(red: 1.0, green: 0.96, blue: 0.92) // #FFF5EB

    // Stroke widths (scaled from SVG)
    private let houseStrokeWidth: CGFloat = 28
    private let checkmarkStrokeWidth: CGFloat = 32

    var body: some View {
        GeometryReader { geometry in
            let size = min(geometry.size.width, geometry.size.height)
            let scale = size / svgSize
            // Center offset to position content in middle of available space
            let offsetX = (geometry.size.width - size) / 2
            let offsetY = (geometry.size.height - size) / 2

            ZStack {
                // Background
                if showBackground {
                    BackgroundShape()
                        .fill(
                            LinearGradient(
                                colors: [
                                    backgroundColor.opacity(1.0),
                                    backgroundColor.opacity(0.85)
                                ],
                                startPoint: .top,
                                endPoint: .bottom
                            )
                        )
                        .opacity(backgroundOpacity)
                        .shadow(color: .black.opacity(0.15), radius: 12 * scale, x: 0, y: 8 * scale)
                }

                // House left side
                HouseLeftPath(trimEnd: houseLeftProgress)
                    .stroke(
                        foregroundColor,
                        style: StrokeStyle(
                            lineWidth: houseStrokeWidth * scale,
                            lineCap: .round,
                            lineJoin: .round
                        )
                    )

                // House right side
                HouseRightPath(trimEnd: houseRightProgress)
                    .stroke(
                        foregroundColor,
                        style: StrokeStyle(
                            lineWidth: houseStrokeWidth * scale,
                            lineCap: .round,
                            lineJoin: .round
                        )
                    )

                // Window
                WindowShape(scale: windowScale)
                    .fill(foregroundColor)

                // Checkmark
                CheckmarkPath(trimEnd: checkmarkProgress)
                    .stroke(
                        foregroundColor,
                        style: StrokeStyle(
                            lineWidth: checkmarkStrokeWidth * scale,
                            lineCap: .round,
                            lineJoin: .round
                        )
                    )
            }
            .frame(width: size, height: size)
            .offset(x: offsetX, y: offsetY)
        }
        .aspectRatio(1, contentMode: .fit)
        .accessibilityHidden(true)
    }
}

/// Animated version with built-in draw animation
struct AnimatedHoneyDueIconView: View {
    @State private var houseLeftProgress: CGFloat = 0
    @State private var houseRightProgress: CGFloat = 0
    @State private var windowScale: CGFloat = 0
    @State private var checkmarkProgress: CGFloat = 0
    @State private var backgroundOpacity: Double = 0

    var animationDuration: Double = 0.5
    var staggerDelay: Double = 0.15
    var showBackground: Bool = true

    var body: some View {
        HoneyDueIconView(
            houseLeftProgress: houseLeftProgress,
            houseRightProgress: houseRightProgress,
            windowScale: windowScale,
            checkmarkProgress: checkmarkProgress,
            showBackground: showBackground,
            backgroundOpacity: backgroundOpacity
        )
        .accessibilityHidden(true)
        .onAppear {
            animateIn()
        }
    }

    func animateIn() {
        // Background fade in
        withAnimation(.easeOut(duration: animationDuration * 0.5)) {
            backgroundOpacity = 1.0
        }

        // House sides draw together
        withAnimation(.easeOut(duration: animationDuration).delay(staggerDelay)) {
            houseLeftProgress = 1.0
            houseRightProgress = 1.0
        }

        // Window pops in
        withAnimation(.spring(response: 0.4, dampingFraction: 0.6).delay(staggerDelay * 2)) {
            windowScale = 1.0
        }

        // Checkmark draws
        withAnimation(.easeOut(duration: animationDuration * 0.8).delay(staggerDelay * 3)) {
            checkmarkProgress = 1.0
        }
    }

    func reset() {
        houseLeftProgress = 0
        houseRightProgress = 0
        windowScale = 0
        checkmarkProgress = 0
        backgroundOpacity = 0
    }
}

#Preview("Static Icon") {
    HoneyDueIconView()
        .frame(width: 200, height: 200)
        .padding()
}

#Preview("Animated Icon") {
    AnimatedHoneyDueIconView()
        .frame(width: 200, height: 200)
        .padding()
}

#Preview("Icon Without Background") {
    HoneyDueIconView(showBackground: false)
        .frame(width: 200, height: 200)
        .padding()
        .background(Color.orange)
}

#Preview("Custom Colors") {
    HoneyDueIconView(
        backgroundColor: .blue,
        foregroundColor: .white
    )
    .frame(width: 200, height: 200)
    .padding()
}
