import SwiftUI
import SwiftData

// MARK: - ActiveRecordingView
/// The live recording screen showing real-time waveform, elapsed time,
/// and quick-action buttons for adding photos and notes during a session.
/// Fully redesigned to use a minimalist business-focused line-drawn UI.
struct ActiveRecordingView: View {
    @Environment(\.modelContext) private var modelContext
    @Environment(\.dismiss) private var dismiss

    let session: CelestiaSession
    var initialDuration: TimeInterval = 0
    let recordingSource: RecordingSourceChoice
    var onFinishRecording: (() -> Void)? = nil

    @State private var recordingVM: RecordingViewModel
    @State private var showNoteSheet = false
    @State private var showCamera = false
    @State private var noteText = ""
    @State private var latestEvent: CelestiaTimelineEvent?
    @State private var latestEventVisible = false
    @State private var isEndingRecording = false
    @State private var stopErrorMessage: String?

    init(
        session: CelestiaSession,
        initialDuration: TimeInterval = 0,
        recordingSource: RecordingSourceChoice = .iPhone,
        onFinishRecording: (() -> Void)? = nil
    ) {
        self.session = session
        self.initialDuration = initialDuration
        self.recordingSource = recordingSource
        self.onFinishRecording = onFinishRecording
        _recordingVM = State(initialValue: RecordingViewModel(source: recordingSource))
    }

    var body: some View {
        ZStack {
            // Dynamic clean background
            Color.spaceBlack
                .ignoresSafeArea()

            VStack(spacing: 0) {
                Spacer()
                    .frame(height: 20)

                // Top Header Block (Timecode + Indicator)
                VStack(spacing: 16) {
                    timecodeSection
                    recordingIndicator
                }
                .padding(.bottom, 24)

                // Live Waveform
                waveformSection
                    .padding(.horizontal, 24)
                    .padding(.bottom, 20)

                // Latest Event Card
                latestEventCard
                    .padding(.horizontal, 24)
                    .padding(.bottom, 20)

                Spacer()

                // Action Buttons
                actionButtons
                    .padding(.horizontal, 48)
                    .padding(.bottom, 32)

                // End Recording
                endRecordingButton
                    .padding(.bottom, 24)
            }
        }
        .toolbar(.hidden, for: .tabBar)
        .toolbar(.hidden, for: .navigationBar)
        .navigationBarHidden(true)
        .navigationBarBackButtonHidden(true)
        .sheet(isPresented: $showNoteSheet) {
            noteInputSheet
        }
        .fullScreenCover(isPresented: $showCamera) {
            ImagePicker(sourceType: UIImagePickerController.isSourceTypeAvailable(.camera) ? .camera : .photoLibrary) { image in
                saveImageAndAddEvent(image)
            }
        }
        .onAppear {
            UIApplication.shared.isIdleTimerDisabled = true
            recordingVM.startRecording(initialDuration: initialDuration)
        }
        .onDisappear {
            UIApplication.shared.isIdleTimerDisabled = false
            if recordingVM.isRecording {
                recordingVM.stopRecording()
            }
        }
        .alert("无法结束设备录音", isPresented: Binding(
            get: { stopErrorMessage != nil },
            set: { if !$0 { stopErrorMessage = nil } }
        )) {
            Button("重试") { endRecording() }
            Button("继续录音", role: .cancel) { stopErrorMessage = nil }
        } message: {
            Text(stopErrorMessage ?? "请确认微光仍在附近并保持连接。")
        }
    }

    // MARK: - Timecode

    private var timecodeSection: some View {
        Text(recordingVM.elapsedTimeFormatted)
            .font(.system(size: 52, weight: .light))
            .monospacedDigit()
            .foregroundStyle(Color.primary)
            .contentTransition(.numericText(countsDown: false))
            .frame(height: 64)
    }

    // MARK: - Recording Indicator

    private var recordingIndicator: some View {
        VStack(spacing: 8) {
            HStack(spacing: 8) {
                TimelineView(.periodic(from: .now, by: 1.0)) { context in
                    let isEven = Int(context.date.timeIntervalSince1970) % 2 == 0
                    Circle()
                        .fill(recordingVM.isRecording ? Color.recordingRed : Color.secondary)
                        .frame(width: 8, height: 8)
                        .opacity(recordingVM.isRecording ? (isEven ? 1.0 : 0.3) : 0.6)
                        .animation(.easeInOut(duration: 0.5), value: isEven)
                }
                .frame(width: 10, height: 10)

                Text(recordingVM.isPaused ? "已暂停" : recordingVM.statusMessage)
                    .font(.system(size: 11, weight: .semibold, design: .monospaced))
                    .foregroundStyle(recordingVM.isRecording ? Color.recordingRed : Color.secondary)
                    .tracking(1.2)

                Text("· \(session.title)")
                    .font(.system(size: 11, weight: .regular))
                    .foregroundStyle(Color.secondary.opacity(0.7))
                    .lineLimit(1)
            }

            HStack(spacing: 6) {
                Image(systemName: recordingSource.systemImage)
                    .font(.system(size: 11, weight: .medium))
                Text("当前录音设备：\(recordingVM.sourceDisplayName)")
                    .font(.system(size: 11, weight: .medium))
            }
            .foregroundStyle(Color.primary.opacity(0.85))

            if let error = recordingVM.errorMessage {
                Text(error)
                    .font(.system(size: 10))
                    .foregroundStyle(Color.recordingRed)
                    .multilineTextAlignment(.center)
                    .lineLimit(2)
            }
        }
        .padding(.horizontal, 10)
        .padding(.vertical, 8)
        .businessBorder(cornerRadius: 6)
    }

    // MARK: - Waveform

    private var waveformSection: some View {
        VStack(spacing: 0) {
            LiveWaveformView(samples: recordingVM.waveformSamples)
                .frame(height: 90)

            // Graphical VU Meter + Numeric Display
            HStack(spacing: 10) {
                Text("音量电平")
                    .font(.system(size: 9, weight: .semibold, design: .monospaced))
                    .foregroundStyle(Color.secondary.opacity(0.6))
                    .tracking(1.5)

                AmplitudeLevelMeterView(amplitude: recordingVM.currentAmplitude)

                Spacer(minLength: 0)

                Text(String(format: "%02.0f%%", recordingVM.currentAmplitude * 100))
                    .font(.system(size: 9, weight: .medium, design: .monospaced))
                    .foregroundStyle(recordingVM.currentAmplitude > 0.85 ? Color.recordingRed : Color.secondary)
            }
            .padding(.horizontal, 4)
            .padding(.top, 10)
        }
        .frame(height: 114)
    }

    // MARK: - Latest Event Card

    private var latestEventCard: some View {
        ZStack { // Fix: Use ZStack instead of Group to enforce the fixed frame even when empty
            if let event = latestEvent, latestEventVisible {
                HStack(spacing: 12) {
                    Image(systemName: event.eventIcon)
                        .font(.system(size: 12))
                        .foregroundStyle(Color.primary)
                        .frame(width: 28, height: 28)
                        .businessBorder(cornerRadius: 14)

                    VStack(alignment: .leading, spacing: 2) {
                        Text(eventLabel(for: event.eventType))
                            .font(.system(size: 11, weight: .semibold))
                            .foregroundStyle(Color.primary)

                        if let text = event.textContent {
                            Text(text)
                               .font(.system(size: 12))
                               .foregroundStyle(Color.secondary)
                               .lineLimit(1)
                        }
                    }

                    Spacer()

                    Text(event.relativeTimeFormatted)
                        .font(.system(size: 11, weight: .regular, design: .monospaced))
                        .foregroundStyle(Color.secondary)
                }
                .padding(12)
                .background(Color.cardBackground.opacity(0.4))
                .businessBorder(cornerRadius: 8)
                .transition(.asymmetric(
                    insertion: .move(edge: .bottom).combined(with: .opacity),
                    removal: .opacity
                ))
            }
        }
        .frame(height: 56)
        .animation(.spring(response: 0.35, dampingFraction: 0.8), value: latestEvent?.id)
    }

    // MARK: - Action Buttons

    private var actionButtons: some View {
        HStack(spacing: 40) {
            // Camera button
            actionButton(
                icon: "camera",
                label: "拍照打点"
            ) {
                capturePhoto()
            }

            // Note button
            actionButton(
                icon: "doc.text",
                label: "文字笔记"
            ) {
                showNoteSheet = true
            }
        }
    }

    private func actionButton(
        icon: String,
        label: String,
        action: @escaping () -> Void
    ) -> some View {
        Button(action: action) {
            VStack(spacing: 10) {
                ZStack {
                    Circle()
                        .fill(Color.primary.opacity(0.02))
                        .frame(width: 60, height: 60)
                        .businessBorder(cornerRadius: 30)

                    Image(systemName: icon)
                        .font(.system(size: 20, weight: .light))
                        .foregroundStyle(Color.primary)
                }

                Text(label)
                    .font(.system(size: 11, weight: .regular))
                    .foregroundStyle(Color.secondary)
            }
        }
        .buttonStyle(.plain)
    }

    // MARK: - End Recording Button

    private var endRecordingButton: some View {
        Button {
            endRecording()
        } label: {
            VStack(spacing: 6) {
                Text("双击结束录制")
                    .font(.system(size: 13, weight: .medium))
                    .foregroundStyle(Color.recordingRed)
                    .padding(.horizontal, 24)
                    .padding(.vertical, 10)
                    .businessBorder(cornerRadius: 8)
                
                Text("双击即可完成本次现场录音")
                    .font(.system(size: 8, weight: .medium, design: .monospaced))
                    .foregroundStyle(Color.secondary.opacity(0.5))
                    .tracking(1.5)
            }
        }
        .highPriorityGesture(
            TapGesture(count: 2).onEnded {
                endRecording()
            }
        )
        .buttonStyle(.plain)
        .disabled(isEndingRecording)
    }

    // MARK: - Note Input Sheet

    private var noteInputSheet: some View {
        NavigationStack {
            ZStack {
                Color.spaceBlack.ignoresSafeArea()

                VStack(spacing: 20) {
                    TextField("输入笔记内容...", text: $noteText, axis: .vertical)
                        .textFieldStyle(.plain)
                        .font(.system(size: 15))
                        .foregroundStyle(Color.primary)
                        .padding(14)
                        .frame(minHeight: 120, alignment: .top)
                        .background(Color.cardBackground.opacity(0.5))
                        .businessBorder(cornerRadius: 8)

                    Button {
                        addNote()
                    } label: {
                        Text("保存笔记")
                            .font(.system(size: 14, weight: .semibold))
                            .foregroundStyle(Color.spaceBlack)
                            .frame(maxWidth: .infinity)
                            .padding(.vertical, 12)
                            .background(Color.primary)
                            .cornerRadius(8)
                    }
                    .disabled(noteText.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty)

                    Spacer()
                }
                .padding(24)
            }
            .navigationTitle("添加笔记")
            .navigationBarTitleDisplayMode(.inline)
            .toolbar {
                ToolbarItem(placement: .cancellationAction) {
                    Button("取消") {
                        showNoteSheet = false
                        noteText = ""
                    }
                    .foregroundStyle(Color.secondary)
                }
            }
        }
        .presentationDetents([.medium])
        .presentationDragIndicator(.visible)
        .presentationBackground(Color.spaceBlack)
    }

    // MARK: - Actions

    private func capturePhoto() {
        showCamera = true
    }

    private func saveImageAndAddEvent(_ image: UIImage) {
        guard let data = image.jpegData(compressionQuality: 0.8) else { return }
        let filename = "photo_\(UUID().uuidString).jpg"
        let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
        let fileURL = documentsURL.appendingPathComponent(filename)
        do {
            try data.write(to: fileURL)
            let event = recordingVM.addPhotoEvent(to: session, localFilePath: filename)
            HapticManager.trigger(.photoCapture)
            showLatestEvent(event)
        } catch {
            print("[ActiveRecordingView] Failed to save captured photo: \(error.localizedDescription)")
        }
    }

    private func addNote() {
        let text = noteText.trimmingCharacters(in: .whitespacesAndNewlines)
        guard !text.isEmpty else { return }

        let event = recordingVM.addNoteEvent(to: session, text: text)

        HapticManager.trigger(.noteAdded)
        showLatestEvent(event)

        noteText = ""
        showNoteSheet = false
    }

    private func endRecording() {
        guard !isEndingRecording else { return }
        isEndingRecording = true

        recordingVM.stopRecording { result in
            switch result {
            case .success(let confirmedURL):
                finalizeRecording(newRecordedURL: confirmedURL ?? recordingVM.outputFileURL)
            case .failure(let error):
                isEndingRecording = false
                stopErrorMessage = error.localizedDescription
            }
        }
    }

    private func finalizeRecording(newRecordedURL: URL?) {
        let existingPath = session.localAudioPath
        let existingURL = AudioPathHelper.resolveURL(for: existingPath)
        let totalRecordedSeconds = recordingVM.elapsedTime
        
        if let newRecordedURL = newRecordedURL {
            Task { @MainActor in
                let mergedURL = await AudioMerger.mergeAudioFiles(firstURL: existingURL, secondURL: newRecordedURL)
                session.localAudioPath = AudioPathHelper.relativePath(from: mergedURL.path)
                session.endTime = session.startTime.addingTimeInterval(totalRecordedSeconds)
                try? modelContext.save()
                
                HapticManager.trigger(.recordStop)
                isEndingRecording = false
                dismiss()
                onFinishRecording?()
            }
        } else {
            if existingURL != nil {
                session.endTime = session.startTime.addingTimeInterval(totalRecordedSeconds)
                try? modelContext.save()
            } else {
                session.endTime = Date()
                try? modelContext.save()
            }
            HapticManager.trigger(.recordStop)
            isEndingRecording = false
            dismiss()
            onFinishRecording?()
        }
    }

    private func showLatestEvent(_ event: CelestiaTimelineEvent) {
        withAnimation {
            latestEvent = event
            latestEventVisible = true
        }
        // Auto-dismiss after a few seconds
        DispatchQueue.main.asyncAfter(deadline: .now() + 4) {
            withAnimation {
                latestEventVisible = false
            }
        }
    }

    // MARK: - Helpers

    private func eventLabel(for type: String) -> String {
        switch type {
        case "PHOTO": return "已捕获照片"
        case "NOTE": return "已保存笔记"
        case "MARKER": return "标记点"
        case "VOICE": return "音轨事件"
        default: return "事件"
        }
    }
}

// MARK: - Amplitude Level Meter View

/// A minimalist graphical VU meter bar visualizing real-time audio amplitude.
private struct AmplitudeLevelMeterView: View {
    let amplitude: Float // 0.0 to 1.0

    private let totalSegments: Int = 16

    var body: some View {
        HStack(spacing: 3) {
            ForEach(0..<totalSegments, id: \.self) { index in
                let threshold = Float(index) / Float(totalSegments)
                let isFilled = amplitude > threshold
                let isPeak = index >= totalSegments - 2

                RoundedRectangle(cornerRadius: 1)
                    .fill(
                        isFilled
                            ? (isPeak ? Color.recordingRed : Color.primary.opacity(0.85))
                            : Color.primary.opacity(0.12)
                    )
                    .frame(height: isFilled ? (isPeak ? 7 : 5) : 3)
                    .animation(.spring(response: 0.15, dampingFraction: 0.75), value: amplitude)
            }
        }
    }
}

// MARK: - Preview

#Preview {
    let session = CelestiaSession(title: "Preview Session")
    ActiveRecordingView(session: session)
        .modelContainer(for: CelestiaSession.self, inMemory: true)
}
