import SwiftUI
import PhotosUI
import UIKit

/// A helper SwiftUI wrapper for UIImagePickerController to select photos or capture via camera.
struct ImagePicker: UIViewControllerRepresentable {
    var sourceType: UIImagePickerController.SourceType = .camera
    var onImagePicked: (UIImage) -> Void

    @Environment(\.dismiss) private var dismiss

    func makeUIViewController(context: Context) -> UIImagePickerController {
        let picker = UIImagePickerController()
        picker.sourceType = sourceType
        picker.delegate = context.coordinator
        return picker
    }

    func updateUIViewController(_ uiViewController: UIImagePickerController, context: Context) {}

    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }

    class Coordinator: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
        let parent: ImagePicker

        init(_ parent: ImagePicker) {
            self.parent = parent
        }

        func imagePickerController(
            _ picker: UIImagePickerController,
            didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]
        ) {
            if let image = info[.originalImage] as? UIImage {
                parent.onImagePicked(image)
            }
            parent.dismiss()
        }

        func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
            parent.dismiss()
        }
    }
}

struct PhotoRecordDraft: Identifiable {
    let id: UUID
    let image: UIImage
    var note: String

    init(
        id: UUID = UUID(),
        image: UIImage,
        note: String = ""
    ) {
        self.id = id
        self.image = image
        self.note = note
    }
}

struct PhotoRecordEditorSheet: View {
    @Environment(\.dismiss) private var dismiss

    let timeLabel: String
    let onSave: ([PhotoRecordDraft], TimelineLocation?) -> Bool

    @State private var drafts: [PhotoRecordDraft] = []
    @State private var recordLocation: TimelineLocation?
    @State private var selectedLibraryItems: [PhotosPickerItem] = []
    @State private var showCamera = false
    @State private var isLoadingLibrary = false
    @State private var loadError: String?

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

                ScrollView {
                    VStack(alignment: .leading, spacing: 16) {
                        Label("记录点 \(timeLabel)", systemImage: "clock")
                            .font(.system(size: 12, weight: .medium, design: .monospaced))
                            .foregroundStyle(Color.secondary)

                        HStack(spacing: 12) {
                            if UIImagePickerController.isSourceTypeAvailable(.camera) {
                                Button {
                                    showCamera = true
                                } label: {
                                    photoSourceButtonLabel(
                                        title: "拍照",
                                        systemImage: "camera"
                                    )
                                }
                                .buttonStyle(.plain)
                            }

                            PhotosPicker(
                                selection: $selectedLibraryItems,
                                maxSelectionCount: 0,
                                matching: .images
                            ) {
                                photoSourceButtonLabel(
                                    title: "从相册选择",
                                    systemImage: "photo.on.rectangle"
                                )
                            }
                            .buttonStyle(.plain)
                        }

                        TimelineLocationButton(location: $recordLocation)

                        if isLoadingLibrary {
                            HStack(spacing: 8) {
                                ProgressView()
                                Text("正在读取照片…")
                                    .font(.system(size: 12))
                                    .foregroundStyle(Color.secondary)
                            }
                        }

                        if drafts.isEmpty, !isLoadingLibrary {
                            ContentUnavailableView(
                                "还没有照片",
                                systemImage: "photo.badge.plus",
                                description: Text("可以连续拍照，也可以从相册一次选择多张。")
                            )
                            .frame(maxWidth: .infinity, minHeight: 220)
                        } else {
                            LazyVStack(spacing: 14) {
                                ForEach($drafts) { $draft in
                                    photoDraftCard(draft: $draft)
                                }
                            }
                        }
                    }
                    .padding(20)
                }
            }
            .navigationTitle("添加照片记录")
            .navigationBarTitleDisplayMode(.inline)
            .toolbar {
                ToolbarItem(placement: .cancellationAction) {
                    Button("取消") {
                        dismiss()
                    }
                }

                ToolbarItem(placement: .confirmationAction) {
                    Button("保存 \(drafts.count) 张") {
                        if onSave(drafts, recordLocation) {
                            dismiss()
                        }
                    }
                    .disabled(drafts.isEmpty || isLoadingLibrary)
                }
            }
        }
        .fullScreenCover(isPresented: $showCamera) {
            ImagePicker(sourceType: .camera) { image in
                drafts.append(PhotoRecordDraft(image: image))
            }
        }
        .onChange(of: selectedLibraryItems) { _, newItems in
            guard !newItems.isEmpty else { return }
            Task {
                await importLibraryItems(newItems)
            }
        }
        .alert("无法读取照片", isPresented: Binding(
            get: { loadError != nil },
            set: { if !$0 { loadError = nil } }
        )) {
            Button("知道了", role: .cancel) {}
        } message: {
            Text(loadError ?? "请重新选择照片。")
        }
        .presentationDetents([.large])
        .presentationDragIndicator(.visible)
        .presentationBackground(Color.spaceBlack)
    }

    private func photoSourceButtonLabel(
        title: String,
        systemImage: String
    ) -> some View {
        Label(title, systemImage: systemImage)
            .font(.system(size: 13, weight: .medium))
            .foregroundStyle(Color.primary)
            .frame(maxWidth: .infinity)
            .padding(.vertical, 12)
            .background(Color.cardBackground.opacity(0.35))
            .businessBorder(cornerRadius: 8)
            .contentShape(Rectangle())
    }

    private func photoDraftCard(
        draft: Binding<PhotoRecordDraft>
    ) -> some View {
        VStack(alignment: .leading, spacing: 10) {
            ZStack(alignment: .topTrailing) {
                Image(uiImage: draft.wrappedValue.image)
                    .resizable()
                    .scaledToFit()
                    .frame(maxWidth: .infinity, minHeight: 160, maxHeight: 300)
                    .clipShape(RoundedRectangle(cornerRadius: 8))

                Button(role: .destructive) {
                    let draftID = draft.wrappedValue.id
                    drafts.removeAll { $0.id == draftID }
                } label: {
                    Image(systemName: "trash")
                        .font(.system(size: 12, weight: .semibold))
                        .foregroundStyle(.white)
                        .frame(width: 32, height: 32)
                        .background(.black.opacity(0.6), in: Circle())
                }
                .padding(8)
                .accessibilityLabel("移除这张照片")
            }

            ZStack(alignment: .topLeading) {
                if draft.wrappedValue.note.isEmpty {
                    Text("照片备注")
                        .font(.system(size: 14))
                        .foregroundStyle(Color.secondary.opacity(0.55))
                        .padding(.horizontal, 15)
                        .padding(.vertical, 17)
                        .allowsHitTesting(false)
                }

                TextEditor(text: draft.note)
                    .font(.system(size: 14))
                    .foregroundStyle(Color.primary)
                    .scrollContentBackground(.hidden)
                    .padding(8)
                    .frame(height: 72)
            }
            .background(Color.cardBackground.opacity(0.45))
            .businessBorder(cornerRadius: 8)

        }
        .padding(12)
        .background(Color.cardBackground.opacity(0.18))
        .businessBorder(cornerRadius: 10)
    }

    @MainActor
    private func importLibraryItems(_ items: [PhotosPickerItem]) async {
        isLoadingLibrary = true
        defer {
            isLoadingLibrary = false
            selectedLibraryItems = []
        }

        var importedDrafts: [PhotoRecordDraft] = []
        var failedCount = 0

        for item in items {
            do {
                guard let data = try await item.loadTransferable(type: Data.self),
                      let image = UIImage(data: data) else {
                    failedCount += 1
                    continue
                }
                importedDrafts.append(PhotoRecordDraft(image: image))
            } catch {
                failedCount += 1
            }
        }

        drafts.append(contentsOf: importedDrafts)

        if failedCount > 0 {
            loadError = failedCount == items.count
                ? "所选照片均无法读取，请重新选择。"
                : "有 \(failedCount) 张照片无法读取，其余照片已添加。"
        }
    }
}
