import Adamantium
import ComponentLibrary
import ComposableArchitecture
import Foundation
import SwiftUI

@Reducer
public struct BrandedAlertAnnounce {
    @ObservableState
    public struct State: Equatable {
        var style: AnnounceAlertStyle
        var areSlidingElementsShown: Bool = false
        var isShowingLoadingOverlay: Bool = false

        init(style: AnnounceAlertStyle = .preset(.empty)) {
            self.style = style
        }
    }

    public enum Action: BindableAction {
        case delegate(Delegate)
        case binding(BindingAction<State>)
        case activateSlidingElements
        case deactivateSlidingElements
        case showLoadingOverlay
        case hideLoadingOverlay

        public enum Delegate {
            case exitButton
            case exitToCreate
        }
    }

    public init() {}

    public var body: some ReducerOf<Self> {
        BindingReducer()
        Reduce<State, Action> { state, action in
            switch action {
            case .activateSlidingElements:
                state.areSlidingElementsShown = true
                return .none

            case .deactivateSlidingElements:
                state.areSlidingElementsShown = false
                return .none

            case .showLoadingOverlay:
                state.isShowingLoadingOverlay = true
                return .none

            case .hideLoadingOverlay:
                state.isShowingLoadingOverlay = false
                return .none

            case .binding,
                 .delegate:
                // Catch-all
                return .none
            }
        }
    }
}

public struct BrandedAlertAnnounceView: View {
    @Bindable var store: StoreOf<BrandedAlertAnnounce>

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

    public var body: some View {
        ZStack {
            bannerView
            captionBar
            exitButtonStack
            if store.isShowingLoadingOverlay {
                ZStack {
                    Color.SemanticV1.backgroundBlockOverlay.opacity(0.25)
                    ProgressView()
                        .progressViewStyle(.circular)
                }
            }
        }
        .frame(width: 313.0, height: 546.0)
        .clipShape(.rect(cornerRadius: 24.0))
        .onAppear {
            store.send(.activateSlidingElements)
        }
        .onDisappear {
            store.send(.deactivateSlidingElements)
        }
        .onTapGesture {
            switch tapAction {
            case .exit:
                store.send(.delegate(.exitButton))
            case .exitToCreate:
                store.send(.showLoadingOverlay)
                store.send(.delegate(.exitToCreate))
            }
        }
    }
}

private extension BrandedAlertAnnounceView {
    enum Constants {
        static let exitCircleSize: CGFloat = 40.0
        static let exitButtonPadding: CGFloat = 12.0
    }

    var copyData: AnnounceAlertStyle.TextCopy {
        return store.style.textCopy
    }

    var tapAction: AnnounceAlertStyle.TapAction {
        store.style.tapAction
    }

    @ViewBuilder
    var bannerView: some View {
        ZStack {
            Color.clear
            AnnounceAnimatedCardStack(store: store, imageNames: copyData.imageNames)
                .opacity(store.areSlidingElementsShown ? 1.0 : 0.0)
                .animation(.easeOut.delay(0.1), value: store.areSlidingElementsShown)
            AnnounceBannerStack(
                label: copyData.titleTagLabel,
                title: copyData.title,
                description: copyData.description
            )
            .padding(.top, 32.0)
        }
        .background {
            AuraShaderView(id: "branded_alert_aura", colorSet: .maroonVioletRed, seed: 710.0)
        }
    }

    @ViewBuilder
    var captionBar: some View {
        VStack {
            Spacer()
            HStack {
                Text(copyData.barCaption)
                    .typographyV1(.body1Wide)
                    .foregroundStyle(Color.SemanticV1.textOnLight)

                if let barTagLabel = copyData.barTagLabel, !barTagLabel.isEmpty {
                    Spacer()
                    InlineTextBadgeView(
                        label: barTagLabel,
                        textColor: Color.SemanticV1.iconOnDark,
                        accentColor: .SemanticV1.backgroundBlockOverlay.opacity(0.75)
                    )
                }
            }
            .padding(.horizontal, 16.0)
            .frame(maxWidth: .infinity)
            .frame(height: 56.0)
            .background {
                ZStack {
                    VisualEffectView(style: .light)
                    Color.SemanticV1.iconOnDark.opacity(0.75)
                }
            }
        }
    }

    @ViewBuilder
    var exitButtonStack: some View {
        VStack {
            HStack {
                Spacer()
                Button {
                    store.send(.delegate(.exitButton))
                } label: {
                    ZStack {
                        Circle()
                            .fill(Color.SemanticV1.backgroundBlockOverlay.opacity(0.25))
                            .frame(width: Constants.exitCircleSize, height: Constants.exitCircleSize)
                        Image.Icon.close
                            .foregroundStyle(Color.SemanticV1.iconOnDark)
                    }
                    .padding(.top, Constants.exitButtonPadding)
                    .padding(.trailing, Constants.exitButtonPadding)
                }
            }
            Spacer()
        }
    }
}
