import SwiftUI

// MARK: - Custom Shape for Rounded Corners
struct RoundedCorners: Shape {
    var topLeft: CGFloat = 0.0
    var topRight: CGFloat = 0.0
    var bottomLeft: CGFloat = 0.0
    var bottomRight: CGFloat = 0.0
    
    func path(in rect: CGRect) -> Path {
        var path = Path()
        
        let width = rect.size.width
        let height = rect.size.height
        
        // Start from top left
        path.move(to: CGPoint(x: topLeft, y: 0))
        
        // Top edge and top right corner
        path.addLine(to: CGPoint(x: width - topRight, y: 0))
        if topRight > 0 {
            path.addArc(
                center: CGPoint(x: width - topRight, y: topRight),
                radius: topRight,
                startAngle: Angle(degrees: -90),
                endAngle: Angle(degrees: 0),
                clockwise: false
            )
        }
        
        // Right edge and bottom right corner
        path.addLine(to: CGPoint(x: width, y: height - bottomRight))
        if bottomRight > 0 {
            path.addArc(
                center: CGPoint(x: width - bottomRight, y: height - bottomRight),
                radius: bottomRight,
                startAngle: Angle(degrees: 0),
                endAngle: Angle(degrees: 90),
                clockwise: false
            )
        }
        
        // Bottom edge and bottom left corner
        path.addLine(to: CGPoint(x: bottomLeft, y: height))
        if bottomLeft > 0 {
            path.addArc(
                center: CGPoint(x: bottomLeft, y: height - bottomLeft),
                radius: bottomLeft,
                startAngle: Angle(degrees: 90),
                endAngle: Angle(degrees: 180),
                clockwise: false
            )
        }
        
        // Left edge and top left corner
        path.addLine(to: CGPoint(x: 0, y: topLeft))
        if topLeft > 0 {
            path.addArc(
                center: CGPoint(x: topLeft, y: topLeft),
                radius: topLeft,
                startAngle: Angle(degrees: 180),
                endAngle: Angle(degrees: 270),
                clockwise: false
            )
        }
        
        path.closeSubpath()
        return path
    }
}

public enum RibbonPosition {
    case topLeft
    case topRight
    case bottomLeft
    case bottomRight
}

public struct BadgeRibbon: View {
    let position: RibbonPosition
    let label: String
    let isRound: Bool
    let backgroundColor: Color
    
    public init(
        position: RibbonPosition = .topRight,
        label: String = "Label",
        isRound: Bool = false,
        backgroundColor: Color? = nil
    ) {
        self.position = position
        self.label = label
        self.isRound = isRound
        self.backgroundColor = backgroundColor ?? Colors.orange03
    }
    
    private var rotation: Angle {
        switch position {
        case .topRight, .bottomRight:
            return .degrees(180)
        case .topLeft, .bottomLeft:
            return .zero
        }
    }
    
    private var useUpTail: Bool {
        position == .bottomLeft || position == .topRight
    }
    
    private var verticalAlignment: VerticalAlignment {
        switch position {
        case .topLeft, .bottomRight:
            return .top
        case .bottomLeft, .topRight:
            return .bottom
        }
    }
    
    public var body: some View {
        HStack(alignment: verticalAlignment, spacing: 0) {
            if useUpTail {
                upTail
            } else {
                downTail
            }
            
            if isRound {
                roundContent
            } else {
                skewContent
            }
        }
        .frame(height: RibbonConstants.ribbonHeight)
        .rotationEffect(rotation)
    }
    
    private var roundContent: some View {
        HStack(spacing: 0) {
            Text(label)
                .font(.system(size: scaleSize(12), weight: .medium))
                .foregroundColor(Colors.black01)
                .lineLimit(1)
                .rotationEffect(rotation)
        }
        .frame(height: RibbonConstants.roundHeight)
        .padding(.trailing, RibbonConstants.roundPaddingEnd)
        .background(
            RoundedCorners(
                topLeft: 0,
                topRight: RibbonConstants.roundRightRadius,
                bottomLeft: 0,
                bottomRight: RibbonConstants.roundRightRadius
            )
            .fill(backgroundColor)
        )
    }
    
    private var skewContent: some View {
        HStack(spacing: 0) {
            Text(label)
                .font(.system(size: scaleSize(12), weight: .medium))
                .foregroundColor(Colors.black01)
                .lineLimit(1)
                .rotationEffect(rotation)
                .frame(height: RibbonConstants.skewBodyHeight)
                .padding(.horizontal, 8)
                .background(backgroundColor)
            
            rightTail
        }
    }
    
    private var upTail: some View {
        ImageView(
            "https://static.momocdn.net/app/img/kits/utils/Head_down_4x.png",
            placeholder: AnyView(Color.clear)
        )
        .frame(width: RibbonConstants.headTailWidth, height: RibbonConstants.headTailHeight)
        .rotationEffect(.degrees(180))
        .offset(x: 1)
        .clipped()
    }
    
    private var downTail: some View {
        ImageView(
            "https://static.momocdn.net/app/img/kits/utils/Head_4x.png",
            placeholder: AnyView(Color.clear)
        )
        .frame(width: RibbonConstants.headTailWidth, height: RibbonConstants.headTailHeight)
        .offset(x: 1)
        .clipped()
    }
    
    private var rightTail: some View {
        ImageView(
            "https://static.momocdn.net/app/img/kits/utils/Tail_4x.png",
            placeholder: AnyView(Color.clear)
        )
        .frame(width: RibbonConstants.skewTailWidth, height: RibbonConstants.skewTailHeight)
        .offset(x: -2)
        .clipped()
    }
}

// MARK: - Constants
private struct RibbonConstants {
    static let ribbonHeight: CGFloat = 20
    static let roundHeight: CGFloat = 16
    static let skewBodyHeight: CGFloat = 16
    static let roundRightRadius: CGFloat = 8
    static let roundPaddingEnd: CGFloat = 6
    static let skewTailWidth: CGFloat = 8
    static let skewTailHeight: CGFloat = 16
    static let headTailWidth: CGFloat = 5
    static let headTailHeight: CGFloat = 20
}

// MARK: - String Extension for Text Size
extension String {
    func size(withAttributes attributes: [NSAttributedString.Key: Any]?) -> CGSize {
        let size = (self as NSString).size(withAttributes: attributes)
        return size
    }
}

// MARK: - Preview
#if DEBUG
struct BadgeRibbon_Previews: PreviewProvider {
    static var previews: some View {
        VStack(spacing: 30) {
            // Basic ribbon examples
            BadgeRibbon(position: .topRight, label: "New")
            BadgeRibbon(position: .topLeft, label: "Hot", isRound: true)
            BadgeRibbon(position: .bottomLeft, label: "Sale")
            BadgeRibbon(position: .bottomRight, label: "50% OFF", isRound: true)
        }
        .padding()
        .previewLayout(.sizeThatFits)
    }
}
#endif

