import APIClient
import ComponentLibrary
import GenAPI
import SwiftUI

public struct PromoCard: View {
    public var item: PromoItem
    public var onPrimaryCtaTap: () -> Void
    public var onSecondaryCtaTap: () -> Void
    @State private var cardWidth: CGFloat = 0

    private var cardHeight: CGFloat {
        CGFloat(item.cardHeight ?? 250)
    }

    private var badgeTextColor: Color {
        if let textColor = item.badge?.textColor,
           let color = UInt(textColor, radix: 16)
        {
            return Color(hex: color)
        }
        return Color.SemanticV2.foregroundPrimaryOnLight
    }

    private var badgeBackgroundColor: Color {
        if let backgroundColor = item.badge?.backgroundColor,
           let color = UInt(backgroundColor, radix: 16)
        {
            return Color(hex: color)
        }
        return Color.SemanticV2.backgroundLightOverlay
    }

    private var primaryCtaTextColor: Color {
        if let textColor = item.primaryCta?.textColor,
           let color = UInt(textColor, radix: 16)
        {
            return Color(hex: color)
        }
        return Color.SemanticV2.foregroundPrimaryOnLight
    }

    private var primaryCtaBackgroundColor: Color {
        if let backgroundColor = item.primaryCta?.backgroundColor,
           let color = UInt(backgroundColor, radix: 16)
        {
            return Color(hex: color)
        }
        return Color.SemanticV2.backgroundLightOverlay
    }

    private var secondaryCtaTextColor: Color {
        if let textColor = item.secondaryCta?.textColor,
           let color = UInt(textColor, radix: 16)
        {
            return Color(hex: color)
        }
        return Color.SemanticV2.foregroundPrimaryOnDark
    }

    private var secondaryCtaBackgroundColor: Color {
        if let backgroundColor = item.secondaryCta?.backgroundColor,
           let color = UInt(backgroundColor, radix: 16)
        {
            return Color(hex: color)
        }
        return Color.SemanticV2.backgroundGlassThin
    }

    private var primaryHeadlineTextColor: Color {
        if let textColor = item.primaryHeadline?.color,
           let color = UInt(textColor, radix: 16)
        {
            return Color(hex: color)
        }
        return Color.SemanticV2.foregroundPrimary
    }

    private var secondaryHeadlineTextColor: Color {
        if let textColor = item.secondaryHeadline?.color,
           let color = UInt(textColor, radix: 16)
        {
            return Color(hex: color)
        }
        return Color.SemanticV2.foregroundPrimary
    }

    private var primaryHeadlineText: String? {
        item.primaryHeadline?.text
    }

    private var secondaryHeadlineText: String? {
        item.secondaryHeadline?.text
    }

    private var primaryCtaLabel: String? {
        item.primaryCta?.label
    }

    private var secondaryCtaLabel: String? {
        item.secondaryCta?.label
    }

    private var primaryCtaAction: String? {
        item.primaryCta?.action
    }

    private var secondaryCtaAction: String? {
        item.secondaryCta?.action
    }

    private var primaryCtaUrl: String? {
        item.primaryCta?.url
    }

    private var secondaryCtaUrl: String? {
        item.secondaryCta?.url
    }

    private var badgeLabel: String? {
        item.badge?.label
    }

    public var body: some View {
        VStack(alignment: .leading, spacing: 0) {
            badge
            Spacer()
            headline(cardWidth: cardWidth)
                .padding(.bottom, 14)
            HStack {
                primaryCtaButton(
                    label: primaryCtaLabel,
                    action: primaryCtaAction,
                    urlString: primaryCtaUrl,
                    textColor: primaryCtaTextColor,
                    backgroundColor: primaryCtaBackgroundColor,
                    onTap: onPrimaryCtaTap
                )
                secondaryCtaButton(
                    label: secondaryCtaLabel,
                    action: secondaryCtaAction,
                    urlString: secondaryCtaUrl,
                    textColor: secondaryCtaTextColor,
                    backgroundColor: secondaryCtaBackgroundColor,
                    onTap: onSecondaryCtaTap
                )
                Spacer()
            }
        }
        .padding(16)
        .background {
            backgroundImage
                .clipShape(RoundedRectangle(cornerRadius: 16))
                .overlay(
                    RoundedRectangle(cornerRadius: 16)
                        .stroke(Color.SemanticV2.borderPrimary, lineWidth: 1, antialiased: true)
                )
        }
        .contentShape(RoundedRectangle(cornerRadius: 16))
        .onTapGesture {
            onPrimaryCtaTap()
        }
        .onGeometryChange(for: CGSize.self) { proxy in proxy.size } action: { size in
            cardWidth = size.width
        }
        .frame(height: cardHeight)
        .padding(.bottom, 14)
    }

    @ViewBuilder
    private func headline(cardWidth: CGFloat) -> some View {
        VStack(alignment: .leading, spacing: 6) {
            if let text = primaryHeadlineText {
                Text(text)
                    .typographyV1(.body3Bold.size { _ in 20.0 })
                    .foregroundColor(primaryHeadlineTextColor)
                    .multilineTextAlignment(.leading)
                    .lineLimit(2)
                    .minimumScaleFactor(0.7)
            }
            if let text = secondaryHeadlineText {
                Text(text)
                    .typographyV1(.body2thin.size { _ in 16.0 }.lineHeight(20.0))
                    .foregroundColor(secondaryHeadlineTextColor)
                    .multilineTextAlignment(.leading)
                    .lineLimit(3)
                    .minimumScaleFactor(0.7)
            }
        }
        .frame(maxWidth: cardWidth * 2 / 3) // Textbox width is 2/3 of the card width
        .environment(\.colorScheme, .dark)
    }

    @ViewBuilder
    private var backgroundImage: some View {
        if let backgroundImageUrl = item.backgroundImageUrl {
            RemoteImage(url: backgroundImageUrl, fallbackId: nil)
                .aspectRatio(contentMode: .fit)
                .frame(maxWidth: .infinity, maxHeight: cardHeight)
                .clipped()
        } else {
            EmptyView()
        }
    }

    @ViewBuilder
    private var badge: some View {
        if let label = badgeLabel {
            Text(label)
                .typographyV1(.subtitleSmall)
                .foregroundColor(badgeTextColor)
                .padding(.vertical, 3)
                .padding(.horizontal, 6)
                .background(Capsule().fill(badgeBackgroundColor))
                .padding(.bottom, 1) // Visual offset from designs
        }
    }

    @ViewBuilder
    private func primaryCtaButton(
        label: String?,
        action: String?,
        urlString _: String?,
        textColor: Color,
        backgroundColor: Color,
        onTap: @escaping () -> Void
    ) -> some View {
        if let label,
           let action,
           let urlString = primaryCtaUrl,
           let _ = URL(string: urlString) // Check if the URL is valid
        {
            ctaButton(
                label: label,
                action: action,
                icon: CtaAction(rawValue: action).icon,
                foregroundColor: textColor,
                backgroundColor: backgroundColor,
                borderColor: Color.SemanticV2.borderPrimary, onTap: onTap
            )
        }
    }

    @ViewBuilder
    private func secondaryCtaButton(
        label: String?,
        action: String?,
        urlString _: String?,
        textColor: Color,
        backgroundColor: Color,
        onTap: @escaping () -> Void
    ) -> some View {
        if let label,
           let action,
           let urlString = secondaryCtaUrl,
           let _ = URL(string: urlString) // Check if the URL is valid
        {
            ctaButton(
                label: label,
                action: action,
                icon: CtaAction(rawValue: action).icon,
                foregroundColor: textColor,
                backgroundColor: backgroundColor,
                borderColor: Color.SemanticV2.borderPrimary, onTap: onTap
            )
        }
    }

    @ViewBuilder
    private func ctaButton(
        label: String,
        action _: String,
        icon: some View,
        foregroundColor: Color,
        backgroundColor: Color,
        borderColor: Color,
        onTap: @escaping () -> Void
    ) -> some View {
        Button {
            onTap()
        } label: {
            HStack(spacing: 4) {
                icon
                    .frame(width: 16, height: 16)
                    .foregroundColor(foregroundColor)
                Text(label)
                    .typographyV1(.button)
                    .foregroundColor(foregroundColor)
            }
            .padding(.horizontal, 12)
            .padding(.vertical, 8)
            .background {
                Capsule()
                    .fill(backgroundColor)
                    .strokeBorder(borderColor, lineWidth: 1, antialiased: true)
            }
        }
        .buttonStyle(ScaleButtonStyle(scaleAmount: 0.95))
    }

    private enum CtaAction: String {
        case play
        case remix
        case cover
        case extend
        case externalLink = "external_link"
        case `default`

        public init(rawValue: String) {
            switch rawValue {
            case "play": self = .play
            case "remix": self = .remix
            case "cover": self = .cover
            case "extend": self = .extend
            case "external_link": self = .externalLink
            default: self = .default
            }
        }

        @ViewBuilder
        public var icon: some View {
            switch self {
            case .play:
                Image.Icon.playFilled
            case .remix:
                Image.Icon.remix
            case .cover:
                Image.Icon.cover
            case .extend:
                Image.Icon.extend
            case .externalLink:
                Image.Icon.linkExternal
            case .default:
                EmptyView()
            }
        }
    }
}
