import SwiftUI
import SwiftData

/// 趋势 Tab。日历已迁至主页;此页专注「时间序列」:
/// 任何出现 ≥2 次的指标都能成趋势,分「长期监测」(seriesKey)与「化验指标」(按名归并)两段。
struct TrendsView: View {
    @Query(sort: \Indicator.capturedAt, order: .reverse)
    private var indicators: [Indicator]

    @Query private var profiles: [UserProfile]
    @Query private var customMetrics: [CustomMonitorMetric]

    private var profile: UserProfile? { profiles.first }

    /// 顶部搜索:点放大镜展开搜索框,按指标名(bucket.title)实时过滤两段列表。
    @State private var searching = false
    @State private var query = ""

    private var seriesBuckets: [SeriesBucket] {
        SeriesBucket.build(from: indicators,
                           profile: profile,
                           customMetrics: customMetrics)
    }

    private func filtered(_ buckets: [SeriesBucket]) -> [SeriesBucket] {
        let q = query.trimmingCharacters(in: .whitespaces)
        guard !q.isEmpty else { return buckets }
        return buckets.filter { $0.title.localizedCaseInsensitiveContains(q) }
    }

    var body: some View {
        // SeriesBucket.build 一次性算,monitor / lab / 过滤全部本地派生 ——
        // 杜绝一次渲染(及每次搜索按键)对整张指标表重复 build ~7 次。
        let series = seriesBuckets
        let monitor = filtered(series.filter { $0.kind == .monitor })
        let lab = filtered(series.filter { $0.kind == .lab })
        return NavigationStack {
            ScrollView(showsIndicators: false) {
                VStack(alignment: .leading, spacing: 18) {
                    header.padding(.top, 4)
                    if series.isEmpty {
                        emptyState
                    } else if monitor.isEmpty && lab.isEmpty {
                        noMatchState
                    } else {
                        if !monitor.isEmpty {
                            section(title: String(appLoc: "长期监测"), buckets: monitor)
                        }
                        if !lab.isEmpty {
                            section(title: String(appLoc: "化验指标趋势"), buckets: lab)
                        }
                    }
                }
                .padding(.horizontal, 20)
                .padding(.bottom, 24)
            }
            .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading)
            .background(Tj.Palette.sand.ignoresSafeArea())
            .navigationBarHidden(true)
        }
    }

    private var header: some View {
        VStack(alignment: .leading, spacing: 12) {
            HStack(alignment: .lastTextBaseline) {
                Text("趋势")
                    .font(.tjTitle(26))
                    .foregroundStyle(Tj.Palette.text)
                Spacer()
                searchToggle
            }
            if searching { searchField }
        }
    }

    private var searchToggle: some View {
        Button {
            withAnimation(.easeInOut(duration: 0.18)) {
                searching.toggle()
                if !searching { query = "" }
            }
        } label: {
            Image(systemName: searching ? "xmark" : "magnifyingglass")
                .font(.tjScaled( 15, weight: .semibold))
                .foregroundStyle(Tj.Palette.text)
                .frame(width: 36, height: 36)
                .background(Circle().fill(Tj.Palette.sand2))
        }
        .buttonStyle(.plain)
        .accessibilityLabel(searching ? String(appLoc: "关闭搜索") : String(appLoc: "搜索指标"))
    }

    private var searchField: some View {
        HStack(spacing: 8) {
            Image(systemName: "magnifyingglass")
                .font(.tjScaled( 13))
                .foregroundStyle(Tj.Palette.text3)
            TextField(String(appLoc: "搜索指标名"), text: $query)
                .textInputAutocapitalization(.never)
                .autocorrectionDisabled()
                .foregroundStyle(Tj.Palette.text)
                .tint(Tj.Palette.ink)
            if !query.isEmpty {
                Button { query = "" } label: {
                    Image(systemName: "xmark.circle.fill")
                        .foregroundStyle(Tj.Palette.text3)
                }
                .buttonStyle(.plain)
            }
        }
        .padding(.horizontal, 12)
        .padding(.vertical, 10)
        .background(
            RoundedRectangle(cornerRadius: Tj.Radius.sm, style: .continuous)
                .fill(Tj.Palette.paper)
        )
        .overlay(
            RoundedRectangle(cornerRadius: Tj.Radius.sm, style: .continuous)
                .strokeBorder(Tj.Palette.line, lineWidth: 1)
        )
    }

    private var noMatchState: some View {
        VStack(spacing: 12) {
            TjPlaceholder(label: String(appLoc: "没有匹配「\(query)」的指标"))
                .frame(height: 120)
                .frame(maxWidth: 260)
        }
        .frame(maxWidth: .infinity)
        .padding(.top, 60)
    }

    private func section(title: String, buckets: [SeriesBucket]) -> some View {
        VStack(alignment: .leading, spacing: 12) {
            HStack(alignment: .lastTextBaseline) {
                Text(title)
                    .font(.tjH2())
                    .foregroundStyle(Tj.Palette.text)
                Text("\(buckets.count) 项")
                    .font(.tjScaled( 12))
                    .foregroundStyle(Tj.Palette.text3)
                Spacer()
            }

            VStack(spacing: 12) {
                ForEach(buckets) { bucket in
                    NavigationLink {
                        TrendDetailView(bucket: bucket)
                    } label: {
                        TrendRow(bucket: bucket)
                    }
                    .buttonStyle(.plain)
                }
            }
        }
    }

    private var emptyState: some View {
        VStack(spacing: 12) {
            TjPlaceholder(label: String(appLoc: "还没有可成趋势的指标"))
                .frame(height: 120)
                .frame(maxWidth: 260)
            Text("同一指标记录满 2 次后,会在这里出现时间序列")
                .font(.tjScaled( 12))
                .foregroundStyle(Tj.Palette.text3)
                .multilineTextAlignment(.center)
        }
        .frame(maxWidth: .infinity)
        .padding(.top, 60)
    }
}

#Preview {
    TrendsView()
        .modelContainer(for: [
            Indicator.self, Report.self, DiaryEntry.self, Symptom.self, Asset.self
        ], inMemory: true)
}
