import SwiftUI
import SwiftData

// MARK: - HomeView
/// The main launch screen of CelestiaTrace.
/// Features a minimalist, line-drawn aesthetic with a central record button
/// and a subtle technical grid background.
struct HomeView: View {
    @Environment(\.modelContext) private var modelContext
    @ObservedObject private var bleManager: BLEManager = .shared
    @ObservedObject private var authManager: AuthManager = .shared

    @State private var activeRecording: ActiveRecordingPresentation?
    @State private var completedRecordingSession: CelestiaSession?
    @State private var selectedSessionForDetail: CelestiaSession?
    @State private var detector = RecordingEnvironmentDetector()
    @State private var dismissedWarnings: Set<String> = []
    @State private var showRecordingSourcePicker = false
    @State private var pendingRecordingSource: RecordingSourceChoice?

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

                // Subtle technical grid background
                businessGrid

                // Main content
                VStack(spacing: 0) {
                    topBar
                        .padding(.top, 16)

                    if let firstWarning = detector.activeWarnings.first(where: { !dismissedWarnings.contains($0) }) {
                        DiscreetWarningBanner(warning: firstWarning) {
                            withAnimation {
                                _ = dismissedWarnings.insert(firstWarning)
                            }
                        }
                        .padding(.top, 12)
                    }

                    Spacer()

                    recordSection

                    Spacer()
                }
                .padding(.horizontal, 24)
            }
            .navigationBarHidden(true)
            .onAppear {
                detector.checkEnvironment()
            }
            .fullScreenCover(item: $activeRecording, onDismiss: {
                if let session = completedRecordingSession {
                    selectedSessionForDetail = session
                    completedRecordingSession = nil
                }
            }) { recording in
                ActiveRecordingView(
                    session: recording.session,
                    recordingSource: recording.source
                ) {
                    completedRecordingSession = recording.session
                }
            }
            .sheet(isPresented: $showRecordingSourcePicker, onDismiss: {
                guard let source = pendingRecordingSource else { return }
                pendingRecordingSource = nil
                createSessionAndNavigate(source: source)
            }) {
                RecordingSourcePickerView(devices: connectedSparkDevices) { source in
                    pendingRecordingSource = source
                    showRecordingSourcePicker = false
                }
            }
            .navigationDestination(item: $selectedSessionForDetail) { session in
                SessionDetailView(session: session)
            }
        }
    }

    // MARK: - Top Bar

    private var topBar: some View {
        HStack(alignment: .top) {
            VStack(alignment: .leading, spacing: 4) {
                Text("星痕现场记录")
                    .font(.system(size: 11, weight: .bold, design: .monospaced))
                    .foregroundStyle(Color.primary.opacity(0.8))
                    .tracking(3)

                Text(currentDateFormatted)
                    .font(.system(size: 13, weight: .regular))
                    .foregroundStyle(Color.secondary)
            }
            Spacer()
        }
    }

    // MARK: - Record Section

    private var recordSection: some View {
        VStack(spacing: 24) {
            PulsingRecordButton {
                beginNewRecording()
            }

            Button {
                beginNewRecording()
            } label: {
                Text("开始")
                    .font(.system(size: 16, weight: .medium))
                    .foregroundStyle(Color.primary.opacity(0.88))
                    .tracking(0.4)
            }
            .buttonStyle(.plain)
        }
    }

    // MARK: - Technical Grid Background

    private var businessGrid: some View {
        Canvas { context, size in
            let step: CGFloat = 40
            let cols = Int(size.width / step)
            let rows = Int(size.height / step)
            
            for col in 0...cols {
                let x = CGFloat(col) * step
                var path = Path()
                path.move(to: CGPoint(x: x, y: 0))
                path.addLine(to: CGPoint(x: x, y: size.height))
                context.stroke(path, with: .color(Color.primary.opacity(0.015)), lineWidth: 0.5)
            }
            for row in 0...rows {
                let y = CGFloat(row) * step
                var path = Path()
                path.move(to: CGPoint(x: 0, y: y))
                path.addLine(to: CGPoint(x: size.width, y: y))
                context.stroke(path, with: .color(Color.primary.opacity(0.015)), lineWidth: 0.5)
            }
        }
        .ignoresSafeArea()
        .allowsHitTesting(false)
    }

    // MARK: - Actions

    private func beginNewRecording() {
        if connectedSparkDevices.isEmpty {
            createSessionAndNavigate(source: .iPhone)
        } else {
            showRecordingSourcePicker = true
        }
    }

    private func createSessionAndNavigate(source: RecordingSourceChoice) {
        let formatter = DateFormatter()
        formatter.dateFormat = "yyyyMMdd_HHmm"
        let title = "现场记录_\(formatter.string(from: Date()))"

        let session = CelestiaSession(title: title)
        modelContext.insert(session)
        try? modelContext.save()

        HapticManager.trigger(.recordStart)
        activeRecording = ActiveRecordingPresentation(session: session, source: source)
    }

    private var connectedSparkDevices: [BoundDevice] {
        guard let userID = authManager.currentUser?.id else { return [] }
        return bleManager.connectedDevices(forUserId: userID)
            .sorted { $0.boundAt < $1.boundAt }
    }

    // MARK: - Helpers

    private var currentDateFormatted: String {
        let formatter = DateFormatter()
        formatter.locale = Locale(identifier: "zh_Hans")
        formatter.dateFormat = "yyyy年M月d日 EEEE"
        return formatter.string(from: Date())
    }
}

private struct ActiveRecordingPresentation: Identifiable {
    let id = UUID()
    let session: CelestiaSession
    let source: RecordingSourceChoice
}

// MARK: - Recording source picker

/// Shared by new recordings and continuation recordings. When at least one
/// connected Spark exists, the first Spark is selected by default.
struct RecordingSourcePickerView: View {
    @Environment(\.dismiss) private var dismiss

    let devices: [BoundDevice]
    let onConfirm: (RecordingSourceChoice) -> Void
    @State private var selection: RecordingSourceChoice

    init(devices: [BoundDevice], onConfirm: @escaping (RecordingSourceChoice) -> Void) {
        self.devices = devices
        self.onConfirm = onConfirm
        if let first = devices.first {
            _selection = State(initialValue: .spark(deviceID: first.id, displayName: first.name))
        } else {
            _selection = State(initialValue: .iPhone)
        }
    }

    var body: some View {
        NavigationStack {
            ZStack {
                Color.spaceBlack.ignoresSafeArea()
                VStack(alignment: .leading, spacing: 14) {
                    Text("选择本次现场记录使用的录音设备")
                        .font(.system(size: 13))
                        .foregroundStyle(Color.secondary)

                    ForEach(Array(devices.enumerated()), id: \.element.id) { index, device in
                        sourceRow(
                            source: .spark(deviceID: device.id, displayName: device.name),
                            title: device.name,
                            subtitle: sparkSubtitle(device),
                            badge: index == 0 ? "默认" : nil
                        )
                    }

                    sourceRow(
                        source: .iPhone,
                        title: "iPhone 麦克风",
                        subtitle: "使用手机内置或当前系统音频输入",
                        badge: devices.isEmpty ? "默认" : nil
                    )

                    Button {
                        onConfirm(selection)
                    } label: {
                        Text("开始现场记录")
                            .font(.system(size: 14, weight: .semibold))
                            .foregroundStyle(Color.spaceBlack)
                            .frame(maxWidth: .infinity)
                            .padding(.vertical, 12)
                            .background(Color.primary)
                            .cornerRadius(8)
                    }
                    .padding(.top, 8)

                    Spacer()
                }
                .padding(20)
            }
            .navigationTitle("录音设备")
            .navigationBarTitleDisplayMode(.inline)
            .toolbar {
                ToolbarItem(placement: .cancellationAction) {
                    Button("取消") { dismiss() }
                        .foregroundStyle(Color.secondary)
                }
            }
        }
        .presentationDetents([.medium, .large])
        .presentationBackground(Color.spaceBlack)
    }

    private func sourceRow(
        source: RecordingSourceChoice,
        title: String,
        subtitle: String,
        badge: String?
    ) -> some View {
        Button {
            selection = source
        } label: {
            HStack(spacing: 12) {
                Image(systemName: source.systemImage)
                    .font(.system(size: 19, weight: .light))
                    .foregroundStyle(Color.primary)
                    .frame(width: 34)

                VStack(alignment: .leading, spacing: 4) {
                    HStack(spacing: 7) {
                        Text(title)
                            .font(.system(size: 14, weight: .semibold))
                            .foregroundStyle(Color.primary)
                        if let badge {
                            Text(badge)
                                .font(.system(size: 9, weight: .bold))
                                .foregroundStyle(Color.spaceBlack)
                                .padding(.horizontal, 6)
                                .padding(.vertical, 2)
                                .background(Color.primary)
                                .cornerRadius(4)
                        }
                    }
                    Text(subtitle)
                        .font(.system(size: 11))
                        .foregroundStyle(Color.secondary)
                }

                Spacer()

                Image(systemName: selection == source ? "checkmark.circle.fill" : "circle")
                    .font(.system(size: 18))
                    .foregroundStyle(selection == source ? Color.primary : Color.secondary)
            }
            .padding(14)
            .background(Color.cardBackground.opacity(selection == source ? 0.55 : 0.25))
            .businessBorder(cornerRadius: 10)
        }
        .buttonStyle(.plain)
    }

    private func sparkSubtitle(_ device: BoundDevice) -> String {
        var parts = ["已连接"]
        if let battery = device.batteryLevel { parts.append("电量 \(battery)%") }
        if let free = device.freeStorageMB { parts.append("剩余 \(free) MB") }
        return parts.joined(separator: " · ")
    }
}

// MARK: - Preview

#Preview {
    HomeView()
        .modelContainer(for: CelestiaSession.self, inMemory: true)
}
