import SwiftUI

// MARK: - SearchSkeletonView

/// Telegram-style skeleton loading for search results.
/// Matches the Figma chat row layout: 62px avatar, two-line text, trailing time.
/// Uses TimelineView so the shimmer never restarts on view rebuild.
struct SearchSkeletonView: View {

    var body: some View {
        TimelineView(.animation) { timeline in
            let phase = shimmerPhase(from: timeline.date)

            ScrollView {
                VStack(spacing: 0) {
                    ForEach(0..<7, id: \.self) { index in
                        skeletonRow(index: index, phase: phase)
                        if index < 6 {
                            Divider()
                                .foregroundStyle(RosettaColors.Adaptive.divider)
                                .padding(.leading, 82)
                        }
                    }
                }
            }
            .scrollDisabled(true)
        }
    }

    private func skeletonRow(index: Int, phase: CGFloat) -> some View {
        HStack(spacing: 0) {
            // Avatar — 62pt circle matching Figma
            Circle()
                .fill(shimmerGradient(phase: phase))
                .frame(width: 62, height: 62)
                .padding(.leading, 10)
                .padding(.trailing, 10)

            // Text block — two lines matching Figma row heights
            VStack(alignment: .leading, spacing: 8) {
                // Title line — name width varies per row
                RoundedRectangle(cornerRadius: 4)
                    .fill(shimmerGradient(phase: phase))
                    .frame(width: titleWidth(for: index), height: 16)

                // Subtitle line — message preview
                RoundedRectangle(cornerRadius: 4)
                    .fill(shimmerGradient(phase: phase))
                    .frame(width: subtitleWidth(for: index), height: 14)
            }

            Spacer()

            // Trailing time placeholder
            RoundedRectangle(cornerRadius: 3)
                .fill(shimmerGradient(phase: phase))
                .frame(width: 40, height: 12)
                .padding(.trailing, 16)
        }
        .frame(height: 78)
    }

    // Vary widths to look natural (not uniform blocks)
    private func titleWidth(for index: Int) -> CGFloat {
        let widths: [CGFloat] = [130, 100, 160, 90, 140, 110, 150]
        return widths[index % widths.count]
    }

    private func subtitleWidth(for index: Int) -> CGFloat {
        let widths: [CGFloat] = [200, 170, 220, 150, 190, 180, 210]
        return widths[index % widths.count]
    }
}

// MARK: - SearchSkeletonRow

/// Single shimmer row matching `serverUserRow` layout (48px avatar, two text lines).
/// Used inline below existing search results while server is still loading.
struct SearchSkeletonRow: View {

    var body: some View {
        TimelineView(.animation) { timeline in
            let phase = shimmerPhase(from: timeline.date)

            HStack(spacing: 12) {
                Circle()
                    .fill(shimmerGradient(phase: phase))
                    .frame(width: 48, height: 48)

                VStack(alignment: .leading, spacing: 6) {
                    RoundedRectangle(cornerRadius: 4)
                        .fill(shimmerGradient(phase: phase))
                        .frame(width: 120, height: 14)

                    RoundedRectangle(cornerRadius: 4)
                        .fill(shimmerGradient(phase: phase))
                        .frame(width: 90, height: 12)
                }

                Spacer()
            }
            .padding(.horizontal, 16)
            .padding(.vertical, 12)
        }
    }
}

// MARK: - Shared Shimmer Helpers

/// Derives a 0→1 phase from the system clock (1.5s cycle).
/// Clock-based — never resets on view rebuild.
private func shimmerPhase(from date: Date) -> CGFloat {
    let elapsed = date.timeIntervalSinceReferenceDate
    let cycle: Double = 1.5
    return CGFloat(elapsed.truncatingRemainder(dividingBy: cycle) / cycle)
}

private func shimmerGradient(phase: CGFloat) -> LinearGradient {
    // Map phase 0→1 to position -0.5→1.5 so the highlight
    // enters from off-screen left and exits off-screen right.
    // When phase wraps 1→0, highlight is already invisible — no jump.
    let position = phase * 2.0 - 0.5
    return LinearGradient(
        colors: [
            Color.gray.opacity(0.08),
            Color.gray.opacity(0.15),
            Color.gray.opacity(0.08),
        ],
        startPoint: UnitPoint(x: position - 0.3, y: 0),
        endPoint: UnitPoint(x: position + 0.3, y: 0)
    )
}
