import SwiftUI
import UniformTypeIdentifiers
import AudioCore

struct LibraryView: View {
    @State private var library = LibraryModel()
    @State private var openProject: ProjectStore?
    @State private var showImporter = false

    private static let importTypes: [UTType] = [
        UTType(filenameExtension: "acasong") ?? .plainText,
        UTType(filenameExtension: "musicxml") ?? .xml,
        UTType(filenameExtension: "mxl") ?? .zip,
        .xml,
    ]

    var body: some View {
        NavigationStack {
            List {
                if !library.projects.isEmpty {
                    Section("My Projects") {
                        ForEach(library.projects) { entry in
                            Button {
                                openProject = try? ProjectStore.open(at: entry.url)
                            } label: {
                                HStack {
                                    VStack(alignment: .leading, spacing: 2) {
                                        Text(entry.title)
                                            .font(.headline)
                                            .foregroundStyle(.primary)
                                        Text("\(entry.recordedPartCount)/\(entry.partCount) parts recorded")
                                            .font(.caption)
                                            .foregroundStyle(.secondary)
                                    }
                                    Spacer()
                                    ProgressView(
                                        value: Double(entry.recordedPartCount),
                                        total: Double(max(1, entry.partCount))
                                    )
                                    .progressViewStyle(.circular)
                                    .controlSize(.small)
                                }
                            }
                        }
                        .onDelete { indexSet in
                            for index in indexSet {
                                library.deleteProject(library.projects[index])
                            }
                        }
                    }
                }

                if !library.importedSongs.isEmpty {
                    Section("Imported Songs") {
                        ForEach(library.importedSongs) { song in
                            songRow(song)
                        }
                    }
                }

                Section("Start a New Project") {
                    ForEach(library.bundledSongs) { song in
                        songRow(song)
                    }
                    Button {
                        showImporter = true
                    } label: {
                        Label("Import Song (MusicXML / acasong)", systemImage: "square.and.arrow.down")
                    }
                }
            }
            .navigationTitle("Acapella")
            .onAppear { library.refresh() }
            .fileImporter(
                isPresented: $showImporter,
                allowedContentTypes: LibraryView.importTypes,
                allowsMultipleSelection: true
            ) { result in
                if case .success(let urls) = result {
                    for url in urls { library.importSong(from: url) }
                }
            }
            .alert("Import", isPresented: .init(
                get: { library.importReport != nil },
                set: { if !$0 { library.importReport = nil } }
            )) {
                Button("OK") { library.importReport = nil }
            } message: {
                Text(library.importReport ?? "")
            }
            .fullScreenCover(item: $openProject) { store in
                ProjectView(store: store) {
                    openProject = nil
                    library.refresh()
                }
            }
            .alert("Error", isPresented: .init(
                get: { library.errorMessage != nil },
                set: { if !$0 { library.errorMessage = nil } }
            )) {
                Button("OK") { library.errorMessage = nil }
            } message: {
                Text(library.errorMessage ?? "")
            }
        }
    }

    private func songRow(_ song: LibraryModel.BundledSong) -> some View {
        Button {
            if let store = library.createProject(from: song) {
                openProject = store
            }
        } label: {
            HStack {
                Image(systemName: "music.note.list")
                    .foregroundStyle(.tint)
                VStack(alignment: .leading, spacing: 2) {
                    Text(song.title)
                        .foregroundStyle(.primary)
                    Text("\(song.score.parts.count) parts · \(song.score.keySignature.name) · \(song.score.timeSignature.name)")
                        .font(.caption)
                        .foregroundStyle(.secondary)
                }
            }
        }
    }
}

extension ProjectStore: @retroactive Identifiable {
    public var id: URL { url }
}

#Preview {
    LibraryView()
}
