//
//  TravelAlbumDetailView.swift
//  suixinkan
//
//  Created by Codex on 2026/6/29.
//

import SwiftUI

/// 旅拍相册详情页，展示素材网格与管理操作，对齐 Android TravelAlbumDetailScreen。
struct TravelAlbumDetailView: View {
    let albumID: Int

    @EnvironmentObject private var accountContext: AccountContext
    @Environment(\.travelAlbumAPI) private var travelAlbumAPI
    @EnvironmentObject private var toastCenter: ToastCenter
    @Environment(\.globalLoading) private var globalLoading
    @Environment(\.dismiss) private var dismiss
    @Environment(\.openURL) private var openURL

    @StateObject private var viewModel = TravelAlbumDetailViewModel()
    @State private var showMoreMenu = false
    @State private var navigateToWiredTransfer = false
    @State private var didReturnFromWiredTransfer = false
    @State private var previewPayload: TravelAlbumMaterialPreviewPayload?

    private var photoStore: WiredTransferPhotoStore {
        WiredTransferPhotoStore(
            accountPrefixProvider: { accountContext.accountCachePrefix ?? "guest_" },
            userIDProvider: { accountContext.profile?.userId ?? "" }
        )
    }

    var body: some View {
        Group {
            if viewModel.isLoading, viewModel.album == nil {
                ProgressView()
                    .frame(maxWidth: .infinity, maxHeight: .infinity)
            } else if viewModel.album != nil {
                contentView
            } else {
                Text("加载失败")
                    .font(.system(size: 14))
                    .foregroundStyle(TravelAlbumDetailDesign.text333)
                    .frame(maxWidth: .infinity, maxHeight: .infinity)
            }
        }
        .background(TravelAlbumDetailDesign.pageBackground.ignoresSafeArea())
        .navigationTitle("相册管理")
        .navigationBarTitleDisplayMode(.inline)
        .toolbar {
            ToolbarItem(placement: .topBarTrailing) {
                Menu {
                    Button("删除相册", role: .destructive) {
                        viewModel.showDeleteAlbumConfirm = true
                    }
                } label: {
                    Image(systemName: "ellipsis")
                        .foregroundStyle(TravelAlbumDetailDesign.text333)
                }
                .accessibilityLabel("更多")
            }
        }
        .safeAreaInset(edge: .bottom) {
            bottomBar
        }
        .background(wiredTransferNavigationLink)
        .sheet(item: $previewPayload) { payload in
            WiredTransferPhotoPreviewSheet(
                imageSources: payload.sources,
                startIndex: payload.startIndex,
                onDismiss: { previewPayload = nil }
            )
        }
        .confirmationDialog("删除相册", isPresented: $viewModel.showDeleteAlbumConfirm, titleVisibility: .visible) {
            Button("删除", role: .destructive) {
                Task { await deleteAlbum() }
            }
            Button("取消", role: .cancel) {}
        } message: {
            Text("确定删除该相册吗？已有购买素材的相册无法删除。")
        }
        .confirmationDialog("删除素材", isPresented: $viewModel.showDeleteMaterialConfirm, titleVisibility: .visible) {
            Button("删除", role: .destructive) {
                Task { await deleteSelectedMaterials() }
            }
            Button("取消", role: .cancel) {}
        } message: {
            Text("确定删除选中的 \(viewModel.selectedMaterialIDs.count) 张素材吗？")
        }
        .task(id: albumID) {
            globalLoading.show()
            defer { globalLoading.hide() }
            await viewModel.refreshAll(api: travelAlbumAPI, albumID: albumID)
        }
        .onChange(of: navigateToWiredTransfer) { isActive in
            guard !isActive, didReturnFromWiredTransfer else { return }
            didReturnFromWiredTransfer = false
            Task { await viewModel.refreshAll(api: travelAlbumAPI, albumID: albumID) }
        }
        .onChange(of: viewModel.errorMessage) { message in
            guard let message, !message.isEmpty else { return }
            toastCenter.show(message)
            viewModel.errorMessage = nil
        }
    }

    private var contentView: some View {
        VStack(spacing: TravelAlbumDetailDesign.sectionSpacing) {
            if let album = viewModel.album {
                TravelAlbumDetailInfoCard(album: album) { phone in
                    dialPhone(phone)
                }
            }

            TravelAlbumDetailPhotoManageCard(
                materials: viewModel.materials,
                allPhotoCount: viewModel.allPhotoCount,
                selectedTab: viewModel.selectedTab,
                orderBy: viewModel.orderBy,
                isSelectionMode: viewModel.isSelectionMode,
                selectedMaterialIDs: viewModel.selectedMaterialIDs,
                onTabSelect: { tab in
                    Task { await viewModel.selectTab(tab, api: travelAlbumAPI) }
                },
                onOrderBySelect: { order in
                    Task { await viewModel.setOrderBy(order, api: travelAlbumAPI) }
                },
                onToggleSelectionMode: {
                    viewModel.toggleSelectionMode()
                },
                onMaterialClick: { material in
                    viewModel.toggleMaterialSelection(material)
                },
                onMaterialPreview: { material in
                    openMaterialPreview(material)
                },
                onLoadMore: { index in
                    Task { await viewModel.loadMoreIfNeeded(lastVisibleIndex: index, api: travelAlbumAPI) }
                }
            )
            .frame(maxHeight: .infinity)
        }
        .padding(.horizontal, TravelAlbumDetailDesign.contentHorizontalPadding)
        .padding(.top, 12)
        .padding(.bottom, 8)
        .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top)
    }

    private var bottomBar: some View {
        VStack(spacing: 8) {
            if viewModel.isSelectionMode, !viewModel.selectedMaterialIDs.isEmpty {
                Button {
                    viewModel.requestDeleteSelectedMaterials()
                } label: {
                    Text("删除选中(\(viewModel.selectedMaterialIDs.count))")
                        .font(.system(size: 16))
                        .foregroundStyle(.white)
                        .frame(maxWidth: .infinity)
                        .frame(height: TravelAlbumDetailDesign.bottomButtonHeight)
                        .background(TravelAlbumDetailDesign.deleteRed)
                        .clipShape(RoundedRectangle(cornerRadius: TravelAlbumDetailDesign.bottomButtonCornerRadius))
                }
                .buttonStyle(.plain)
            }

            Button {
                didReturnFromWiredTransfer = true
                navigateToWiredTransfer = true
            } label: {
                Text("上传照片")
                    .font(.system(size: 16, weight: .medium))
                    .foregroundStyle(.white)
                    .frame(maxWidth: .infinity)
                    .frame(height: TravelAlbumDetailDesign.bottomButtonHeight)
                    .background(AppDesign.primary)
                    .clipShape(RoundedRectangle(cornerRadius: TravelAlbumDetailDesign.bottomButtonCornerRadius))
            }
            .buttonStyle(.plain)
        }
        .padding(.horizontal, TravelAlbumDetailDesign.bottomBarHorizontalPadding)
        .padding(.vertical, TravelAlbumDetailDesign.bottomBarVerticalPadding)
        .background(TravelAlbumDetailDesign.pageBackground)
    }

    @ViewBuilder
    private var wiredTransferNavigationLink: some View {
        if let context = viewModel.wiredTransferContext() {
            NavigationLink(isActive: $navigateToWiredTransfer) {
                WiredCameraTransferView(context: context)
            } label: {
                EmptyView()
            }
            .hidden()
        }
    }

    /// 拨打客户电话。
    private func dialPhone(_ phone: String) {
        let trimmed = phone.trimmingCharacters(in: .whitespacesAndNewlines)
        guard !trimmed.isEmpty, let url = URL(string: "tel:\(trimmed)") else { return }
        openURL(url)
    }

    /// 打开素材大图预览，支持左右滑动浏览当前列表。
    private func openMaterialPreview(_ material: TravelAlbumMaterial) {
        let previewMaterials = viewModel.materials.filter { !$0.previewURLString.isEmpty }
        guard !material.previewURLString.isEmpty else {
            toastCenter.show("暂无法预览该照片")
            return
        }
        let sources = previewMaterials.map(\.previewURLString)
        let startIndex = previewMaterials.firstIndex(where: { $0.id == material.id }) ?? 0
        previewPayload = TravelAlbumMaterialPreviewPayload(sources: sources, startIndex: startIndex)
    }

    private func deleteAlbum() async {
        globalLoading.show()
        defer { globalLoading.hide() }
        let success = await viewModel.deleteAlbum(api: travelAlbumAPI, albumID: albumID, photoStore: photoStore)
        if success {
            toastCenter.show("相册已删除")
            dismiss()
        }
    }

    private func deleteSelectedMaterials() async {
        globalLoading.show()
        defer { globalLoading.hide() }
        let success = await viewModel.confirmDeleteSelectedMaterials(api: travelAlbumAPI)
        if success {
            toastCenter.show("删除成功")
        }
    }
}

/// 旅拍相册素材预览 Sheet 载荷。
private struct TravelAlbumMaterialPreviewPayload: Identifiable {
    let id = UUID()
    let sources: [String]
    let startIndex: Int
}
