//
//  ScenicApplicationView.swift
//  suixinkan
//
//  Created by Codex on 2026/6/23.
//

import PhotosUI
import SwiftUI

/// 景区申请页面，支持新增景区入驻资料、图片上传和审核状态回填。
struct ScenicApplicationView: View {
    @Environment(ScenicPermissionAPI.self) private var scenicPermissionAPI
    @Environment(OSSUploadService.self) private var ossUploadService
    @State private var viewModel = ScenicApplicationViewModel()
    @State private var pickedImageItems: [PhotosPickerItem] = []
    @State private var activeLocationPicker: ScenicLocationPicker?

    var body: some View {
        VStack(spacing: 0) {
            ScrollView {
                VStack(spacing: AppMetrics.Spacing.medium) {
                    if viewModel.loadFailed {
                        ContentUnavailableView(
                            "景区申请初始化失败",
                            systemImage: "exclamationmark.triangle",
                            description: Text(viewModel.loadFailureReason ?? "请检查网络后重试")
                        )
                        Button("重新加载") {
                            Task { await viewModel.loadInitial(api: scenicPermissionAPI) }
                        }
                        .font(.system(size: AppMetrics.FontSize.footnote, weight: .semibold))
                        .buttonStyle(.plain)
                    } else {
                        warmTip
                        formSection
                    }
                }
                .padding(AppMetrics.Spacing.medium)
            }
            if !viewModel.loadFailed {
                agreementSection
            }
        }
        .background(Color(hex: 0xF4F4F4).ignoresSafeArea())
        .navigationTitle("景区申请")
        .navigationBarTitleDisplayMode(.inline)
        .task {
            await viewModel.loadInitial(api: scenicPermissionAPI)
        }
        .onChange(of: pickedImageItems) { _, items in
            guard !items.isEmpty else { return }
            Task {
                await importPickedImages(items)
                pickedImageItems = []
            }
        }
        .sheet(item: $activeLocationPicker) { picker in
            ScenicLocationSelectionSheet(
                picker: picker,
                provinces: viewModel.provinces,
                cities: viewModel.cities,
                selectedProvince: viewModel.selectedProvince,
                selectedCity: viewModel.selectedCity,
                onSelectProvince: { item in
                    viewModel.selectedProvince = item.name
                    viewModel.onProvinceChange()
                    activeLocationPicker = nil
                },
                onSelectCity: { item in
                    viewModel.selectedCity = item.name
                    activeLocationPicker = nil
                }
            )
            .presentationDetents([.medium, .large])
        }
        .alert("提示", isPresented: Binding(
            get: { viewModel.message != nil },
            set: { if !$0 { viewModel.message = nil } }
        )) {
            Button("知道了", role: .cancel) {}
        } message: {
            Text(viewModel.message ?? "")
        }
    }

    private var warmTip: some View {
        VStack(alignment: .leading, spacing: AppMetrics.Spacing.xSmall) {
            Text("温馨提示")
                .font(.system(size: AppMetrics.FontSize.body, weight: .bold))
            Text("如果你想入驻更多的景区，平台可以帮你跟景区官方谈合作；如果已经有的景区，只要符合入驻条件即可申请。")
                .font(.system(size: AppMetrics.FontSize.subheadline))
                .lineSpacing(AppMetrics.LineSpacing.title)
        }
        .foregroundStyle(.white)
        .frame(maxWidth: .infinity, alignment: .leading)
        .padding(AppMetrics.Spacing.medium)
        .background(AppDesign.primary, in: RoundedRectangle(cornerRadius: 8))
    }

    private var formSection: some View {
        VStack(alignment: .leading, spacing: AppMetrics.Spacing.large) {
            if let pending = viewModel.pending {
                pendingStatusCard(pending)
            }
            if viewModel.pendingLoadFailed && viewModel.pending == nil {
                pendingFailureRow
            }
            inputField("景区名称", text: $viewModel.scenicName, disabled: viewModel.isReadOnly)
            uploadSection
            locationSection
            coopTypeSection
            inputField("备注信息 (\(viewModel.remark.count)/50)", text: $viewModel.remark, axis: .vertical, disabled: viewModel.isReadOnly)
                .onChange(of: viewModel.remark) { _, value in
                    if value.count > 50 {
                        viewModel.remark = String(value.prefix(50))
                    }
                }
            if let pending = viewModel.pending, pending.status == 3 {
                Text("驳回原因：\(pending.auditNote ?? pending.rejectReason ?? "--")")
                    .font(.system(size: AppMetrics.FontSize.caption))
                    .foregroundStyle(Color(hex: 0xDC2626))
                    .frame(maxWidth: .infinity, alignment: .leading)
                    .padding(AppMetrics.Spacing.small)
                    .background(Color(hex: 0xFEF2F2), in: RoundedRectangle(cornerRadius: 8))
            }
        }
        .padding(AppMetrics.Spacing.medium)
        .background(.white, in: RoundedRectangle(cornerRadius: 8))
    }

    private var pendingFailureRow: some View {
        HStack(spacing: AppMetrics.Spacing.xSmall) {
            Image(systemName: "exclamationmark.triangle")
                .foregroundStyle(AppDesign.warning)
            Text("待审核记录加载失败，暂未展示历史申请状态")
                .font(.system(size: AppMetrics.FontSize.caption))
                .foregroundStyle(AppDesign.textSecondary)
            Spacer()
            Button("重试") {
                Task { await viewModel.reloadPending(api: scenicPermissionAPI) }
            }
            .font(.system(size: AppMetrics.FontSize.caption, weight: .semibold))
            .buttonStyle(.plain)
        }
        .padding(AppMetrics.Spacing.small)
        .background(Color(hex: 0xFFF7ED), in: RoundedRectangle(cornerRadius: 8))
    }

    private var uploadSection: some View {
        VStack(alignment: .leading, spacing: AppMetrics.Spacing.xSmall) {
            HStack {
                Text("景区图片")
                    .font(.system(size: AppMetrics.FontSize.body, weight: .medium))
                Spacer()
                Text("\(viewModel.uploadPlaceholderCount)/20")
                    .font(.system(size: AppMetrics.FontSize.caption, weight: .medium))
                    .foregroundStyle(AppDesign.textSecondary)
            }
            LazyVGrid(columns: [GridItem(.adaptive(minimum: 92), spacing: AppMetrics.Spacing.xSmall)], spacing: AppMetrics.Spacing.xSmall) {
                ForEach(viewModel.remoteImageURLs, id: \.self) { url in
                    scenicImageCell(url: url, local: nil, progress: nil) {
                        viewModel.removeRemoteImage(url)
                    }
                }
                ForEach(viewModel.localImages) { image in
                    scenicImageCell(url: image.uploadedURL, local: image.data, progress: image.uploading ? image.progress : nil) {
                        viewModel.removeLocalImage(id: image.id)
                    }
                }
                if viewModel.uploadPlaceholderCount < 20 && !viewModel.isReadOnly {
                    PhotosPicker(
                        selection: $pickedImageItems,
                        maxSelectionCount: max(0, 20 - viewModel.uploadPlaceholderCount),
                        matching: .images
                    ) {
                        VStack(spacing: AppMetrics.Spacing.xSmall) {
                            Image(systemName: "plus")
                                .font(.system(size: AppMetrics.FontSize.title, weight: .semibold))
                            Text("上传图片")
                                .font(.system(size: AppMetrics.FontSize.caption, weight: .medium))
                        }
                        .foregroundStyle(AppDesign.primary)
                        .frame(height: 92)
                        .frame(maxWidth: .infinity)
                        .background(AppDesign.primarySoft, in: RoundedRectangle(cornerRadius: 10))
                        .overlay {
                            RoundedRectangle(cornerRadius: 10)
                                .stroke(AppDesign.primary.opacity(0.25), style: StrokeStyle(lineWidth: 1, dash: [5, 4]))
                        }
                    }
                    .buttonStyle(.plain)
                }
            }
        }
    }

    private var locationSection: some View {
        VStack(alignment: .leading, spacing: AppMetrics.Spacing.xSmall) {
            Text("景区位置")
                .font(.system(size: AppMetrics.FontSize.body, weight: .medium))
            HStack(spacing: AppMetrics.Spacing.small) {
                Button {
                    activeLocationPicker = .province
                } label: {
                    pickerBox(title: viewModel.selectedProvince.isEmpty ? "省份" : viewModel.selectedProvince)
                }
                .buttonStyle(.plain)
                .disabled(viewModel.isReadOnly)

                Button {
                    guard !viewModel.selectedProvince.isEmpty else {
                        viewModel.message = "请先选择省份"
                        return
                    }
                    activeLocationPicker = .city
                } label: {
                    pickerBox(title: viewModel.selectedCity.isEmpty ? "城市" : viewModel.selectedCity)
                }
                .buttonStyle(.plain)
                .disabled(viewModel.isReadOnly)
            }
        }
    }

    private var coopTypeSection: some View {
        VStack(alignment: .leading, spacing: AppMetrics.Spacing.small) {
            Text("合作类型")
                .font(.system(size: AppMetrics.FontSize.body, weight: .medium))
            VStack(spacing: AppMetrics.Spacing.xSmall) {
                coopButton(title: "我是摄影师，我想入驻", tag: 1)
                coopButton(title: "我是景区资源方，可以合作", tag: 2)
                coopButton(title: "我有摄影师团队，带队入驻", tag: 3)
                coopButton(title: "我是旅拍店，想合作", tag: 4)
                coopButton(title: "我已经在景区运营旅拍了，想使用软件，提高效率", tag: 5)
            }
        }
    }

    private var agreementSection: some View {
        VStack(spacing: AppMetrics.Spacing.small) {
            HStack(spacing: AppMetrics.Spacing.small) {
                Button {
                    viewModel.agreed.toggle()
                } label: {
                    Image(systemName: viewModel.agreed ? "checkmark.square.fill" : "square")
                        .font(.system(size: AppMetrics.ControlSize.passwordIcon))
                        .foregroundStyle(viewModel.agreed ? AppDesign.primary : AppDesign.textSecondary)
                }
                .buttonStyle(.plain)
                .disabled(viewModel.isReadOnly)
                Text("已阅读并同意《用户须知》与《隐私政策》")
                    .font(.system(size: AppMetrics.FontSize.subheadline))
                    .foregroundStyle(AppDesign.textPrimary)
                    .lineLimit(2)
                Spacer()
            }
            Button(viewModel.submitting ? "提交中..." : "确认提交") {
                Task { await viewModel.submit(api: scenicPermissionAPI, uploader: ossUploadService) }
            }
            .disabled(viewModel.isSubmitLocked)
            .font(.system(size: AppMetrics.FontSize.body, weight: .medium))
            .foregroundStyle(.white)
            .frame(maxWidth: .infinity)
            .frame(height: 46)
            .background(viewModel.canSubmit ? AppDesign.primary : Color(hex: 0xD8D8D8), in: RoundedRectangle(cornerRadius: 8))
        }
        .padding(AppMetrics.Spacing.medium)
        .background(.white)
    }

    /// 构建输入区。
    private func inputField(_ title: String, text: Binding<String>, axis: Axis = .horizontal, disabled: Bool = false) -> some View {
        VStack(alignment: .leading, spacing: AppMetrics.Spacing.small) {
            Text(title)
                .font(.system(size: AppMetrics.FontSize.body, weight: .medium))
            TextField("", text: text, prompt: Text("请输入\(title)").foregroundColor(AppDesign.placeholder), axis: axis)
                .disabled(disabled)
                .font(.system(size: AppMetrics.FontSize.subheadline))
                .lineLimit(axis == .vertical ? 3...5 : 1...1)
                .appInputFieldStyle(cornerRadius: 8, minHeight: axis == .vertical ? 100 : 50)
        }
    }

    /// 构建地区选择框。
    private func pickerBox(title: String) -> some View {
        HStack {
            Text(title)
                .font(.system(size: AppMetrics.FontSize.subheadline))
                .foregroundStyle(title == "省份" || title == "城市" ? AppDesign.placeholder : AppDesign.textPrimary)
                .lineLimit(1)
            Spacer()
            Image(systemName: "chevron.down")
                .foregroundStyle(AppDesign.textSecondary)
        }
        .padding(.horizontal, AppMetrics.Spacing.substantial)
        .frame(height: 50)
        .background(Color(hex: 0xFBFCFE), in: RoundedRectangle(cornerRadius: 10))
        .overlay {
            RoundedRectangle(cornerRadius: 10)
                .stroke(Color(hex: 0xE2E8F0), lineWidth: 1)
        }
    }

    /// 构建合作类型按钮。
    private func coopButton(title: String, tag: Int) -> some View {
        Button {
            viewModel.coopType = tag
        } label: {
            Text(title)
                .font(.system(size: AppMetrics.FontSize.subheadline, weight: .medium))
                .foregroundStyle(viewModel.coopType == tag ? .white : AppDesign.textSecondary)
                .lineLimit(2)
                .multilineTextAlignment(.leading)
                .frame(maxWidth: .infinity, alignment: .leading)
                .padding(.horizontal, AppMetrics.Spacing.medium)
                .frame(minHeight: tag == 5 ? 70 : 48)
                .background(viewModel.coopType == tag ? AppDesign.primary : .white, in: RoundedRectangle(cornerRadius: 8))
                .overlay {
                    RoundedRectangle(cornerRadius: 8)
                        .stroke(viewModel.coopType == tag ? AppDesign.primary : Color(hex: 0xE2E8F0), lineWidth: 1)
                }
        }
        .buttonStyle(.plain)
        .disabled(viewModel.isReadOnly)
    }

    /// 构建待审核状态卡片。
    private func pendingStatusCard(_ pending: ScenicApplicationPendingResponse) -> some View {
        VStack(alignment: .leading, spacing: AppMetrics.Spacing.xSmall) {
            Label(statusText(pending.status), systemImage: statusIcon(pending.status))
                .font(.system(size: AppMetrics.FontSize.caption, weight: .semibold))
                .foregroundStyle(statusColor(pending.status))
                .padding(.horizontal, AppMetrics.Spacing.small)
                .frame(height: 28)
                .background(statusColor(pending.status).opacity(0.12), in: Capsule())
            metaRow("申请编号", pending.code.isEmpty ? "--" : pending.code)
            metaRow("提交时间", pending.createdAt.isEmpty ? "--" : pending.createdAt)
        }
        .padding(AppMetrics.Spacing.small)
        .background(Color(hex: 0xF8FAFC), in: RoundedRectangle(cornerRadius: 8))
    }

    /// 构建图片格。
    private func scenicImageCell(url: String?, local data: Data?, progress: Int?, onDelete: @escaping () -> Void) -> some View {
        ZStack(alignment: .topTrailing) {
            ZStack {
                if let data, let image = UIImage(data: data) {
                    Image(uiImage: image)
                        .resizable()
                        .scaledToFill()
                } else if let url, !url.isEmpty {
                    RemoteImage(urlString: url) {
                        imagePlaceholder
                    }
                } else {
                    imagePlaceholder
                }
                if let progress {
                    Color.black.opacity(0.38)
                    ProgressView(value: Double(progress), total: 100)
                        .tint(.white)
                        .padding(AppMetrics.Spacing.xSmall)
                }
            }
            .frame(height: 92)
            .frame(maxWidth: .infinity)
            .clipShape(RoundedRectangle(cornerRadius: 10))

            if !viewModel.isReadOnly {
                Button(action: onDelete) {
                    Image(systemName: "xmark.circle.fill")
                        .font(.system(size: AppMetrics.FontSize.title2, weight: .semibold))
                        .foregroundStyle(.white, Color.black.opacity(0.55))
                        .padding(AppMetrics.Spacing.xxSmall)
                }
                .buttonStyle(.plain)
            }
        }
    }

    private var imagePlaceholder: some View {
        ZStack {
            Color(hex: 0xF1F5F9)
            Image(systemName: "photo.fill")
                .font(.system(size: AppMetrics.FontSize.title, weight: .semibold))
                .foregroundStyle(Color(hex: 0x94A3B8))
        }
    }

    /// 导入用户从系统相册选择的图片数据。
    private func importPickedImages(_ items: [PhotosPickerItem]) async {
        for item in items {
            guard viewModel.uploadPlaceholderCount < 20 else { return }
            do {
                guard let data = try await item.loadTransferable(type: Data.self) else { continue }
                viewModel.addLocalImage(data: data, fileName: "scenic_\(UUID().uuidString).jpg")
            } catch {
                viewModel.message = error.localizedDescription
            }
        }
    }

    private func metaRow(_ title: String, _ value: String) -> some View {
        HStack {
            Text("\(title)：")
                .foregroundStyle(AppDesign.textSecondary)
            Text(value)
                .foregroundStyle(AppDesign.textPrimary)
            Spacer()
        }
        .font(.system(size: AppMetrics.FontSize.caption))
    }

    private func statusText(_ status: Int) -> String {
        switch status {
        case 1: return "待审核"
        case 2: return "已通过"
        case 3: return "已驳回"
        case 9: return "已取消"
        default: return "未提交"
        }
    }

    private func statusIcon(_ status: Int) -> String {
        switch status {
        case 2: return "checkmark.circle.fill"
        case 3: return "xmark.octagon.fill"
        case 1: return "clock.badge.exclamationmark.fill"
        default: return "questionmark.circle.fill"
        }
    }

    private func statusColor(_ status: Int) -> Color {
        switch status {
        case 2: return AppDesign.success
        case 3: return Color(hex: 0xDC2626)
        case 1: return AppDesign.warning
        default: return AppDesign.textSecondary
        }
    }
}

/// 景区申请地区选择器类型。
private enum ScenicLocationPicker: Identifiable {
    case province
    case city

    var id: String {
        switch self {
        case .province: "province"
        case .city: "city"
        }
    }

    var title: String {
        switch self {
        case .province: "选择省份"
        case .city: "选择城市"
        }
    }
}

/// 景区申请省市选择弹层。
private struct ScenicLocationSelectionSheet: View {
    @Environment(\.dismiss) private var dismiss
    let picker: ScenicLocationPicker
    let provinces: [ScenicAreaNode]
    let cities: [ScenicAreaNode]
    let selectedProvince: String
    let selectedCity: String
    let onSelectProvince: (ScenicAreaNode) -> Void
    let onSelectCity: (ScenicAreaNode) -> Void

    private var items: [ScenicAreaNode] {
        picker == .province ? provinces : cities
    }

    var body: some View {
        NavigationStack {
            ScrollView {
                LazyVStack(spacing: AppMetrics.Spacing.xSmall) {
                    ForEach(items) { item in
                        Button {
                            switch picker {
                            case .province:
                                onSelectProvince(item)
                            case .city:
                                onSelectCity(item)
                            }
                            dismiss()
                        } label: {
                            HStack(spacing: AppMetrics.Spacing.small) {
                                Text(item.name)
                                    .font(.system(size: AppMetrics.FontSize.subheadline, weight: isSelected(item) ? .semibold : .regular))
                                    .foregroundStyle(AppDesign.textPrimary)
                                Spacer()
                                if isSelected(item) {
                                    Image(systemName: "checkmark.circle.fill")
                                        .foregroundStyle(AppDesign.primary)
                                }
                            }
                            .padding(.horizontal, AppMetrics.Spacing.substantial)
                            .frame(height: 48)
                            .background(.white, in: RoundedRectangle(cornerRadius: 12))
                        }
                        .buttonStyle(.plain)
                    }
                }
                .padding(AppMetrics.Spacing.medium)
            }
            .background(Color(hex: 0xF5F7FA).ignoresSafeArea())
            .navigationTitle(picker.title)
            .navigationBarTitleDisplayMode(.inline)
            .toolbar {
                ToolbarItem(placement: .cancellationAction) {
                    Button("关闭") { dismiss() }
                }
            }
        }
    }

    /// 判断地区节点是否已选中。
    private func isSelected(_ item: ScenicAreaNode) -> Bool {
        switch picker {
        case .province:
            item.name == selectedProvince
        case .city:
            item.name == selectedCity
        }
    }
}
