import SwiftUI
import SwiftData

// MARK: - HomeView
/// The main launch screen of CelestiaTrace.
/// Features a minimalist, line-drawn aesthetic with a central record button,
/// bordered session cards, and a subtle technical grid background.
struct HomeView: View {
    @Environment(\.modelContext) private var modelContext
    @Query(sort: \CelestiaSession.startTime, order: .reverse) private var sessions: [CelestiaSession]
    @ObservedObject private var bleManager: BLEManager = .shared
    @ObservedObject private var authManager: AuthManager = .shared

    @State private var navigateToRecording = false
    @State private var activeSession: 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 selectedRecordingSource: RecordingSourceChoice = .iPhone

    /// Callback to switch to the History tab from the parent TabView.
    var onSwitchToHistory: (() -> Void)?

    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()

                    recentSessionsSection
                        .padding(.bottom, 16)

                    historyLink
                        .padding(.bottom, 24)
                }
                .padding(.horizontal, 24)
            }
            .navigationBarHidden(true)
            .onAppear {
                detector.checkEnvironment()
            }
            .fullScreenCover(isPresented: $navigateToRecording) {
                if let session = activeSession {
                    ActiveRecordingView(session: session, recordingSource: selectedRecordingSource) {
                        selectedSessionForDetail = session
                    }
                }
            }
            .sheet(isPresented: $showRecordingSourcePicker) {
                RecordingSourcePickerView(devices: connectedSparkDevices) { source in
                    showRecordingSourcePicker = false
                    createSessionAndNavigate(source: source)
                }
            }
            .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()

            // Status indicator
            HStack(spacing: 6) {
                Circle()
                    .fill(Color.primary.opacity(0.7))
                    .frame(width: 5, height: 5)
                Text("就绪")
                    .font(.system(size: 9, weight: .semibold, design: .monospaced))
                    .foregroundStyle(Color.secondary)
            }
            .padding(.horizontal, 8)
            .padding(.vertical, 4)
            .businessBorder(cornerRadius: 4)
        }
    }

    // MARK: - Record Section

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

            VStack(spacing: 6) {
                Text("新建现场记录")
                    .font(.system(size: 16, weight: .medium))
                    .foregroundStyle(Color.primary)

                Text("点击开启全新现场录音")
                    .font(.system(size: 9, weight: .medium, design: .monospaced))
                    .foregroundStyle(Color.secondary.opacity(0.7))
                    .tracking(2)
            }
        }
    }

    // MARK: - Recent Sessions

    private var recentSessionsSection: some View {
        VStack(alignment: .leading, spacing: 12) {
            HStack {
                Image(systemName: "list.dash")
                    .font(.system(size: 12))
                    .foregroundStyle(Color.secondary)
                Text("最近记录")
                    .font(.system(size: 13, weight: .semibold))
                    .foregroundStyle(Color.primary.opacity(0.8))
            }

            if sessions.isEmpty {
                emptyRecentState
            } else {
                ScrollView(.horizontal, showsIndicators: false) {
                    HStack(spacing: 12) {
                        ForEach(sessions.prefix(3)) { session in
                            Button {
                                selectedSessionForDetail = session
                            } label: {
                                RecentSessionCard(session: session)
                            }
                            .buttonStyle(.plain)
                        }
                    }
                    .padding(.vertical, 2)
                }
            }
        }
    }

    private var emptyRecentState: some View {
        HStack {
            Spacer()
            VStack(spacing: 8) {
                Image(systemName: "plus.square.dashed")
                    .font(.system(size: 20))
                    .foregroundStyle(Color.secondary.opacity(0.4))
                Text("暂无记录")
                    .font(.system(size: 12))
                    .foregroundStyle(Color.secondary.opacity(0.5))
            }
            .padding(.vertical, 32)
            Spacer()
        }
        .background(Color.cardBackground.opacity(0.3))
        .businessBorder(cornerRadius: 8)
    }

    // MARK: - History Link

    private var historyLink: some View {
        Button {
            onSwitchToHistory?()
        } label: {
            HStack(spacing: 6) {
                Text("查看历史列表")
                    .font(.system(size: 13, weight: .regular))
                Image(systemName: "chevron.right")
                    .font(.system(size: 10))
            }
            .foregroundStyle(Color.primary.opacity(0.7))
            .padding(.horizontal, 14)
            .padding(.vertical, 8)
            .businessBorder(cornerRadius: 6)
        }
    }

    // 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 = "yyyy.MM.dd HH:mm"
        let title = "现场记录 · \(formatter.string(from: Date()))"

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

        activeSession = session
        selectedRecordingSource = source
        HapticManager.trigger(.recordStart)
        navigateToRecording = true
    }

    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())
    }
}

// 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: - Recent Session Card

private struct RecentSessionCard: View {
    let session: CelestiaSession

    var body: some View {
        VStack(alignment: .leading, spacing: 8) {
            Text(session.title)
                .font(.system(size: 13, weight: .medium))
                .foregroundStyle(Color.primary)
                .lineLimit(1)

            HStack(spacing: 4) {
                Image(systemName: "waveform")
                    .font(.system(size: 9))
                    .foregroundStyle(Color.secondary)
                Text(session.durationFormatted)
                    .font(.system(size: 11, weight: .regular, design: .monospaced))
                    .foregroundStyle(Color.secondary)
            }

            HStack(spacing: 12) {
                HStack(spacing: 3) {
                    Image(systemName: "camera")
                        .font(.system(size: 9))
                    Text("\(session.photoCount)")
                        .font(.system(size: 10, design: .monospaced))
                }
                .foregroundStyle(Color.secondary)

                HStack(spacing: 3) {
                    Image(systemName: "doc.text")
                        .font(.system(size: 9))
                    Text("\(session.noteCount)")
                        .font(.system(size: 10, design: .monospaced))
                }
                .foregroundStyle(Color.secondary)
            }
            .padding(.top, 4)
        }
        .padding(12)
        .frame(width: 150, alignment: .leading)
        .background(Color.cardBackground.opacity(0.3))
        .businessBorder(cornerRadius: 8)
    }
}

// MARK: - Preview

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