import SwiftUI
import SwiftData

struct ExplorerView: View {
    @Environment(\.modelContext) private var modelContext
    @Query(sort: \Album.updatedAt, order: .reverse) private var albums: [Album]

    var onStartLesson: (StudySession) -> Void

    @State private var currentPath = ""
    @State private var listing: DirListing = DirListing(path: "", entries: [])
    @State private var selectedIDs: Set<String> = []
    @State private var errorMessage: String?
    @State private var showNewFolder = false
    @State private var newFolderName = ""
    @State private var renameTarget: DirEntry?
    @State private var renameText = ""
    @State private var moveTarget: DirEntry?
    @State private var moveDest = ""
    @State private var deleteTarget: DirEntry?
    @State private var draftMode: AlbumMode = .playlist
    @State private var draftTitle = "未命名专辑"
    @State private var draft: Album?
    @State private var draftError: String?

    private var store: LibraryStore { LibraryStore(modelContext: modelContext) }

    private var selectedEntries: [CatalogEntry] {
        listing.entries.compactMap { entry in
            guard !entry.isDir, let resource = entry.resource, selectedIDs.contains(resource.id) else { return nil }
            return resource
        }
    }

    private var resolved: ResolvedSelection {
        SelectionResolver.resolve(selectedEntries)
    }

    var body: some View {
        HStack(spacing: 0) {
            directoryPane
                .frame(minWidth: 280, idealWidth: 320)
            Divider()
            centerPane
                .frame(minWidth: 280)
            Divider()
            detailPane
                .frame(minWidth: 280, idealWidth: 340)
        }
        .navigationTitle("Explorer")
        .onAppear(perform: reload)
        .alert("错误", isPresented: Binding(
            get: { errorMessage != nil },
            set: { if !$0 { errorMessage = nil } }
        )) {
            Button("好", role: .cancel) {}
        } message: {
            Text(errorMessage ?? "")
        }
        .alert("新建文件夹", isPresented: $showNewFolder) {
            TextField("名称", text: $newFolderName)
            Button("取消", role: .cancel) {}
            Button("创建") { createFolder() }
        }
        .alert("重命名", isPresented: Binding(
            get: { renameTarget != nil },
            set: { if !$0 { renameTarget = nil } }
        )) {
            TextField("新名称", text: $renameText)
            Button("取消", role: .cancel) {}
            Button("保存") { applyRename() }
        }
        .alert("移动到目录", isPresented: Binding(
            get: { moveTarget != nil },
            set: { if !$0 { moveTarget = nil } }
        )) {
            TextField("目标相对路径", text: $moveDest)
            Button("取消", role: .cancel) {}
            Button("移动") { applyMove() }
        }
        .confirmationDialog(
            "确认删除？",
            isPresented: Binding(
                get: { deleteTarget != nil },
                set: { if !$0 { deleteTarget = nil } }
            ),
            titleVisibility: .visible
        ) {
            Button("删除", role: .destructive) { applyDelete() }
            Button("取消", role: .cancel) {}
        } message: {
            Text(deleteTarget?.relativePath ?? "")
        }
    }

    private var directoryPane: some View {
        VStack(alignment: .leading, spacing: 0) {
            HStack {
                Button {
                    goUp()
                } label: {
                    Image(systemName: "chevron.left")
                }
                .disabled(currentPath.isEmpty)
                Text(currentPath.isEmpty ? "library/" : "library/\(currentPath)")
                    .font(.caption.monospaced())
                    .lineLimit(1)
                Spacer()
                Button {
                    newFolderName = ""
                    showNewFolder = true
                } label: {
                    Image(systemName: "folder.badge.plus")
                }
            }
            .padding(12)

            List {
                ForEach(listing.entries) { entry in
                    row(for: entry)
                }
            }
            .listStyle(.plain)
        }
    }

    private func row(for entry: DirEntry) -> some View {
        HStack(spacing: 12) {
            if entry.isDir {
                Label(entry.name, systemImage: "folder.fill")
                    .frame(maxWidth: .infinity, alignment: .leading)
                    .contentShape(Rectangle())
                    .onTapGesture {
                        currentPath = entry.relativePath
                        selectedIDs.removeAll()
                        reload()
                    }
            } else {
                let resource = entry.resource
                let selected = resource.map { selectedIDs.contains($0.id) } ?? false
                HStack {
                    Image(systemName: selected ? "checkmark.circle.fill" : "circle")
                    Text(entry.name)
                    Spacer()
                    KindBadge(kind: resource?.kind ?? ResourceKind.from(extension: (entry.name as NSString).pathExtension))
                }
                .frame(maxWidth: .infinity, alignment: .leading)
                .contentShape(Rectangle())
                .onTapGesture {
                    guard let resource else { return }
                    if selectedIDs.contains(resource.id) {
                        selectedIDs.remove(resource.id)
                    } else {
                        selectedIDs.insert(resource.id)
                    }
                }
            }
            Menu {
                Button("重命名") {
                    renameTarget = entry
                    renameText = entry.name
                }
                Button("移动") {
                    moveTarget = entry
                    moveDest = ""
                }
                Button("删除", role: .destructive) {
                    deleteTarget = entry
                }
            } label: {
                Image(systemName: "ellipsis.circle")
                    .frame(minWidth: 44, minHeight: 44)
                    .contentShape(Rectangle())
            }
        }
    }

    private var centerPane: some View {
        VStack(alignment: .leading, spacing: 16) {
            Text("选区 / 草稿")
                .font(.title3.bold())
            Text(resolved.message)
                .foregroundStyle(.secondary)

            Picker("草稿类型", selection: $draftMode) {
                Text(AlbumMode.playlist.label).tag(AlbumMode.playlist)
                Text(AlbumMode.combo.label).tag(AlbumMode.combo)
            }
            .pickerStyle(.segmented)
            .onChange(of: draftMode) { _, _ in
                draft = nil
                draftError = nil
            }

            TextField("标题", text: $draftTitle)
                .textFieldStyle(.roundedBorder)

            HStack {
                Button("从选区生成草稿") {
                    let built = AlbumDraftHelper.buildDraftFromSelection(
                        mode: draftMode,
                        resolved: resolved,
                        title: draftTitle
                    )
                    draft = built.album
                    draftError = built.error
                }
                Button("追加选区") {
                    guard let draft else {
                        draftError = "请先生成草稿"
                        return
                    }
                    let result = AlbumDraftHelper.appendSelectionToDraft(draft: draft, resolved: resolved)
                    self.draft = result.album
                    draftError = result.error
                }
                .disabled(draft == nil)
            }

            if let draftError {
                Text(draftError).foregroundStyle(.orange)
            }

            if let draft {
                Text("\(draft.mode.label) · \(draft.items.count) 项")
                Button("保存到资料库") {
                    store.saveAlbum(draft)
                    self.draft = nil
                }
                .buttonStyle(.borderedProminent)
            }

            Divider()
            Text("已保存专辑/课程").font(.headline)
            List {
                ForEach(albums, id: \.id) { album in
                    HStack {
                        VStack(alignment: .leading) {
                            Text(album.title)
                            Text("\(album.mode.label) · \(album.items.count) 项")
                                .font(.caption)
                                .foregroundStyle(.secondary)
                        }
                        Spacer()
                        Button("开第 1 课") {
                            startAlbum(album, index: 0)
                        }
                        .disabled(album.items.isEmpty)
                        Button(role: .destructive) {
                            store.deleteAlbum(album)
                        } label: {
                            Image(systemName: "trash")
                        }
                    }
                }
            }
            .listStyle(.plain)
        }
        .padding()
    }

    private var detailPane: some View {
        VStack(alignment: .leading, spacing: 16) {
            Text("详情")
                .font(.title3.bold())
            Text("已选 \(selectedEntries.count) 个文件")
            Text(resolved.label)
                .font(.title2)
            Text(resolved.message)
                .foregroundStyle(.secondary)

            ForEach(selectedEntries, id: \.id) { entry in
                HStack {
                    KindBadge(kind: entry.kind)
                    Text(entry.name)
                }
            }

            Spacer()

            Button {
                startLessonFromSelection()
            } label: {
                Label("开始学习", systemImage: "play.fill")
                    .frame(maxWidth: .infinity)
            }
            .buttonStyle(.borderedProminent)
            .disabled(resolved.status != .ready || resolved.mode == nil)
            .padding(.bottom)
        }
        .padding()
    }

    private func reload() {
        do {
            listing = try store.listDirectory(relative: currentPath)
        } catch {
            errorMessage = error.localizedDescription
        }
    }

    private func goUp() {
        guard !currentPath.isEmpty else { return }
        currentPath = (currentPath as NSString).deletingLastPathComponent
        if currentPath == "." { currentPath = "" }
        reload()
    }

    private func createFolder() {
        do {
            _ = try store.createFolder(parentDir: currentPath, name: newFolderName)
            reload()
        } catch {
            errorMessage = error.localizedDescription
        }
    }

    private func applyRename() {
        guard let target = renameTarget else { return }
        do {
            try store.rename(relativePath: target.relativePath, newName: renameText)
            renameTarget = nil
            reload()
        } catch {
            errorMessage = error.localizedDescription
        }
    }

    private func applyMove() {
        guard let target = moveTarget else { return }
        do {
            try store.move(relativePath: target.relativePath, targetDir: moveDest)
            moveTarget = nil
            reload()
        } catch {
            errorMessage = error.localizedDescription
        }
    }

    private func applyDelete() {
        guard let target = deleteTarget else { return }
        do {
            try store.delete(relativePath: target.relativePath)
            deleteTarget = nil
            selectedIDs.removeAll()
            reload()
        } catch {
            errorMessage = error.localizedDescription
        }
    }

    private func startLessonFromSelection() {
        guard resolved.status == .ready, let mode = resolved.mode else {
            errorMessage = resolved.message
            return
        }
        if !mode.isMVPSupported {
            errorMessage = "该模式（\(mode.label)）UI 暂未产品化，请改用单资源或 video+pdf / pdf+audio"
            return
        }
        let title = selectedEntries.map(\.name).joined(separator: " + ")
        let session = store.createSession(
            title: title.isEmpty ? mode.label : title,
            mode: mode,
            resourceIds: resolved.resourceIds
        )
        onStartLesson(session)
    }

    private func startAlbum(_ album: Album, index: Int) {
        guard let lesson = AlbumSessionHelper.itemToLesson(album: album, index: index) else {
            errorMessage = "专辑项无效"
            return
        }
        if !lesson.mode.isMVPSupported {
            errorMessage = "该模式暂未在 Study 中支持"
            return
        }
        let session = store.createSession(
            title: lesson.title,
            mode: lesson.mode,
            resourceIds: lesson.resourceIds,
            albumId: lesson.albumId,
            albumIndex: lesson.albumIndex
        )
        onStartLesson(session)
    }
}

struct KindBadge: View {
    let kind: ResourceKind

    var body: some View {
        Text(kind.label)
            .font(.caption2.bold())
            .padding(.horizontal, 8)
            .padding(.vertical, 3)
            .background(color.opacity(0.18))
            .foregroundStyle(color)
            .clipShape(Capsule())
    }

    private var color: Color {
        switch kind {
        case .video: return .blue
        case .audio: return .purple
        case .pdf: return .orange
        case .other: return .gray
        }
    }
}
