import APIClient
import ComponentLibrary
import Foundation
import Localization
import SwiftUI

struct AudioUploadDetailView: View {
    var audioRecording: AudioRecording
    var uploadState: AudioUploadState
    var imageUrl: String?
    var isPlaying: Bool
    var isPlayButtonDisabled: Bool
    var elapsedTime: TimeInterval
    var totalTime: TimeInterval
    var elapsed: String
    var playPause: () -> Void
    var delete: () -> Void

    // Create Style actions
    var selectedStyle: BlendedCreatePrompt.AudioCreateStyle
    var didTapCreateStyle: () -> Void

    // Animations
    @Namespace private var namespace
    private struct TransitionId: Hashable {}

    private var progressView: some View {
        let progress = min(totalTime, max(0, elapsedTime))
        return ProgressView(value: progress, total: totalTime)
            .progressViewStyle(LinearProgressViewStyle())
            .background(Capsule().fill(.ultraThinMaterial))
            .tint(Color.SemanticV2.accentBrand)
            .contentShape(.rect)
    }

    var body: some View {
        ZStack {
            switch uploadState {
            case .uploading(let progress):
                uploadingProgressView(progress)
                    .matchedGeometryEffect(id: TransitionId(), in: namespace)

            case .checkingStatus:
                checkingStatusView(uploadState.title)
                    .matchedGeometryEffect(id: TransitionId(), in: namespace)

            case .completed:
                uploadedView(title: uploadState.isComplete ? audioRecording.title : uploadState.title)
                    .matchedGeometryEffect(id: TransitionId(), in: namespace)

            case .error(let errorMessage):
                errorView(errorMessage)
                    .matchedGeometryEffect(id: TransitionId(), in: namespace)
            }
        }
        .background { Color.SemanticV2.backgroundSecondary }
        .clipShape(RoundedRectangle(cornerRadius: 20))
        .animation(.spring, value: imageUrl)
    }

    @ViewBuilder
    private func uploadingProgressView(_ progress: Double) -> some View {
        VStack(spacing: 0) {
            HStack {
                Text(L10n.FeatureCreateClip.uploadUploadingClip)
                    .typographyV1(.subtitleMedium)
                    .foregroundStyle(Color.SemanticV2.foregroundPrimary)

                Spacer()

                Button {
                    UINotificationFeedbackGenerator().notificationOccurred(.warning)
                    delete()
                } label: {
                    Image.Icon.trashV2
                        .resizable()
                        .frame(width: 18, height: 18)
                        .foregroundStyle(Color.SemanticV2.foregroundPrimary)
                }
            }

            Color.clear
                .frame(height: 20)

            HStack(spacing: 12) {
                ProgressView(value: progress, total: 1)
                    .progressViewStyle(LinearProgressViewStyle())
                    .background(Capsule().fill(.ultraThinMaterial))
                    .tint(Color.SemanticV2.accentBrand)
                    .contentShape(.rect)

                Text(progress.formatted(.percent))
                    .typographyV1(.bodySmallNew)
                    .foregroundStyle(Color.SemanticV2.foregroundSecondary)
            }
        }
        .padding([.top, .horizontal], 20)
        .padding(.bottom, 10)
    }

    @ViewBuilder
    private func checkingStatusView(_ status: String) -> some View {
        HStack {
            ProgressView()
                .progressViewStyle(CircularProgressViewStyle(tint: Color.SemanticV2.accentBrand))
                .frame(width: 18, height: 18)

            Text(status)
                .typographyV1(.subtitleMedium)
                .foregroundStyle(Color.SemanticV2.foregroundPrimary)

            Spacer()

            Button {
                UINotificationFeedbackGenerator().notificationOccurred(.warning)
                delete()
            } label: {
                Image.Icon.trashV2
                    .resizable()
                    .frame(width: 18, height: 18)
                    .foregroundStyle(Color.SemanticV2.foregroundPrimary)
            }
            .frame(alignment: .topTrailing)
        }
        .padding(20)
    }

    @ViewBuilder
    private func errorView(_ errorMessage: String) -> some View {
        VStack(spacing: 0) {
            HStack {
                Image.Icon.warning
                    .resizable()
                    .frame(width: 18, height: 18)
                    .foregroundStyle(Color.SemanticV2.accentError)
                    .frame(alignment: .topLeading)

                VStack(alignment: .leading, spacing: 4) {
                    Text(L10n.FeatureCreateClip.errorTitle)
                        .typographyV1(.subtitleMedium)
                        .foregroundStyle(Color.SemanticV2.foregroundPrimary)

                    Text(errorMessage)
                        .typographyV1(.bodySmallNew)
                        .foregroundStyle(Color.SemanticV2.foregroundSecondary)
                }

                Spacer()

                Button {
                    UINotificationFeedbackGenerator().notificationOccurred(.warning)
                    delete()
                } label: {
                    Image.Icon.trashV2
                        .resizable()
                        .frame(width: 18, height: 18)
                        .foregroundStyle(Color.SemanticV2.foregroundPrimary)
                }
                .frame(alignment: .topTrailing)
            }
        }
        .padding([.top, .horizontal], 20)
        .padding(.bottom, 10)
    }

    @ViewBuilder
    private func uploadedView(title: String) -> some View {
        VStack(spacing: 0) {
            HStack {
                if let imageUrl {
                    RemoteImage(url: imageUrl, fallbackId: "1")
                        .frame(width: 40, height: 60)
                        .clipShape(RoundedRectangle(cornerRadius: 10))
                } else {
                    RoundedRectangle(cornerRadius: 10)
                        .fill(Color.SemanticV2.backgroundTertiary)
                        .frame(width: 40, height: 60)
                }

                VStack(alignment: .leading, spacing: 4) {
                    Text(title)
                        .typographyV1(.subtitleMedium)
                        .foregroundStyle(Color.SemanticV2.foregroundPrimary)

                    Text(elapsed)
                        .typographyV1(.bodySmallNew)
                        .foregroundStyle(Color.SemanticV2.foregroundSecondary)
                }

                Spacer()

                HStack(spacing: 20) {
                    Button {
                        UIImpactFeedbackGenerator(style: .light).impactOccurred()
                        playPause()
                    } label: {
                        ZStack {
                            (isPlaying ? Image.Icon.pause : Image.Icon.playFilled)
                                .resizable()
                                .frame(width: 16, height: 16) // Legacy play button is too big
                                .foregroundStyle(Color.SemanticV2.foregroundPrimary)
                        }
                    }
                    .disabled(isPlayButtonDisabled)

                    Button {
                        UINotificationFeedbackGenerator().notificationOccurred(.warning)
                        delete()
                    } label: {
                        Image.Icon.trashV2
                            .resizable()
                            .frame(width: 18, height: 18)
                            .foregroundStyle(Color.SemanticV2.foregroundPrimary)
                    }
                }
                .padding(10)
            }
            .padding(10)

            // Divider Line
            Color.SemanticV2.borderSecondary
                .frame(height: 0.5)
                .frame(maxWidth: .infinity)

            createStyleButton
        }
    }

    var selectedStyleText: String {
        switch selectedStyle {
        case .cover:
            L10n.FeatureCreateClip.coverClip

        case .extend:
            L10n.FeatureCreateClip.extendClip
        }
    }

    var selectedStyleImage: Image {
        switch selectedStyle {
        case .cover:
            Image.Icon.cover

        case .extend:
            Image.Icon.extend
        }
    }

    @ViewBuilder
    private var createStyleButton: some View {
        Button {
            didTapCreateStyle()
        } label: {
            HStack(spacing: 0) {
                selectedStyleImage
                    .foregroundStyle(Color.SemanticV1.iconPrimary)
                    .padding(.trailing, 20)

                VStack(spacing: 0) {
                    Text(selectedStyleText)
                        .foregroundStyle(Color.SemanticV1.iconPrimary)
                        .typographyV1(.subtitleMedium)
                        .frame(maxWidth: .infinity, alignment: .leading)

                    Text(selectedStyle.description)
                        .foregroundStyle(Color.SemanticV1.iconPrimary)
                        .typographyV1(.bodyMedium)
                        .frame(maxWidth: .infinity, alignment: .leading)
                }
            }
            .padding(.horizontal, 25)
            .padding(.vertical, 10)
        }
    }
}
