//
//  ProjectViews.swift
//  suixinkan
//
//  Created by Codex on 2026/6/24.
//

import PhotosUI
import SwiftUI
import UniformTypeIdentifiers

/// 摄影师项目管理页面，展示项目列表并提供新建、详情和删除入口。
struct ProjectManagementView: View {
    @EnvironmentObject private var accountContext: AccountContext
    @Environment(\.accountSnapshotStore) private var snapshotStore
    @Environment(\.projectAPI) private var projectAPI
    @Environment(\.globalLoading) private var globalLoading
    @StateObject private var viewModel = ProjectManagementViewModel()

    var body: some View {
        VStack(spacing: 0) {
            filterBar
            if accountContext.currentScenic?.id == nil {
                AppContentUnavailableView("缺少景区", systemImage: "map", description: Text("请选择景区后再管理项目。"))
                    .frame(maxWidth: .infinity, maxHeight: .infinity)
            } else {
                projectList
            }
        }
        .navigationTitle("项目管理")
        .navigationBarTitleDisplayMode(.inline)
        .toolbar {
            ToolbarItem(placement: .topBarTrailing) {
                NavigationLink(value: HomeRoute.projectEditor(id: nil, storeMode: false)) {
                    Image(systemName: "plus")
                }
                .accessibilityLabel("新建项目")
            }
        }
        .task(id: accountContext.currentScenic?.id) {
            await reload(showLoading: true)
        }
    }

    private var filterBar: some View {
        HStack(spacing: AppMetrics.Spacing.small) {
            Image(systemName: "magnifyingglass")
                .foregroundStyle(AppDesign.textSecondary)
            TextField("搜索项目名称", text: $viewModel.searchText)
                .textInputAutocapitalization(.never)
                .autocorrectionDisabled(true)
                .submitLabel(.search)
                .onSubmit { Task { await reload(showLoading: true) } }
            Button("搜索") {
                Task { await reload(showLoading: true) }
            }
            .font(.system(size: AppMetrics.FontSize.subheadline, weight: .semibold))
            .foregroundStyle(AppDesign.primary)
        }
        .padding(.horizontal, AppMetrics.Spacing.medium)
        .frame(height: 52)
        .background(.white)
    }

    private var projectList: some View {
        ScrollView {
            LazyVStack(spacing: AppMetrics.Spacing.medium) {
                if viewModel.items.isEmpty && !viewModel.loading {
                    AppContentUnavailableView("暂无项目", systemImage: "folder", description: Text("可点击右上角创建项目。"))
                        .frame(maxWidth: .infinity, minHeight: 260)
                }
                ForEach(viewModel.items) { item in
                    NavigationLink(value: HomeRoute.projectDetail(id: item.id, storeMode: false)) {
                        ProjectCardView(item: item)
                    }
                    .buttonStyle(.plain)
                    .contextMenu {
                        Button(role: .destructive) {
                            Task { await viewModel.delete(id: item.id, api: projectAPI) }
                        } label: {
                            Label("删除", systemImage: "trash")
                        }
                    }
                }
                if viewModel.hasMore {
                    ProgressView()
                        .padding(.vertical, AppMetrics.Spacing.medium)
                        .onAppear {
                            Task { await viewModel.loadMore(api: projectAPI, scenicId: accountContext.currentScenic?.id) }
                        }
                } else if !viewModel.items.isEmpty {
                    Text("没有更多")
                        .font(.system(size: AppMetrics.FontSize.caption))
                        .foregroundStyle(AppDesign.textSecondary)
                        .padding(.vertical, AppMetrics.Spacing.medium)
                }
            }
            .padding(AppMetrics.Spacing.medium)
        }
        .background(Color(hex: 0xF5F7FA))
        .refreshable { await reload(showLoading: false) }
    }

    private func reload(showLoading: Bool) async {
        await globalLoading.withOptionalLoading(showLoading && accountContext.currentScenic?.id != nil) {
            await viewModel.reload(api: projectAPI, scenicId: accountContext.currentScenic?.id)
        }
    }
}

/// 店铺项目管理页面，展示店铺项目列表、筛选和新建入口。
struct StoreProjectManagementView: View {
    @Environment(\.accountSnapshotStore) private var snapshotStore
    @Environment(\.projectAPI) private var projectAPI
    @Environment(\.globalLoading) private var globalLoading
    @StateObject private var viewModel = StoreProjectManagementViewModel()

    var body: some View {
        ScrollView {
            VStack(spacing: AppMetrics.Spacing.medium) {
                storeFilterCard
                storeSummaryCard
                ForEach(viewModel.filteredItems) { item in
                    NavigationLink(value: HomeRoute.projectDetail(id: item.id, storeMode: true)) {
                        ProjectCompactCardView(item: item)
                    }
                    .buttonStyle(.plain)
                }
                if viewModel.filteredItems.isEmpty && !viewModel.loading {
                    AppContentUnavailableView("暂无店铺项目", systemImage: "folder", description: Text("可点击右上角新建店铺项目。"))
                        .frame(minHeight: 260)
                }
            }
            .padding(AppMetrics.Spacing.medium)
        }
        .background(Color(hex: 0xF5F7FA))
        .navigationTitle("店铺项目管理")
        .navigationBarTitleDisplayMode(.inline)
        .toolbar {
            ToolbarItem(placement: .topBarTrailing) {
                NavigationLink(value: HomeRoute.projectEditor(id: nil, storeMode: true)) {
                    Image(systemName: "plus")
                }
                .accessibilityLabel("新建店铺项目")
            }
        }
        .task { await reload(showLoading: true) }
        .refreshable { await reload(showLoading: false) }
    }

    private var storeFilterCard: some View {
        VStack(spacing: AppMetrics.Spacing.small) {
            Picker("项目类型", selection: $viewModel.selectedType) {
                Text("全部").tag(0)
                Text("多点位").tag(19)
                Text("押金").tag(4)
            }
            .pickerStyle(.segmented)
            TextField("搜索项目名称", text: $viewModel.searchText)
                .textInputAutocapitalization(.never)
                .autocorrectionDisabled(true)
                .appInputFieldStyle(cornerRadius: AppMetrics.CornerRadius.input, minHeight: AppMetrics.ControlSize.inputHeight)
        }
        .padding(AppMetrics.Spacing.medium)
        .background(.white, in: RoundedRectangle(cornerRadius: AppMetrics.CornerRadius.card))
    }

    private var storeSummaryCard: some View {
        HStack(spacing: AppMetrics.Spacing.small) {
            stat("总数", "\(viewModel.filteredItems.count)")
            stat("启用", "\(viewModel.filteredItems.filter { $0.status == 1 }.count)")
            stat("押金", "\(viewModel.filteredItems.filter { $0.type == 4 }.count)")
        }
    }

    private func stat(_ title: String, _ value: String) -> some View {
        VStack(alignment: .leading, spacing: 4) {
            Text(title)
                .font(.system(size: AppMetrics.FontSize.caption))
                .foregroundStyle(AppDesign.textSecondary)
            Text(value)
                .font(.system(size: AppMetrics.FontSize.body, weight: .semibold))
                .foregroundStyle(AppDesign.textPrimary)
        }
        .frame(maxWidth: .infinity, alignment: .leading)
        .padding(AppMetrics.Spacing.small)
        .background(.white, in: RoundedRectangle(cornerRadius: AppMetrics.CornerRadius.card))
    }

    private func reload(showLoading: Bool) async {
        await globalLoading.withOptionalLoading(showLoading) {
            await viewModel.reload(api: projectAPI, userId: snapshotStore.load()?.profile?.userId ?? snapshotStore.load()?.businessUserId.map(String.init))
        }
    }
}

/// 项目详情页面，展示项目基础信息、媒体、打卡点和摄影师摘要。
struct ProjectDetailView: View {
    @Environment(\.projectAPI) private var projectAPI
    @Environment(\.globalLoading) private var globalLoading
    let projectId: Int
    let storeMode: Bool
    @State private var detail: PhotographerProjectDetailResponse?
    @State private var errorMessage: String?

    var body: some View {
        ScrollView {
            VStack(spacing: AppMetrics.Spacing.medium) {
                if let detail {
                    ProjectDetailContentView(detail: detail)
                } else if let errorMessage {
                    AppContentUnavailableView("加载失败", systemImage: "exclamationmark.triangle", description: Text(errorMessage))
                        .frame(minHeight: 360)
                } else {
                    ProgressView()
                        .frame(maxWidth: .infinity, minHeight: 360)
                }
            }
            .padding(AppMetrics.Spacing.medium)
        }
        .background(Color(hex: 0xF5F7FA))
        .navigationTitle("项目详情")
        .navigationBarTitleDisplayMode(.inline)
        .toolbar {
            if detail != nil {
                ToolbarItem(placement: .topBarTrailing) {
                    NavigationLink(value: HomeRoute.projectEditor(id: projectId, storeMode: storeMode)) {
                        Text("编辑")
                    }
                }
            }
        }
        .task { await load() }
    }

    private func load() async {
        await globalLoading.withLoading {
            do {
                detail = storeMode ? try await projectAPI.storeManagerProjectDetail(id: projectId) : try await projectAPI.projectDetail(id: projectId)
            } catch {
                errorMessage = error.localizedDescription
            }
        }
    }
}

/// 摄影师项目编辑页面，支持新建和编辑项目。
struct ProjectEditorView: View {
    @Environment(\.dismiss) private var dismiss
    @EnvironmentObject private var accountContext: AccountContext
    @Environment(\.accountSnapshotStore) private var snapshotStore
    @EnvironmentObject private var scenicSpotContext: ScenicSpotContext
    @Environment(\.projectAPI) private var projectAPI
    @Environment(\.ossUploadService) private var uploadService
    @Environment(\.globalLoading) private var globalLoading
    let projectId: Int?
    @StateObject private var viewModel = ProjectEditorViewModel(mode: .create)
    @State private var coverItem: PhotosPickerItem?
    @State private var carouselItems: [PhotosPickerItem] = []
    @State private var loadingDetail = false

    var body: some View {
        ScrollView {
            VStack(spacing: AppMetrics.Spacing.medium) {
                basicForm
                projectImageForm
                countForm
                spotForm
                if let error = viewModel.errorMessage {
                    Text(error)
                        .font(.system(size: AppMetrics.FontSize.caption))
                        .foregroundStyle(Color(hex: 0xE5484D))
                        .frame(maxWidth: .infinity, alignment: .leading)
                        .padding(AppMetrics.Spacing.medium)
                        .background(Color(hex: 0xE5484D).opacity(0.1), in: RoundedRectangle(cornerRadius: AppMetrics.CornerRadius.card))
                }
            }
            .padding(AppMetrics.Spacing.medium)
        }
        .background(Color(hex: 0xF5F7FA))
        .navigationTitle(projectId == nil ? "新建项目" : "编辑项目")
        .navigationBarTitleDisplayMode(.inline)
        .toolbar {
            ToolbarItem(placement: .topBarTrailing) {
                Button(viewModel.submitting ? "保存中..." : "保存") {
                    Task { await submit() }
                }
                .disabled(viewModel.submitting || loadingDetail)
            }
        }
        .task {
            await prepare()
        }
        .onChange(of: coverItem) { newValue in
            Task { await loadCover(newValue) }
        }
        .onChange(of: carouselItems) { newValue in
            Task { await loadCarousel(newValue) }
        }
    }

    private var basicForm: some View {
        ProjectFormCard(title: "基础信息") {
            TextField("项目名称", text: $viewModel.name)
                .appInputFieldStyle(cornerRadius: AppMetrics.CornerRadius.input, minHeight: AppMetrics.ControlSize.inputHeight)
            TextField("项目简介", text: $viewModel.descriptionText, axis: .vertical)
                .lineLimit(3...5)
                .appInputFieldStyle(cornerRadius: AppMetrics.CornerRadius.input, minHeight: 96)
            HStack(spacing: AppMetrics.Spacing.small) {
                TextField("优惠价", text: $viewModel.price)
                    .keyboardType(.decimalPad)
                    .appInputFieldStyle(cornerRadius: AppMetrics.CornerRadius.input, minHeight: AppMetrics.ControlSize.inputHeight)
                TextField("原价", text: $viewModel.otPrice)
                    .keyboardType(.decimalPad)
                    .appInputFieldStyle(cornerRadius: AppMetrics.CornerRadius.input, minHeight: AppMetrics.ControlSize.inputHeight)
            }
            TextField("押金", text: $viewModel.deposit)
                .keyboardType(.decimalPad)
                .appInputFieldStyle(cornerRadius: AppMetrics.CornerRadius.input, minHeight: AppMetrics.ControlSize.inputHeight)
            TextField("标签，多个用逗号分隔", text: $viewModel.attrLabelText)
                .appInputFieldStyle(cornerRadius: AppMetrics.CornerRadius.input, minHeight: AppMetrics.ControlSize.inputHeight)
        }
    }

    private var projectImageForm: some View {
        ProjectFormCard(title: "项目图片") {
            PhotosPicker(selection: $coverItem, matching: .images) {
                ProjectImagePickerLabel(title: "项目封面", url: viewModel.coverImage?.previewURL ?? viewModel.existingCoverURL)
            }
            PhotosPicker(selection: $carouselItems, maxSelectionCount: 8, matching: .images) {
                Label("选择轮播图（\(viewModel.carouselImages.count + viewModel.existingCarouselURLs.count)）", systemImage: "photo.stack")
                    .frame(maxWidth: .infinity)
                    .frame(height: 44)
                    .background(AppDesign.primarySoft, in: RoundedRectangle(cornerRadius: AppMetrics.CornerRadius.input))
            }
            .buttonStyle(.plain)
        }
    }

    private var countForm: some View {
        ProjectFormCard(title: "交付数量") {
            HStack(spacing: AppMetrics.Spacing.small) {
                TextField("底片", text: $viewModel.materialNum)
                TextField("精修", text: $viewModel.photoNum)
                TextField("视频", text: $viewModel.videoNum)
            }
            .keyboardType(.numberPad)
            .textFieldStyle(.roundedBorder)
        }
    }

    private var spotForm: some View {
        ProjectFormCard(title: "打卡点") {
            if scenicSpotContext.spots.isEmpty {
                Text("暂无打卡点数据")
                    .font(.system(size: AppMetrics.FontSize.caption))
                    .foregroundStyle(AppDesign.textSecondary)
            } else {
                ForEach(scenicSpotContext.spots) { spot in
                    Button {
                        if viewModel.selectedSpotIds.contains(spot.id) {
                            viewModel.selectedSpotIds.remove(spot.id)
                        } else {
                            viewModel.selectedSpotIds.insert(spot.id)
                        }
                    } label: {
                        HStack {
                            Text(spot.name)
                            Spacer()
                            Image(systemName: viewModel.selectedSpotIds.contains(spot.id) ? "checkmark.circle.fill" : "circle")
                                .foregroundStyle(viewModel.selectedSpotIds.contains(spot.id) ? AppDesign.primary : AppDesign.textSecondary)
                        }
                        .font(.system(size: AppMetrics.FontSize.subheadline))
                        .foregroundStyle(AppDesign.textPrimary)
                        .padding(AppMetrics.Spacing.small)
                        .background(Color(hex: 0xF8FAFC), in: RoundedRectangle(cornerRadius: AppMetrics.CornerRadius.input))
                    }
                    .buttonStyle(.plain)
                }
            }
        }
    }

    private func prepare() async {
        guard let projectId else { return }
        loadingDetail = true
        defer { loadingDetail = false }
        do {
            let detail = try await projectAPI.projectDetail(id: projectId)
            viewModel.apply(detail)
        } catch {
            viewModel.errorMessage = error.localizedDescription
        }
    }

    private func submit() async {
        await globalLoading.withLoading {
            let success = await viewModel.submit(
                scenicId: accountContext.currentScenic?.id,
                userId: snapshotStore.load()?.businessUserId ?? Int(snapshotStore.load()?.profile?.userId ?? ""),
                api: projectAPI,
                uploadService: uploadService
            )
            if success { dismiss() }
        }
    }

    private func loadCover(_ item: PhotosPickerItem?) async {
        guard let file = await ProjectPickerLoader.loadImage(from: item) else { return }
        viewModel.coverImage = file
    }

    private func loadCarousel(_ items: [PhotosPickerItem]) async {
        viewModel.carouselImages = await ProjectPickerLoader.loadImages(from: items)
    }
}

/// 店铺项目编辑页面，支持新建和编辑店铺项目。
struct StoreProjectEditorView: View {
    @Environment(\.dismiss) private var dismiss
    @Environment(\.accountSnapshotStore) private var snapshotStore
    @Environment(\.projectAPI) private var projectAPI
    @Environment(\.ossUploadService) private var uploadService
    @Environment(\.globalLoading) private var globalLoading
    let projectId: Int?
    @StateObject private var viewModel = StoreProjectEditorViewModel(mode: .create)
    @State private var coverItem: PhotosPickerItem?
    @State private var carouselItems: [PhotosPickerItem] = []

    var body: some View {
        ScrollView {
            VStack(spacing: AppMetrics.Spacing.medium) {
                storeBasicForm
                storeImageForm
                storeScenicForm
                storePriceForm
                if let error = viewModel.errorMessage {
                    Text(error)
                        .font(.system(size: AppMetrics.FontSize.caption))
                        .foregroundStyle(Color(hex: 0xE5484D))
                }
            }
            .padding(AppMetrics.Spacing.medium)
        }
        .background(Color(hex: 0xF5F7FA))
        .navigationTitle(projectId == nil ? "新建店铺项目" : "编辑店铺项目")
        .navigationBarTitleDisplayMode(.inline)
        .toolbar {
            ToolbarItem(placement: .topBarTrailing) {
                Button(viewModel.submitting ? "保存中..." : "保存") {
                    Task { await submit() }
                }
                .disabled(viewModel.submitting)
            }
        }
        .task { await prepare() }
        .onChange(of: coverItem) { newValue in
            Task { viewModel.coverImage = await ProjectPickerLoader.loadImage(from: newValue) }
        }
        .onChange(of: carouselItems) { newValue in
            Task { viewModel.carouselImages = await ProjectPickerLoader.loadImages(from: newValue) }
        }
    }

    private var storeBasicForm: some View {
        ProjectFormCard(title: "基础信息") {
            Picker("类型", selection: $viewModel.projectType) {
                Text("多点位").tag(19)
                Text("押金").tag(4)
            }
            .pickerStyle(.segmented)
            TextField("项目名称", text: $viewModel.name)
                .appInputFieldStyle(cornerRadius: AppMetrics.CornerRadius.input, minHeight: AppMetrics.ControlSize.inputHeight)
            TextField("项目简介", text: $viewModel.descriptionText, axis: .vertical)
                .lineLimit(3...5)
                .appInputFieldStyle(cornerRadius: AppMetrics.CornerRadius.input, minHeight: 96)
        }
    }

    private var storeImageForm: some View {
        ProjectFormCard(title: "项目图片") {
            PhotosPicker(selection: $coverItem, matching: .images) {
                ProjectImagePickerLabel(title: "项目封面", url: viewModel.coverImage?.previewURL ?? viewModel.existingCoverURL)
            }
            PhotosPicker(selection: $carouselItems, maxSelectionCount: 8, matching: .images) {
                Label("选择轮播图（\(viewModel.carouselImages.count + viewModel.existingCarouselURLs.count)）", systemImage: "photo.stack")
                    .frame(maxWidth: .infinity)
                    .frame(height: 44)
                    .background(AppDesign.primarySoft, in: RoundedRectangle(cornerRadius: AppMetrics.CornerRadius.input))
            }
            .buttonStyle(.plain)
        }
    }

    private var storeScenicForm: some View {
        ProjectFormCard(title: viewModel.projectType == 4 ? "景区与门店" : "景区") {
            ForEach(viewModel.scenicList) { scenic in
                Button {
                    viewModel.toggleScenic(scenic.id)
                    Task { await viewModel.loadStoreList(api: projectAPI) }
                } label: {
                    HStack {
                        Text(scenic.name)
                        Spacer()
                        Image(systemName: viewModel.selectedScenicIds.contains(scenic.id) ? "checkmark.circle.fill" : "circle")
                    }
                    .foregroundStyle(viewModel.selectedScenicIds.contains(scenic.id) ? AppDesign.primary : AppDesign.textPrimary)
                }
                .buttonStyle(.plain)
            }
            if viewModel.projectType == 4 {
                Picker("门店", selection: Binding(get: { viewModel.selectedStoreId ?? 0 }, set: { viewModel.selectedStoreId = $0 == 0 ? nil : $0 })) {
                    Text("请选择").tag(0)
                    ForEach(viewModel.storeList) { store in
                        Text(store.name).tag(store.id)
                    }
                }
            }
        }
    }

    private var storePriceForm: some View {
        ProjectFormCard(title: "价格与数量") {
            if viewModel.projectType == 4 {
                TextField("押金金额", text: $viewModel.priceDeposit)
                    .keyboardType(.decimalPad)
                    .appInputFieldStyle(cornerRadius: AppMetrics.CornerRadius.input, minHeight: AppMetrics.ControlSize.inputHeight)
            } else {
                TextField("项目价格", text: $viewModel.projectPrice)
                    .keyboardType(.decimalPad)
                    .appInputFieldStyle(cornerRadius: AppMetrics.CornerRadius.input, minHeight: AppMetrics.ControlSize.inputHeight)
                HStack {
                    TextField("底片价", text: $viewModel.priceMaterial)
                    TextField("精修价", text: $viewModel.pricePhoto)
                    TextField("视频价", text: $viewModel.priceVideo)
                }
                .keyboardType(.decimalPad)
                .textFieldStyle(.roundedBorder)
            }
        }
    }

    private func prepare() async {
        let userId = snapshotStore.load()?.businessUserId ?? Int(snapshotStore.load()?.profile?.userId ?? "") ?? 0
        if let projectId {
            do {
                let detail = try await projectAPI.storeManagerProjectDetail(id: projectId)
                viewModel.apply(detail)
            } catch {
                viewModel.errorMessage = error.localizedDescription
            }
        }
        await viewModel.loadScenicList(api: projectAPI, userId: userId)
        await viewModel.loadStoreList(api: projectAPI)
    }

    private func submit() async {
        let userId = snapshotStore.load()?.businessUserId ?? Int(snapshotStore.load()?.profile?.userId ?? "") ?? 0
        await globalLoading.withLoading {
            let success = await viewModel.submit(userId: userId, api: projectAPI, uploadService: uploadService)
            if success { dismiss() }
        }
    }
}

/// 项目卡片视图，展示封面、名称、状态和价格。
private struct ProjectCardView: View {
    let item: PhotographerProjectItem

    var body: some View {
        VStack(alignment: .leading, spacing: 0) {
            RemoteImage(urlString: item.coverProject.isEmpty ? item.coverVideo : item.coverProject, contentMode: .fill) {
                Image(systemName: "photo")
                    .font(.system(size: 30))
                    .foregroundStyle(AppDesign.primary)
            }
            .frame(height: 180)
            .clipped()
            VStack(alignment: .leading, spacing: AppMetrics.Spacing.small) {
                HStack {
                    Text(item.name.isEmpty ? "未命名项目" : item.name)
                        .font(.system(size: AppMetrics.FontSize.body, weight: .semibold))
                        .foregroundStyle(AppDesign.textPrimary)
                    Spacer()
                    Text(item.statusName.isEmpty ? "状态\(item.status)" : item.statusName)
                        .font(.system(size: AppMetrics.FontSize.caption))
                        .foregroundStyle(AppDesign.primary)
                }
                Text("¥\(item.price.isEmpty ? "0.00" : item.price)")
                    .font(.system(size: AppMetrics.FontSize.title3, weight: .bold))
                    .foregroundStyle(AppDesign.textPrimary)
            }
            .padding(AppMetrics.Spacing.medium)
        }
        .background(.white, in: RoundedRectangle(cornerRadius: AppMetrics.CornerRadius.card))
        .clipShape(RoundedRectangle(cornerRadius: AppMetrics.CornerRadius.card))
    }
}

/// 紧凑项目卡片视图，展示店铺项目摘要。
private struct ProjectCompactCardView: View {
    let item: PhotographerProjectItem

    var body: some View {
        HStack(spacing: AppMetrics.Spacing.medium) {
            RemoteImage(urlString: item.coverProject.isEmpty ? item.coverVideo : item.coverProject, contentMode: .fill) {
                Image(systemName: "photo")
                    .foregroundStyle(AppDesign.primary)
            }
            .frame(width: 76, height: 76)
            .clipShape(RoundedRectangle(cornerRadius: AppMetrics.CornerRadius.input))
            VStack(alignment: .leading, spacing: 6) {
                Text(item.name.isEmpty ? "未命名项目" : item.name)
                    .font(.system(size: AppMetrics.FontSize.body, weight: .semibold))
                    .foregroundStyle(AppDesign.textPrimary)
                Text(item.typeName.isEmpty ? "类型\(item.type)" : item.typeName)
                    .font(.system(size: AppMetrics.FontSize.caption))
                    .foregroundStyle(AppDesign.textSecondary)
                Text("¥\(item.price.isEmpty ? item.priceDeposit : item.price)")
                    .font(.system(size: AppMetrics.FontSize.subheadline, weight: .semibold))
                    .foregroundStyle(AppDesign.primary)
            }
            Spacer()
        }
        .padding(AppMetrics.Spacing.medium)
        .background(.white, in: RoundedRectangle(cornerRadius: AppMetrics.CornerRadius.card))
    }
}

/// 项目详情内容视图。
private struct ProjectDetailContentView: View {
    let detail: PhotographerProjectDetailResponse

    var body: some View {
        VStack(spacing: AppMetrics.Spacing.medium) {
            ProjectCardView(item: detail.asListItem)
            ProjectFormCard(title: "服务内容") {
                HStack {
                    service("底片", "\(detail.materialNum)")
                    service("精修", "\(detail.photoNum)")
                    service("视频", "\(detail.videoNum)")
                }
            }
            ProjectFormCard(title: "基础信息") {
                row("项目类型", detail.typeName)
                row("状态", detail.statusName)
                row("创建人", detail.creatorName)
                row("简介", detail.description)
                if !detail.auditRemark.isEmpty {
                    row("审核备注", detail.auditRemark)
                }
            }
            if !detail.scenicList.isEmpty {
                ProjectFormCard(title: "打卡点") {
                    Text(detail.scenicList.map(\.name).joined(separator: "、"))
                        .font(.system(size: AppMetrics.FontSize.subheadline))
                        .foregroundStyle(AppDesign.textPrimary)
                }
            }
        }
    }

    private func service(_ title: String, _ value: String) -> some View {
        VStack(spacing: 4) {
            Text(value)
                .font(.system(size: AppMetrics.FontSize.title3, weight: .bold))
                .foregroundStyle(AppDesign.primary)
            Text(title)
                .font(.system(size: AppMetrics.FontSize.caption))
                .foregroundStyle(AppDesign.textSecondary)
        }
        .frame(maxWidth: .infinity)
    }

    private func row(_ title: String, _ value: String) -> some View {
        HStack(alignment: .top) {
            Text(title)
                .foregroundStyle(AppDesign.textSecondary)
            Spacer()
            Text(value.isEmpty ? "--" : value)
                .multilineTextAlignment(.trailing)
                .foregroundStyle(AppDesign.textPrimary)
        }
        .font(.system(size: AppMetrics.FontSize.subheadline))
    }
}

/// 项目表单通用卡片。
private struct ProjectFormCard<Content: View>: View {
    let title: String
    @ViewBuilder let content: () -> Content

    var body: some View {
        VStack(alignment: .leading, spacing: AppMetrics.Spacing.small) {
            Text(title)
                .font(.system(size: AppMetrics.FontSize.body, weight: .semibold))
                .foregroundStyle(AppDesign.textPrimary)
            content()
        }
        .padding(AppMetrics.Spacing.medium)
        .background(.white, in: RoundedRectangle(cornerRadius: AppMetrics.CornerRadius.card))
    }
}

/// 项目图片选择标签。
private struct ProjectImagePickerLabel: View {
    let title: String
    let url: String

    var body: some View {
        ZStack {
            RemoteImage(urlString: url, contentMode: .fill) {
                VStack(spacing: 8) {
                    Image(systemName: "photo.badge.plus")
                    Text(title)
                }
                .foregroundStyle(AppDesign.primary)
            }
        }
        .frame(maxWidth: .infinity)
        .frame(height: 160)
        .background(AppDesign.primarySoft, in: RoundedRectangle(cornerRadius: AppMetrics.CornerRadius.input))
        .clipShape(RoundedRectangle(cornerRadius: AppMetrics.CornerRadius.input))
    }
}

/// PhotosPicker 项目图片加载器。
private enum ProjectPickerLoader {
    /// 从单个 PhotosPickerItem 读取项目图片。
    static func loadImage(from item: PhotosPickerItem?) async -> ProjectLocalImage? {
        guard let item, let data = try? await item.loadTransferable(type: Data.self) else { return nil }
        let fileName = fileName(for: item)
        return ProjectLocalImage(data: data, fileName: fileName, previewURL: dataURL(data: data, fileName: fileName))
    }

    /// 从多个 PhotosPickerItem 读取项目图片。
    static func loadImages(from items: [PhotosPickerItem]) async -> [ProjectLocalImage] {
        var result: [ProjectLocalImage] = []
        for item in items {
            if let image = await loadImage(from: item) {
                result.append(image)
            }
        }
        return result
    }

    private static func fileName(for item: PhotosPickerItem) -> String {
        let ext = item.supportedContentTypes.first?.preferredFilenameExtension ?? "jpg"
        return "project_\(UUID().uuidString).\(ext)"
    }

    private static func dataURL(data: Data, fileName: String) -> String? {
        let mime = UTType(filenameExtension: URL(fileURLWithPath: fileName).pathExtension)?.preferredMIMEType ?? "image/jpeg"
        return "data:\(mime);base64,\(data.base64EncodedString())"
    }
}

private extension PhotographerProjectDetailResponse {
    /// 将详情转换为列表卡片展示项。
    var asListItem: PhotographerProjectItem {
        PhotographerProjectItem(
            id: id,
            type: type,
            typeName: typeName,
            status: status,
            statusName: statusName,
            name: name,
            coverProject: coverProject,
            coverVideo: cover,
            price: price,
            otPrice: otPrice,
            priceDeposit: priceDeposit,
            attrLabel: attrLabel
        )
    }
}
