import Testing
import Foundation
@testable import 康康

struct SeriesBucketTests {

    private func makeIndicator(
        name: String = "测试",
        value: String,
        unit: String = "mmol/L",
        range: String = "",
        status: IndicatorStatus = .normal,
        capturedAt: Date,
        seriesKey: String?
    ) -> Indicator {
        Indicator(name: name, value: value, unit: unit, range: range,
                  status: status, capturedAt: capturedAt,
                  seriesKey: seriesKey)
    }

    @Test func indicatorsWithoutSeriesKeyFoldIntoLabBucket() {
        // 「lab 段」特性:无 seriesKey 的指标按 name+unit 归并,同名 ≥minPoints 次即成趋势。
        let now = Date()
        let items = [
            makeIndicator(value: "5.0", capturedAt: now.addingTimeInterval(-86_400), seriesKey: nil),
            makeIndicator(value: "5.2", capturedAt: now, seriesKey: nil),
        ]
        let buckets = SeriesBucket.build(from: items)
        #expect(buckets.count == 1)
        #expect(buckets.first?.kind == .lab)
        #expect(buckets.first?.lines.first?.points.count == 2)
    }

    @Test func filtersOutSeriesWithFewerThanMinPoints() {
        let now = Date()
        let items = [
            makeIndicator(value: "5.0", capturedAt: now, seriesKey: "glucose.fasting"),
        ]
        let buckets = SeriesBucket.build(from: items, minPoints: 2)
        #expect(buckets.isEmpty)
    }

    @Test func singleSeriesBucketSortedAscending() {
        let day = { (offset: Int) -> Date in
            Calendar.current.date(byAdding: .day, value: offset, to: .now)!
        }
        let items = [
            makeIndicator(value: "5.5", capturedAt: day(-3), seriesKey: "glucose.fasting"),
            makeIndicator(value: "5.2", capturedAt: day(-1), seriesKey: "glucose.fasting"),
            makeIndicator(value: "5.8", capturedAt: day(-2), seriesKey: "glucose.fasting"),
        ]
        let buckets = SeriesBucket.build(from: items)
        #expect(buckets.count == 1)
        let line = try! #require(buckets.first?.lines.first)
        // sorted ascending → -3, -2, -1
        let values = line.points.map(\.value)
        #expect(values == [5.5, 5.8, 5.2])
    }

    @Test func bloodPressureMergesIntoSingleBucket() {
        let now = Date()
        let day = { (offset: Int) -> Date in
            Calendar.current.date(byAdding: .day, value: offset, to: now)!
        }
        let items = [
            makeIndicator(value: "125", capturedAt: day(-2), seriesKey: "bp.systolic"),
            makeIndicator(value: "82",  capturedAt: day(-2), seriesKey: "bp.diastolic"),
            makeIndicator(value: "130", capturedAt: day(-1), seriesKey: "bp.systolic"),
            makeIndicator(value: "85",  capturedAt: day(-1), seriesKey: "bp.diastolic"),
        ]
        let buckets = SeriesBucket.build(from: items)
        let bp = try! #require(buckets.first { $0.id == "bp" })
        #expect(bp.lines.count == 2)
        #expect(bp.title == "血压")
        #expect(bp.lines.contains { $0.seriesKey == "bp.systolic" })
        #expect(bp.lines.contains { $0.seriesKey == "bp.diastolic" })
    }

    @Test func mixedSeriesProducesMultipleBucketsSortedByRecency() {
        let cal = Calendar.current
        let day = { (offset: Int) -> Date in
            cal.date(byAdding: .day, value: offset, to: .now)!
        }
        let items = [
            // weight 较旧
            makeIndicator(value: "68", capturedAt: day(-10), seriesKey: "weight"),
            makeIndicator(value: "67", capturedAt: day(-7),  seriesKey: "weight"),
            // glucose 较新
            makeIndicator(value: "5.1", capturedAt: day(-2), seriesKey: "glucose.fasting"),
            makeIndicator(value: "5.3", capturedAt: day(-1), seriesKey: "glucose.fasting"),
        ]
        let buckets = SeriesBucket.build(from: items)
        #expect(buckets.count == 2)
        // 最新的 glucose 排前面
        #expect(buckets.first?.id == "glucose.fasting")
        #expect(buckets.last?.id == "weight")
    }

    @Test func nonNumericValueDropped() {
        let now = Date()
        let items = [
            makeIndicator(value: "高", capturedAt: now, seriesKey: "weight"),
            makeIndicator(value: "68", capturedAt: now, seriesKey: "weight"),
            makeIndicator(value: "67", capturedAt: now.addingTimeInterval(60), seriesKey: "weight"),
        ]
        let buckets = SeriesBucket.build(from: items)
        let line = try! #require(buckets.first?.lines.first)
        #expect(line.points.count == 2)  // "高" 被丢
    }
}
