import Photos
import SwiftData
import SwiftUI

struct ScanView: View {
    @ObservedObject var flowModel: ScanFlowModel
    @Query(sort: \ConfirmedScanRecord.confirmedAt, order: .reverse) private var confirmedRecords: [ConfirmedScanRecord]

    var body: some View {
        ScrollView {
            VStack(alignment: .leading, spacing: 20) {
                cameraSection
                recentPhotosSection
                actionSection
                temporaryLogSection
            }
            .padding(20)
        }
        .navigationTitle("Scan Card")
        .navigationBarTitleDisplayMode(.inline)
        .overlay {
            if flowModel.isRecognizing {
                ProgressView("Recognizing card…")
                    .padding(.horizontal, 18)
                    .padding(.vertical, 14)
                    .background(.ultraThinMaterial, in: RoundedRectangle(cornerRadius: 16))
            }
        }
        .alert("StackDex", isPresented: messageIsPresented) {
            Button("OK", role: .cancel) {
                flowModel.transientMessage = nil
            }
        } message: {
            Text(flowModel.transientMessage ?? "")
        }
    }

    private var cameraSection: some View {
        VStack(alignment: .leading, spacing: 12) {
            Text("Camera")
                .font(.headline)

            ZStack {
                RoundedRectangle(cornerRadius: 24)
                    .fill(.black.opacity(0.92))

                if flowModel.cameraService.isSessionRunning {
                    CameraPreviewView(session: flowModel.cameraService.session)
                        .clipShape(RoundedRectangle(cornerRadius: 24))
                } else {
                    cameraPlaceholder
                }

                RoundedRectangle(cornerRadius: 20)
                    .stroke(.white.opacity(0.7), style: StrokeStyle(lineWidth: 2, dash: [10, 8]))
                    .padding(28)
            }
            .frame(height: 440)

            if flowModel.cameraService.authorizationStatus == .authorized {
                HStack {
                    Spacer()
                    Button {
                        Task { await flowModel.capturePhoto() }
                    } label: {
                        ZStack {
                            Circle().fill(.white).frame(width: 76, height: 76)
                            Circle().stroke(.black.opacity(0.85), lineWidth: 3).frame(width: 62, height: 62)
                        }
                    }
                    .accessibilityLabel("Capture card photo")
                    Spacer()
                }
            }
        }
    }

    @ViewBuilder
    private var cameraPlaceholder: some View {
        VStack(spacing: 14) {
            Image(systemName: "camera.viewfinder")
                .font(.system(size: 44, weight: .semibold))
                .foregroundStyle(.white)

            Text(cameraPlaceholderText)
                .font(.headline)
                .foregroundStyle(.white)
                .multilineTextAlignment(.center)

            Text("Scan starts after an explicit shutter tap. No image is stored after recognition.")
                .font(.subheadline)
                .foregroundStyle(.white.opacity(0.75))
                .multilineTextAlignment(.center)
                .padding(.horizontal, 24)

            if flowModel.cameraService.authorizationStatus != .authorized {
                Button(cameraButtonTitle) {
                    if flowModel.cameraService.authorizationStatus == .denied {
                        flowModel.photoLibraryService.openSettings()
                    } else {
                        Task { await flowModel.enableCamera() }
                    }
                }
                .buttonStyle(.borderedProminent)
            }
        }
        .padding(24)
    }

    private var recentPhotosSection: some View {
        VStack(alignment: .leading, spacing: 12) {
            HStack {
                Text("Recent photos")
                    .font(.headline)
                Spacer()
                if flowModel.photoLibraryService.authorizationStatus == .limited {
                    Button("Manage") {
                        flowModel.photoLibraryService.presentLimitedLibraryPicker()
                    }
                }
            }

            switch flowModel.photoLibraryService.authorizationStatus {
            case .authorized, .limited:
                if flowModel.photoLibraryService.isLoading {
                    ProgressView()
                        .frame(maxWidth: .infinity, minHeight: 72)
                } else if flowModel.photoLibraryService.recentPhotos.isEmpty {
                    secondaryPanel("No recent photos available.")
                } else {
                    ScrollView(.horizontal, showsIndicators: false) {
                        HStack(spacing: 12) {
                            ForEach(flowModel.photoLibraryService.recentPhotos) { item in
                                Button {
                                    Task { await flowModel.importRecentPhoto(item) }
                                } label: {
                                    Image(uiImage: item.thumbnail)
                                        .resizable()
                                        .scaledToFill()
                                        .frame(width: 88, height: 88)
                                        .clipShape(RoundedRectangle(cornerRadius: 14))
                                }
                                .buttonStyle(.plain)
                            }
                        }
                    }
                }
            case .denied, .restricted:
                secondaryPanel("Photo access is unavailable. You can keep scanning with the camera or open Settings to allow recent-photo import.") {
                    Button("Open Settings") {
                        flowModel.photoLibraryService.openSettings()
                    }
                    .buttonStyle(.bordered)
                }
            case .notDetermined:
                secondaryPanel("Recent photos stay optional and are requested only when you ask for them.") {
                    Button("Show Recents") {
                        Task { await flowModel.photoLibraryService.requestAccessAndLoad() }
                    }
                    .buttonStyle(.borderedProminent)
                }
            @unknown default:
                secondaryPanel("Recent photos are unavailable on this device.")
            }
        }
    }

    private var actionSection: some View {
        VStack(alignment: .leading, spacing: 12) {
            Text("Fallback")
                .font(.headline)

            secondaryPanel(flowModel.networkMonitor.isOnline ? "Cloud OCR is prepared as an injectable boundary, but the default client is intentionally stubbed for this local MVP. Vision OCR remains fully functional." : "You’re offline, so StackDex will use the on-device Vision pipeline.") {
                Button("Enter Manually") {
                    flowModel.startManualEntry()
                }
                .buttonStyle(.bordered)
            }
        }
    }

    private var temporaryLogSection: some View {
        VStack(alignment: .leading, spacing: 12) {
            Text("Temporary confirmations")
                .font(.headline)

            if confirmedRecords.isEmpty {
                secondaryPanel("Confirmed cards are logged locally in SwiftData so the MVP can prove the end-to-end flow without storing source images.")
            } else {
                VStack(spacing: 10) {
                    ForEach(Array(confirmedRecords.prefix(3))) { record in
                        HStack(alignment: .top) {
                            VStack(alignment: .leading, spacing: 4) {
                                Text(record.cardName.isEmpty ? "Unnamed card" : record.cardName)
                                    .font(.subheadline.weight(.semibold))
                                Text([record.cardNumber, record.setIdentifier].filter { !$0.isEmpty }.joined(separator: " · "))
                                    .font(.caption)
                                    .foregroundStyle(.secondary)
                            }
                            Spacer()
                            Text(record.confirmedAt, style: .time)
                                .font(.caption2)
                                .foregroundStyle(.secondary)
                        }
                        .padding(12)
                        .background(.thinMaterial, in: RoundedRectangle(cornerRadius: 14))
                    }
                }
            }
        }
    }

    private var messageIsPresented: Binding<Bool> {
        Binding(
            get: { flowModel.transientMessage != nil },
            set: { if !$0 { flowModel.transientMessage = nil } }
        )
    }

    private var cameraPlaceholderText: String {
        switch flowModel.cameraService.authorizationStatus {
        case .authorized:
            return "Starting camera preview…"
        case .denied:
            return "Camera access is denied"
        case .restricted:
            return "Camera access is restricted"
        case .notDetermined:
            return "Enable the camera to scan a card"
        @unknown default:
            return "Camera unavailable"
        }
    }

    private var cameraButtonTitle: String {
        switch flowModel.cameraService.authorizationStatus {
        case .denied, .restricted:
            return "Open Settings"
        default:
            return "Enable Camera"
        }
    }

    private func secondaryPanel(_ text: String, @ViewBuilder actions: () -> some View = { EmptyView() }) -> some View {
        VStack(alignment: .leading, spacing: 10) {
            Text(text)
                .font(.subheadline)
                .foregroundStyle(.secondary)
            actions()
        }
        .frame(maxWidth: .infinity, alignment: .leading)
        .padding(14)
        .background(.thinMaterial, in: RoundedRectangle(cornerRadius: 16))
    }
}
