import AVFoundation
import ComponentLibrary
import ComposableArchitecture
import Localization
import SwiftUI

@Reducer
public struct BluejayAnnouncement {
    public init() {}

    @ObservableState
    public struct State: Equatable {
        public enum Style {
            case free
            case pro
        }

        var style: Style
        var ctaButtonText: String {
            switch style {
            case .free:
                return L10n.FeatureAnnouncements.bluejayAnnouncementUpgradeNow

            case .pro:
                return L10n.FeatureAnnouncements.bluejayAnnouncementCreateWith
            }
        }

        public init(style: Style) {
            self.style = style
        }
    }

    public enum Action {
        case dismiss
        case ctaButtonTapped
        case delegate(Delegate)

        public enum Delegate {
            case openCreate
            case openSubscriptions
        }
    }

    @Dependency(\.dismiss) var dismiss

    public var body: some ReducerOf<Self> {
        Reduce { state, action in
            switch action {
            case .dismiss:
                return .run { _ in await self.dismiss() }

            case .ctaButtonTapped:
                switch state.style {
                case .free:
                    return .send(.delegate(.openSubscriptions))

                case .pro:
                    return .send(.delegate(.openCreate))
                }

            case .delegate:
                return .none
            }
        }
    }
}

public struct BluejayAnnouncementView: View {
    @Bindable private var store: StoreOf<BluejayAnnouncement>

    public init(store: StoreOf<BluejayAnnouncement>) {
        self.store = store
    }

    @Environment(\.openURL) var openURL

    public var body: some View {
        ZStack {
            /// Dark background overlay
            Color.black.opacity(0.8)
                .frame(maxWidth: .infinity, maxHeight: .infinity)

            /// Announcement banner
            VStack(spacing: 18) {
                topBar

                graphic

                textStack

                buttonStack
            }
            .padding(.top, 18)
            .padding([.horizontal, .bottom], 22)
            .background(
                Image(.bluejayAnnouncementBackground)
                    .resizable()
                    .scaledToFill()
            )
            .clipShape(RoundedRectangle(cornerRadius: 32))
            .shadow(color: .black.opacity(0.25), radius: 4, x: 0, y: 4)
            .padding(.horizontal, 40)
        }
        .ignoresSafeArea()
    }

    private var topBar: some View {
        HStack {
            BadgeLabel(L10n.FeatureCreateClip.newModelTooltipBadge)

            Spacer()

            ToolbarButton(.close, color: Color.SemanticV2.foregroundPrimary) {
                store.send(.dismiss)
            }
            .frame(width: 40, height: 40)
            .foregroundStyle(Color.SemanticV2.foregroundPrimary)
            .background(Color.SemanticV2.backgroundPrimary)
            .clipShape(.circle)
            .colorScheme(.light)
        }
    }

    private var graphic: some View {
        Image(.bluejayAnnouncementGraphic)
            .resizable()
            .aspectRatio(contentMode: .fit)
            .clipShape(RoundedRectangle(cornerRadius: 16))
    }

    private var textStack: some View {
        VStack(alignment: .leading, spacing: 8) {
            Text(L10n.FeatureAnnouncements.bluejayAnnouncementTitle)
                .typographyV1(.title)

            Text(L10n.FeatureAnnouncements.bluejayAnnouncementDetail)
                .typographyV1(.detail)
        }
        .colorScheme(.dark)
        .multilineTextAlignment(.leading)
        .foregroundStyle(Color.SemanticV2.foregroundPrimary)
    }

    private var buttonStack: some View {
        HStack(spacing: 10) {
            Button(store.ctaButtonText) {
                store.send(.ctaButtonTapped)
            }
            .buttonStyle(CapsuleButtonStyle())

            Spacer()
        }
        .colorScheme(.light)
    }
}

private extension TypographyV1 {
    /// size: 27pt, lineHeight: 48pt, weight: light
    static let title: TypographyV1 = .init(
        name: "Announcement Title",
        size: 27,
        style: .title,
        weight: .editorialNewLight,
        lineHeight: 31
    )

    /// size: 14pt, lineHeight: 19pt, weight: medium
    static let detail: TypographyV1 = .init(
        name: "Announcement Detail",
        size: 14,
        style: .body,
        weight: .ppNeueMontrealMedium,
        lineHeight: 17
    )
}

struct CapsuleButtonStyle: ButtonStyle {
    func makeBody(configuration: Configuration) -> some View {
        configuration.label
            .typographyV1(.button)
            .foregroundStyle(.foreground)
            .padding(.vertical, 12)
            .padding(.horizontal, 12)
            .background(
                .background.opacity(configuration.isPressed ? 0.5 : 1.0)
            )
            .clipShape(.capsule)
    }
}
