import AudioRecorderClient
import AVFoundation
import ComponentLibrary
import ComposableArchitecture
import Localization
import SwiftUI
import APIClient

public struct ChatAudioRecorderView: View {
    @Bindable var store: StoreOf<ChatAudioRecorder>

    private static let dateComponentsFormatter: DateComponentsFormatter = {
        let formatter = DateComponentsFormatter()
        formatter.allowedUnits = [.minute, .second]
        formatter.zeroFormattingBehavior = .pad
        formatter.unitsStyle = .positional
        return formatter
    }()

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

    public var body: some View {
        Group {
            if store.isTrimming {
                ChatAudioTrimmerView(store: store)
                    .transition(.opacity)
            } else {
                recordingView
                    .transition(.opacity)
            }
        }
        .animation(.easeInOut(duration: 0.3), value: store.isTrimming)
        .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top)
        .background(
            ChatConstants.Colors.Background.secondary
                .ignoresSafeArea(edges: .bottom)
        )
        .presentationDetents([.fraction(0.7)])
        .presentationDragIndicator(.visible)
        .presentationBackground {
            ChatConstants.Colors.Background.secondary
                .ignoresSafeArea(edges: .bottom)
        }
    }

    private var recordingView: some View {
        VStack(spacing: 0) {
            // Timer
            VStack(spacing: 4) {
                Text(timeString(from: store.duration))
                    .typographyV1(
                        TypographyV1.headline5
                            .lineHeight(24)
                            .kerning(0.32)
                    )
                    .foregroundColor(ChatConstants.Colors.Foreground.primary)
            }
            .frame(maxWidth: .infinity)
            .padding(.horizontal, 24)
            .padding(.top, 56)

            Spacer()

            RecordingWaveformView(
                samples: store.samples,
                isRecording: store.isRecording,
                currentDuration: store.duration,
                maxRecordTime: store.maxRecordTime
            )
            .frame(maxWidth: .infinity)
            .frame(maxHeight: .infinity)

            Spacer()

            VStack(spacing: 0) {
                if store.showProgressView {
                    ZStack {
                        Circle()
                            .fill(ChatConstants.Colors.Background.Fog.thin)
                            .frame(width: 100, height: 100)
                        ProgressView()
                            .progressViewStyle(CircularProgressViewStyle(tint: ChatConstants.Colors.Foreground.primary))
                            .scaleEffect(1.5)
                    }
                } else {
                    Button {
                        if store.hasStartedRecording {
                            store.send(.stopButtonTapped)
                        } else {
                            store.send(.startRecordingTapped)
                        }
                    } label: {
                        ZStack {
                            if store.hasStartedRecording {
                                Circle()
                                    .fill(ChatConstants.Colors.Background.Fog.thin)
                                    .frame(width: 100, height: 100)

                                RoundedRectangle(cornerRadius: 8)
                                    .fill(ChatConstants.Colors.Accent.error)
                                    .frame(width: 32, height: 32)
                            } else {
                                Circle()
                                    .fill(ChatConstants.Colors.Accent.error)
                                    .frame(width: 100, height: 100)
                            }
                        }
                    }
                    .buttonStyle(PlainButtonStyle())
                }

                VStack(spacing: 0) {
                    AudioLengthCaptionView()
                        .padding(.horizontal, 24)
                        .padding(.vertical, 24)
                        .frame(height: 60)
                }
            }
        }
    }

    private func timeString(from timeInterval: TimeInterval) -> String {
        Self.dateComponentsFormatter.string(from: timeInterval) ?? "00:00"
    }
}
