//
//  ScenicPromotionSpotTabsView.swift
//  suixinkan
//
//  Created by Codex on 2026/7/2.
//

import SwiftUI

/// 宣传页打卡点标签区，5 个以内等分，超过 5 个时横向滚动并将选中项居中。
struct ScenicPromotionSpotTabsView: View {
    let spots: [ScenicPromotionSpot]
    let selectedSpotID: String?
    let onSelectSpot: (ScenicPromotionSpot) -> Void

    /// 选中背景滑块动画曲线。
    private static let selectionAnimation = Animation.spring(response: 0.35, dampingFraction: 0.82)
    /// 选中标签滚动居中动画曲线。
    private static let scrollAnimation = Animation.easeInOut(duration: 0.25)

    /// 当前选中标签在列表中的索引，未选中时回退到 0。
    private var selectedIndex: Int {
        guard let selectedSpotID else { return 0 }
        return spots.firstIndex(where: { $0.id == selectedSpotID }) ?? 0
    }

    /// 是否需要启用横向滚动（超过 5 个标签）。
    private var shouldEnableScroll: Bool {
        spots.count > Int(ScenicPromotionLayout.visibleSpotTabCount)
    }

    var body: some View {
        if spots.isEmpty {
            EmptyView()
        } else {
            Color.clear
                .frame(maxWidth: .infinity)
                .frame(height: 42)
                .overlay {
                    GeometryReader { proxy in
                        let visibleCount = min(
                            CGFloat(max(spots.count, 1)),
                            ScenicPromotionLayout.visibleSpotTabCount
                        )
                        let tabWidth = proxy.size.width / visibleCount

                        ScrollViewReader { scrollProxy in
                            ScrollView(.horizontal, showsIndicators: false) {
                                ZStack(alignment: .leading) {
                                    selectionBackground(width: tabWidth)

                                    HStack(spacing: 0) {
                                        ForEach(spots) { spot in
                                            ScenicPromotionSpotTabButton(
                                                spot: spot,
                                                isSelected: selectedSpotID == spot.id,
                                                onTap: { onSelectSpot(spot) }
                                            )
                                            .frame(width: tabWidth)
                                            .id(spot.id)
                                        }
                                    }
                                }
                            }
                            .scrollDisabled(!shouldEnableScroll)
                            .onAppear {
                                scrollSelectedTabToCenter(using: scrollProxy, animated: false)
                            }
                            .onChange(of: selectedSpotID) { _ in
                                scrollSelectedTabToCenter(using: scrollProxy, animated: true)
                            }
                        }
                    }
                }
                .background(.white.opacity(0.84), in: RoundedRectangle(cornerRadius: 14))
                .clipShape(RoundedRectangle(cornerRadius: 14))
                .overlay(
                    RoundedRectangle(cornerRadius: 14)
                        .stroke(.white.opacity(0.8), lineWidth: 1)
                )
                .shadow(color: Color(hex: 0x0D47A1, alpha: 0.12), radius: 12, y: 5)
        }
    }

    /// 选中标签的渐变背景滑块，随选中项横向位移。
    @ViewBuilder
    private func selectionBackground(width: CGFloat) -> some View {
        RoundedRectangle(cornerRadius: 14)
            .fill(
                LinearGradient(
                    colors: [Color(hex: 0x1286FF), Color(hex: 0x006BFF)],
                    startPoint: .topLeading,
                    endPoint: .bottomTrailing
                )
            )
            .frame(width: width, height: 42)
            .offset(x: CGFloat(selectedIndex) * width)
            .animation(Self.selectionAnimation, value: selectedIndex)
    }

    /// 超过可见数量时，将选中标签滚动到可视区域中间。
    private func scrollSelectedTabToCenter(using scrollProxy: ScrollViewProxy, animated: Bool) {
        guard shouldEnableScroll, let selectedSpotID else { return }

        if animated {
            withAnimation(Self.scrollAnimation) {
                scrollProxy.scrollTo(selectedSpotID, anchor: .center)
            }
        } else {
            scrollProxy.scrollTo(selectedSpotID, anchor: .center)
        }
    }
}

/// 单个打卡点标签按钮。
struct ScenicPromotionSpotTabButton: View {
    let spot: ScenicPromotionSpot
    let isSelected: Bool
    let onTap: () -> Void

    var body: some View {
        Button(action: onTap) {
            HStack(spacing: 3) {
                Image(systemName: spot.iconName)
                    .font(.system(size: 13, weight: .bold))
                Text(spot.name)
                    .font(.system(size: 12, weight: .bold))
                    .lineLimit(1)
                    .minimumScaleFactor(0.66)
            }
            .foregroundStyle(isSelected ? .white : Color(hex: 0x14213D))
            .frame(height: 42)
            .padding(.horizontal, 4)
            .contentShape(Rectangle())
        }
        .buttonStyle(.plain)
    }
}

#if DEBUG
#Preview("打卡点标签") {
    ScenicPromotionSpotTabsView(
        spots: ScenicPromotionPreviewSupport.sampleBoard.spots,
        selectedSpotID: "bridge",
        onSelectSpot: { _ in }
    )
    .padding(.horizontal, 20)
}
#endif
