import SwiftUI

struct RecordChangeEvolutionChart: View {
    let snapshots: [HealthSnapshot]
    let currentSnapshotID: UUID
    let typeIdentifier: String
    let displayName: String

    private var sortedSnapshots: [HealthSnapshot] {
        snapshots.sorted { $0.timestamp < $1.timestamp }
    }

    private var currentIndex: Int? {
        sortedSnapshots.firstIndex { $0.id == currentSnapshotID }
    }

    private var contextSnapshots: [HealthSnapshot] {
        guard let idx = currentIndex else { return [] }
        let start = max(0, idx - 3)
        let end = min(sortedSnapshots.count, idx + 4)
        return Array(sortedSnapshots[start..<end])
    }

    private var maxCount: Int {
        let counts = contextSnapshots.compactMap { snapshot in
            snapshot.typeCounts?.first { $0.typeIdentifier == typeIdentifier }?.count
        }
        return counts.max() ?? 1
    }

    private var maxNegativeCount: Int {
        var max = 0
        for i in 0..<contextSnapshots.count {
            let snapshot = contextSnapshots[i]
            let previousSnapshot = i > 0 ? contextSnapshots[i - 1] : nil
            let diff = recordDiff(current: snapshot, previous: previousSnapshot)
            max = Swift.max(max, diff.disappeared)
        }
        return max
    }

    private func recordDiff(current: HealthSnapshot, previous: HealthSnapshot?) -> (added: Int, disappeared: Int) {
        guard let previous = previous else { return (0, 0) }
        guard let cache = current.typeCounts?
            .first(where: { $0.typeIdentifier == typeIdentifier })?
            .detailCache,
              cache.matchesBaseline(previous.id) else {
            return (0, 0)
        }
        return (cache.addedCount, cache.disappearedCount)
    }

    var body: some View {
        if contextSnapshots.count < 2 {
            emptyState
        } else {
            evolutionView
        }
    }

    private var emptyState: some View {
        VStack(spacing: 8) {
            Image(systemName: "chart.line.uptrend.xyaxis")
                .font(.system(size: 24, weight: .semibold))
                .foregroundStyle(.secondary)

            Text("Not enough snapshots")
                .font(.caption)
                .foregroundStyle(.secondary)
        }
        .frame(maxWidth: .infinity)
        .padding(24)
        .background(Color(.systemBackground).opacity(0.5), in: RoundedRectangle(cornerRadius: 8))
    }

    private var evolutionView: some View {
        VStack(alignment: .leading, spacing: 12) {
            HStack {
                Text("Evolution")
                    .font(.headline.weight(.semibold))
                    .foregroundStyle(.primary)

                Spacer()

                Text("\(contextSnapshots.count) snapshots")
                    .font(.caption)
                    .foregroundStyle(.secondary)
            }

            evolutionChart

            HStack(spacing: 12) {
                VStack(alignment: .leading, spacing: 4) {
                    Text("Min")
                        .font(.caption)
                        .foregroundStyle(.secondary)
                    Text("\(contextSnapshots.compactMap { $0.typeCounts?.first { $0.typeIdentifier == typeIdentifier }?.count }.min() ?? 0)")
                        .font(.caption.weight(.semibold))
                        .monospacedDigit()
                }

                Spacer()

                VStack(alignment: .center, spacing: 4) {
                    Text("Current")
                        .font(.caption)
                        .foregroundStyle(.secondary)
                    if let current = contextSnapshots.first(where: { $0.id == currentSnapshotID }),
                       let count = current.typeCounts?.first(where: { $0.typeIdentifier == typeIdentifier })?.count {
                        Text("\(count)")
                            .font(.caption.weight(.semibold))
                            .monospacedDigit()
                            .foregroundStyle(Color.accentColor)
                    }
                }

                Spacer()

                VStack(alignment: .trailing, spacing: 4) {
                    Text("Max")
                        .font(.caption)
                        .foregroundStyle(.secondary)
                    Text("\(maxCount)")
                        .font(.caption.weight(.semibold))
                        .monospacedDigit()
                }
            }
            .padding(8)
            .background(Color(.systemBackground).opacity(0.3), in: RoundedRectangle(cornerRadius: 6))
        }
        .padding(12)
        .background(Color(.systemBackground).opacity(0.5), in: RoundedRectangle(cornerRadius: 8))
    }

    @ViewBuilder
    private var evolutionChart: some View {
        HStack(alignment: .bottom, spacing: 4) {
            ForEach(Array(contextSnapshots.enumerated()), id: \.element.id) { idx, snapshot in
                chartBar(at: idx, snapshot: snapshot)
            }
        }
        .frame(height: 100)
        .padding(12)
        .background(Color(.systemBackground).opacity(0.3), in: RoundedRectangle(cornerRadius: 8))
    }

    @ViewBuilder
    private func chartBar(at index: Int, snapshot: HealthSnapshot) -> some View {
        let typeCount = snapshot.typeCounts?.first { $0.typeIdentifier == typeIdentifier }
        let count = typeCount?.count ?? 0
        let isCurrent = snapshot.id == currentSnapshotID
        let previousSnapshot = index > 0 ? contextSnapshots[index - 1] : nil
        let diff = recordDiff(current: snapshot, previous: previousSnapshot)
        let unchanged = count - diff.added

        let barTotalRange = CGFloat(diff.disappeared + count)
        let redHeight = barTotalRange > 0 ? CGFloat(diff.disappeared) / barTotalRange * 80 : 0
        let blueHeight = barTotalRange > 0 ? CGFloat(unchanged) / barTotalRange * 80 : 0
        let greenHeight = barTotalRange > 0 ? CGFloat(diff.added) / barTotalRange * 80 : 0

        let minVisibleHeight: CGFloat = 3

        VStack(spacing: 0) {
            if isCurrent {
                Image(systemName: "star.fill")
                    .font(.system(size: 12, weight: .semibold))
                    .foregroundStyle(Color.accentColor)
                    .padding(.bottom, 4)
            }

            VStack(spacing: 0) {
                if diff.added > 0 {
                    RoundedRectangle(cornerRadius: 1)
                        .fill(Color.healthyGreen)
                        .frame(height: max(minVisibleHeight, greenHeight))
                }

                if unchanged > 0 {
                    RoundedRectangle(cornerRadius: 1)
                        .fill(Color.neutralGray.opacity(0.6))
                        .frame(height: max(1, blueHeight))
                }

                if diff.disappeared > 0 {
                    RoundedRectangle(cornerRadius: 1)
                        .fill(Color.criticalRed)
                        .frame(height: max(minVisibleHeight, redHeight))
                }
            }
            .frame(height: 80)
            .frame(maxWidth: .infinity)

            Text(snapshot.timestamp.formatted(.dateTime.month().day()))
                .font(.caption2)
                .foregroundStyle(.secondary)
                .lineLimit(1)
                .padding(.top, 4)
        }
        .frame(maxWidth: .infinity)
    }
}

#Preview {
    let mockSnapshots = (0..<7).map { idx in
        let snapshot = HealthSnapshot(
            timestamp: Calendar.current.date(byAdding: .day, value: idx - 3, to: Date.now) ?? .now,
            osVersion: "iOS 26.4",
            deviceName: "Preview iPhone",
            deviceID: "preview-device"
        )

        let recordCount = Int.random(in: 5000..<15000)
        let mockRecords = (0..<recordCount).map { i in
            HealthRecordValue(
                typeIdentifier: "HKQuantityTypeIdentifierStepCount",
                sampleUUIDHash: UUID().uuidString,
                recordFingerprint: "fp-\(idx)-\(i)",
                startDate: Date.now.addingTimeInterval(-Double(i * 3600)),
                endDate: Date.now.addingTimeInterval(-Double(i * 3600) + 3600),
                displayValue: nil
            )
        }

        let typeCount = TypeCount(
            typeIdentifier: "HKQuantityTypeIdentifierStepCount",
            displayName: "Step Count",
            count: recordCount
        )
        typeCount.setRecordValues(mockRecords)
        snapshot.typeCounts = [typeCount]

        return snapshot
    }

    RecordChangeEvolutionChart(
        snapshots: mockSnapshots,
        currentSnapshotID: mockSnapshots[3].id,
        typeIdentifier: "HKQuantityTypeIdentifierStepCount",
        displayName: "Step Count"
    )
    .padding(16)
}
