import WidgetKit
import SwiftUI

// MARK: - 快照模型(主 App 的独立拷贝)
//
// ⚠️ 同步契约:与主 App `康康/Persistence/WidgetSnapshot.swift` 字段必须一致。
// extension 不引主 App 代码(免去 target membership 配置),改字段时两边一起改。

private struct WidgetSnapshot: Codable, Equatable {
    struct Item: Codable, Equatable {
        var name: String
        var value: String
        var unit: String
        var statusRaw: String     // high|low|normal
        var capturedAt: Date
    }

    var updatedAt: Date
    var items: [Item]

    static let appGroupID = "group.com.xuhuayong.kangkang"
    static let storeKey = "kk.widget.snapshot.v1"

    static func load() -> WidgetSnapshot? {
        guard let defaults = UserDefaults(suiteName: appGroupID),
              let data = defaults.data(forKey: storeKey) else { return nil }
        return try? JSONDecoder().decode(WidgetSnapshot.self, from: data)
    }
}

// MARK: - 调色(镜像主 App Tj.Palette,extension 不引 DesignSystem)

private enum KkColor {
    static let sand  = Color(red: 0.976, green: 0.969, blue: 0.949)
    static let ink   = Color(red: 0.165, green: 0.153, blue: 0.137)
    static let text  = Color(red: 0.149, green: 0.137, blue: 0.118)
    static let text2 = Color(red: 0.420, green: 0.408, blue: 0.384)
    static let text3 = Color(red: 0.616, green: 0.604, blue: 0.580)
    static let brick = Color(red: 0.886, green: 0.388, blue: 0.314)   // high
    static let amber = Color(red: 0.871, green: 0.627, blue: 0.314)   // low
    static let leaf  = Color(red: 0.180, green: 0.357, blue: 0.518)   // normal
}

private func statusColor(_ raw: String) -> Color {
    switch raw {
    case "high": return KkColor.brick
    case "low":  return KkColor.amber
    default:     return KkColor.leaf
    }
}

// MARK: - Timeline

private struct PinnedEntry: TimelineEntry {
    let date: Date
    let items: [WidgetSnapshot.Item]
    let updatedAt: Date?
}

private struct PinnedProvider: TimelineProvider {
    func placeholder(in context: Context) -> PinnedEntry {
        PinnedEntry(date: .now, items: Self.sampleItems, updatedAt: .now)
    }

    func getSnapshot(in context: Context, completion: @escaping (PinnedEntry) -> Void) {
        if context.isPreview {
            completion(placeholder(in: context))
        } else {
            completion(currentEntry())
        }
    }

    func getTimeline(in context: Context, completion: @escaping (Timeline<PinnedEntry>) -> Void) {
        // 数据由主 App 写快照后 reloadAllTimelines 主动推;这里 30 分钟兜底刷一次
        // (只为让"x 天前"的相对时间不至于太陈旧)。
        let entry = currentEntry()
        let next = Calendar.current.date(byAdding: .minute, value: 30, to: .now) ?? .now
        completion(Timeline(entries: [entry], policy: .after(next)))
    }

    private func currentEntry() -> PinnedEntry {
        let snap = WidgetSnapshot.load()
        return PinnedEntry(date: .now, items: snap?.items ?? [], updatedAt: snap?.updatedAt)
    }

    static let sampleItems: [WidgetSnapshot.Item] = [
        .init(name: "收缩压", value: "128", unit: "mmHg", statusRaw: "normal",
              capturedAt: .now.addingTimeInterval(-3600 * 5)),
        .init(name: "空腹血糖", value: "6.4", unit: "mmol/L", statusRaw: "high",
              capturedAt: .now.addingTimeInterval(-3600 * 30)),
        .init(name: "体重", value: "68.5", unit: "kg", statusRaw: "normal",
              capturedAt: .now.addingTimeInterval(-3600 * 50)),
        .init(name: "尿酸", value: "486", unit: "μmol/L", statusRaw: "high",
              capturedAt: .now.addingTimeInterval(-3600 * 80)),
    ]
}

// MARK: - Views

private struct PinnedIndicatorsView: View {
    @Environment(\.widgetFamily) private var family
    let entry: PinnedEntry

    var body: some View {
        Group {
            if entry.items.isEmpty {
                emptyView
            } else {
                switch family {
                case .systemMedium: mediumView
                default:            smallView
                }
            }
        }
        .containerBackground(for: .widget) { KkColor.sand }
    }

    private var emptyView: some View {
        VStack(spacing: 6) {
            Image(systemName: "chart.line.uptrend.xyaxis")
                .font(.system(size: 22))
                .foregroundStyle(KkColor.text3)
            Text("在康康里关注指标后\n这里会显示最新值")
                .font(.system(size: 11))
                .multilineTextAlignment(.center)
                .foregroundStyle(KkColor.text3)
        }
    }

    /// 小尺寸:首条放大 + 其余最多 2 条小行。
    private var smallView: some View {
        VStack(alignment: .leading, spacing: 6) {
            header
            if let first = entry.items.first {
                VStack(alignment: .leading, spacing: 1) {
                    Text(first.name)
                        .font(.system(size: 11))
                        .foregroundStyle(KkColor.text2)
                    HStack(alignment: .firstTextBaseline, spacing: 3) {
                        Text(first.value)
                            .font(.system(size: 24, weight: .semibold, design: .rounded))
                            .foregroundStyle(statusColor(first.statusRaw))
                        Text(first.unit)
                            .font(.system(size: 10))
                            .foregroundStyle(KkColor.text3)
                    }
                }
            }
            ForEach(entry.items.dropFirst().prefix(2), id: \.name) { item in
                compactRow(item)
            }
            Spacer(minLength: 0)
        }
        .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading)
    }

    /// 中尺寸:两列网格,最多 6 条。
    private var mediumView: some View {
        VStack(alignment: .leading, spacing: 8) {
            header
            LazyVGrid(columns: [GridItem(.flexible(), spacing: 12), GridItem(.flexible())],
                      alignment: .leading, spacing: 8) {
                ForEach(entry.items.prefix(6), id: \.name) { item in
                    gridCell(item)
                }
            }
            Spacer(minLength: 0)
        }
        .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading)
    }

    private var header: some View {
        HStack(spacing: 4) {
            Text("康康 · 长期监测")
                .font(.system(size: 10, weight: .semibold))
                .foregroundStyle(KkColor.text3)
            Spacer()
            if let updatedAt = entry.updatedAt {
                Text(updatedAt, style: .relative)
                    .font(.system(size: 9))
                    .foregroundStyle(KkColor.text3)
            }
        }
    }

    private func compactRow(_ item: WidgetSnapshot.Item) -> some View {
        HStack(spacing: 4) {
            Circle()
                .fill(statusColor(item.statusRaw))
                .frame(width: 5, height: 5)
            Text(item.name)
                .font(.system(size: 10))
                .foregroundStyle(KkColor.text2)
                .lineLimit(1)
            Spacer(minLength: 2)
            Text(item.value)
                .font(.system(size: 11, weight: .semibold, design: .rounded))
                .foregroundStyle(KkColor.text)
        }
    }

    private func gridCell(_ item: WidgetSnapshot.Item) -> some View {
        VStack(alignment: .leading, spacing: 1) {
            HStack(spacing: 4) {
                Circle()
                    .fill(statusColor(item.statusRaw))
                    .frame(width: 5, height: 5)
                Text(item.name)
                    .font(.system(size: 10))
                    .foregroundStyle(KkColor.text2)
                    .lineLimit(1)
            }
            HStack(alignment: .firstTextBaseline, spacing: 2) {
                Text(item.value)
                    .font(.system(size: 15, weight: .semibold, design: .rounded))
                    .foregroundStyle(KkColor.text)
                Text(item.unit)
                    .font(.system(size: 8))
                    .foregroundStyle(KkColor.text3)
                    .lineLimit(1)
            }
        }
    }
}

// MARK: - Widget

struct PinnedIndicatorsWidget: Widget {
    var body: some WidgetConfiguration {
        StaticConfiguration(kind: "PinnedIndicatorsWidget", provider: PinnedProvider()) { entry in
            PinnedIndicatorsView(entry: entry)
        }
        .configurationDisplayName("长期监测")
        .description("展示你关注的健康指标最新值。数据 100% 在本机。")
        .supportedFamilies([.systemSmall, .systemMedium])
    }
}

#Preview("small", as: .systemSmall) {
    PinnedIndicatorsWidget()
} timeline: {
    PinnedEntry(date: .now, items: PinnedProvider.sampleItems, updatedAt: .now)
}

#Preview("medium", as: .systemMedium) {
    PinnedIndicatorsWidget()
} timeline: {
    PinnedEntry(date: .now, items: PinnedProvider.sampleItems, updatedAt: .now)
}
