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

import CoreLocation
import SwiftUI

/// 景区选择页面，支持搜索、定位距离展示和切换当前景区。
struct ScenicSelectionView: View {
    @Environment(AccountContext.self) private var accountContext
    @Environment(PermissionContext.self) private var permissionContext
    @Environment(AccountSnapshotStore.self) private var snapshotStore
    @Environment(\.dismiss) private var dismiss

    @State private var viewModel = ScenicSelectionViewModel()
    @State private var locationProvider = ScenicSelectionLocationProvider()

    var body: some View {
        VStack(spacing: 0) {
            applyBanner
            searchBar
            currentLocationBar
            content
        }
        .background(AppDesign.backgroundColor.ignoresSafeArea())
        .navigationTitle("景区选择")
        .navigationBarTitleDisplayMode(.inline)
        .task {
            viewModel.reload(from: accountContext)
            requestLocation()
        }
    }

    private var applyBanner: some View {
        NavigationLink(value: AppRoute.home(.permissionApply)) {
            HStack(spacing: 10) {
                Image(systemName: "building.2.fill")
                    .font(.system(size: AppMetrics.ControlSize.checkboxIcon, weight: .semibold))
                    .foregroundStyle(AppDesign.warning)
                Text("希望开通更多景区权限")
                    .font(.system(size: AppMetrics.FontSize.subheadline, weight: .medium))
                    .foregroundStyle(AppDesign.warning)
                    .lineLimit(1)
                Spacer()
                Text("立即申请")
                    .font(.system(size: AppMetrics.FontSize.subheadline, weight: .semibold))
                Image(systemName: "chevron.right")
                    .font(.system(size: AppMetrics.FontSize.caption, weight: .bold))
            }
            .foregroundStyle(AppDesign.warning)
            .padding(.horizontal, AppMetrics.Spacing.medium)
            .frame(height: 56)
            .background(Color(hex: 0xFFF0E2))
        }
        .buttonStyle(.plain)
    }

    private var searchBar: some View {
        HStack(spacing: AppMetrics.Spacing.small) {
            Image(systemName: "magnifyingglass")
                .font(.system(size: AppMetrics.ControlSize.checkboxIcon))
                .foregroundStyle(AppDesign.placeholder)
            TextField("搜索景区", text: $viewModel.searchQuery)
                .font(.system(size: AppMetrics.FontSize.subheadline))
                .textInputAutocapitalization(.never)
                .autocorrectionDisabled(true)
                .tint(AppDesign.primary)
        }
        .padding(.horizontal, AppMetrics.Spacing.medium)
        .frame(height: AppMetrics.ControlSize.inputHeight)
        .background(Color(hex: 0xF2F4F8), in: RoundedRectangle(cornerRadius: AppMetrics.CornerRadius.input))
        .padding(.horizontal, AppMetrics.Spacing.medium)
        .padding(.top, AppMetrics.Spacing.medium)
    }

    private var currentLocationBar: some View {
        VStack(alignment: .leading, spacing: AppMetrics.Spacing.xSmall) {
            HStack(spacing: AppMetrics.Spacing.xSmall) {
                Image(systemName: "location.fill")
                    .font(.system(size: AppMetrics.ControlSize.smallIcon, weight: .semibold))
                    .foregroundStyle(AppDesign.textPrimary)
                Text(viewModel.currentLocationText)
                    .font(.system(size: AppMetrics.FontSize.subheadline))
                    .foregroundStyle(AppDesign.textPrimary)
                    .lineLimit(1)
                    .frame(maxWidth: .infinity, alignment: .leading)
                Button("当前定位地址") {
                    requestLocation()
                }
                .font(.system(size: AppMetrics.FontSize.caption, weight: .medium))
                .foregroundStyle(AppDesign.primary)
                .buttonStyle(.plain)
            }
            if let warning = viewModel.locationWarning {
                Text(warning)
                    .font(.system(size: AppMetrics.FontSize.caption))
                    .foregroundStyle(AppDesign.warning)
                    .lineLimit(2)
            }
        }
        .padding(.horizontal, AppMetrics.Spacing.medium)
        .padding(.vertical, AppMetrics.Spacing.small)
    }

    @ViewBuilder
    private var content: some View {
        ScrollView {
            if viewModel.filteredItems.isEmpty {
                ContentUnavailableView(
                    "暂无可选景区",
                    systemImage: "mountain.2",
                    description: Text("可尝试清空搜索关键词或刷新定位。")
                )
                .frame(maxWidth: .infinity, minHeight: 240)
                .padding(.top, AppMetrics.Spacing.xLarge)
            } else {
                LazyVStack(spacing: AppMetrics.Spacing.small) {
                    ForEach(viewModel.filteredItems) { scenic in
                        ScenicSelectionCard(
                            scenic: scenic,
                            isSelected: accountContext.currentScenic?.id == scenic.id
                        ) {
                            viewModel.select(
                                scenicId: scenic.id,
                                accountContext: accountContext,
                                permissionContext: permissionContext,
                                snapshotStore: snapshotStore
                            )
                            dismiss()
                        }
                    }
                }
                .padding(.horizontal, AppMetrics.Spacing.large)
                .padding(.bottom, AppMetrics.Spacing.xLarge)
            }
        }
    }

    /// 请求当前位置，并把定位结果回写 ViewModel。
    private func requestLocation() {
        viewModel.currentLocationText = "定位中..."
        viewModel.locationWarning = nil
        locationProvider.onLocation = { location in
            Task { @MainActor in
                viewModel.applyCurrentLocation(
                    latitude: location.coordinate.latitude,
                    longitude: location.coordinate.longitude
                )
            }
        }
        locationProvider.onFailure = { message in
            Task { @MainActor in
                viewModel.applyLocationFailure(message)
            }
        }
        locationProvider.request()
    }
}

/// 景区选择卡片，展示封面、名称、地址、距离和状态。
private struct ScenicSelectionCard: View {
    let scenic: ScenicSelectionItem
    let isSelected: Bool
    let onTap: () -> Void

    var body: some View {
        Button(action: onTap) {
            HStack(spacing: AppMetrics.Spacing.small) {
                RemoteImage(urlString: scenic.coverURLString) {
                    ZStack {
                        Color(hex: 0xF0F0F0)
                        Image(systemName: "photo")
                            .font(.system(size: AppMetrics.FontSize.title, weight: .medium))
                            .foregroundStyle(Color(hex: 0xAAB2BD))
                    }
                }
                .frame(width: 80, height: 80)
                .clipShape(RoundedRectangle(cornerRadius: 6))

                VStack(alignment: .leading, spacing: AppMetrics.Spacing.xSmall) {
                    HStack(spacing: AppMetrics.Spacing.xSmall) {
                        Text(scenic.name)
                            .font(.system(size: AppMetrics.FontSize.body, weight: .bold))
                            .foregroundStyle(AppDesign.textPrimary)
                            .lineLimit(1)
                        statusBadge
                    }
                    HStack(spacing: AppMetrics.Spacing.xxSmall) {
                        Text(scenic.distanceText)
                            .font(.system(size: AppMetrics.FontSize.subheadline))
                            .foregroundStyle(AppDesign.textPrimary)
                            .fixedSize()
                        Text(scenic.address)
                            .font(.system(size: AppMetrics.FontSize.caption))
                            .foregroundStyle(AppDesign.textSecondary)
                            .lineLimit(1)
                    }
                    if isSelected {
                        Label("当前景区", systemImage: "checkmark.circle.fill")
                            .font(.system(size: AppMetrics.FontSize.caption, weight: .semibold))
                            .foregroundStyle(AppDesign.primary)
                    }
                }
                .frame(maxWidth: .infinity, alignment: .leading)
            }
            .padding(AppMetrics.Spacing.small)
            .frame(minHeight: 104)
            .background(.white, in: RoundedRectangle(cornerRadius: 8))
            .overlay {
                RoundedRectangle(cornerRadius: 8)
                    .stroke(isSelected ? AppDesign.primary : Color(hex: 0xEEF2F7), lineWidth: isSelected ? 2 : 1)
            }
            .shadow(color: .black.opacity(isSelected ? 0.08 : 0.03), radius: 8, x: 0, y: 3)
        }
        .buttonStyle(.plain)
    }

    @ViewBuilder
    private var statusBadge: some View {
        if scenic.isClosest {
            Text("距离最近")
                .font(.system(size: AppMetrics.FontSize.caption, weight: .medium))
                .foregroundStyle(.white)
                .padding(.horizontal, AppMetrics.Spacing.xSmall)
                .frame(height: 26)
                .background(Color(hex: 0xE74C3C), in: RoundedRectangle(cornerRadius: 4))
        } else if scenic.isClosed {
            Text("暂未营业")
                .font(.system(size: AppMetrics.FontSize.caption, weight: .medium))
                .foregroundStyle(AppDesign.textSecondary)
                .padding(.horizontal, AppMetrics.Spacing.xSmall)
                .frame(height: 26)
                .background(Color(hex: 0xE0E0E0), in: RoundedRectangle(cornerRadius: 4))
        }
    }
}

private extension AppDesign {
    static let backgroundColor = Color(hex: 0xF5F7FA)
}
