import SessionCore
import SwiftUI
import WireProtocol

/// T-iOS-14 · "What happened while I was away" banner rendered above the
/// terminal after a reconnect. Render-only: `GateViewModel` owns the state —
/// an ALL-ZERO digest never reaches this view (the VM keeps `digest` nil),
/// the collapsed row auto-fades after `Tunables.digestFadeDelay`, and manual
/// expansion (which cancels the fade) reveals the recent entries.
struct AwayDigestView: View {
    let digest: AwayDigest
    let isExpanded: Bool
    let onExpand: () -> Void
    let onDismiss: () -> Void

    private enum Metrics {
        /// Recent entries shown when expanded (newest kept — the engine's
        /// digest is uncapped, the banner must not be).
        static let maxRecentRows = 12
    }

    private enum Copy {
        static let prefix = "离开期间："
        static let separator = " · "
        static let expandTitle = "展开明细"
        static let dismissTitle = "关闭摘要"
    }

    /// Summary line: non-zero parts only, joined web-statusline style. A
    /// non-empty digest whose counted signals are all zero (e.g. only `user`
    /// events) falls back to a plain activity count so the row is never blank.
    static func summary(for digest: AwayDigest) -> String {
        let parts = [
            digest.toolRuns > 0 ? "工具调用 \(digest.toolRuns) 次" : nil,
            digest.waitingCount > 0 ? "等待审批 \(digest.waitingCount) 次" : nil,
            digest.sawDone ? "已完成" : nil,
            digest.sawStuck ? "曾卡住" : nil,
        ].compactMap { $0 }
        guard !parts.isEmpty else {
            return "\(Copy.prefix)活动 \(digest.recent.count) 条"
        }
        return Copy.prefix + parts.joined(separator: Copy.separator)
    }

    var body: some View {
        VStack(alignment: .leading, spacing: DS.Space.sm8) {
            summaryRow
            if isExpanded {
                recentRows
            }
        }
        .padding(.horizontal, DS.Space.md12)
        .padding(.vertical, DS.Space.sm8)
        .background(.regularMaterial, in: RoundedRectangle(cornerRadius: DS.Radius.md12))
        .overlay(
            RoundedRectangle(cornerRadius: DS.Radius.md12)
                .strokeBorder(DS.Palette.hairline, lineWidth: DS.Stroke.hairline)
        )
        .accessibilityElement(children: .contain)
    }

    private var summaryRow: some View {
        HStack(spacing: DS.Space.sm8) {
            Image(systemName: "clock.arrow.circlepath")
                .foregroundStyle(DS.Palette.accent)
            Text(Self.summary(for: digest))
                .font(DS.Typography.callout.weight(.medium))
                .foregroundStyle(DS.Palette.textPrimary)
                .lineLimit(1)
            Spacer(minLength: DS.Space.sm8)
            if !isExpanded {
                Button(Copy.expandTitle, systemImage: "chevron.down", action: onExpand)
                    .labelStyle(.iconOnly)
            }
            Button(Copy.dismissTitle, systemImage: "xmark", action: onDismiss)
                .labelStyle(.iconOnly)
        }
        .buttonStyle(.borderless)
        .tint(DS.Palette.accent)
        .font(DS.Typography.callout)
    }

    /// Newest `maxRecentRows` entries, oldest→newest. Server text (`label`) is
    /// untrusted display input — rendered as plain Text only.
    private var recentRows: some View {
        VStack(alignment: .leading, spacing: DS.Space.xs4) {
            ForEach(
                Array(digest.recent.suffix(Metrics.maxRecentRows).enumerated()),
                id: \.offset
            ) { _, event in
                recentRow(event)
            }
        }
    }

    private func recentRow(_ event: TimelineEvent) -> some View {
        HStack(spacing: DS.Space.sm8) {
            Text(Self.time(of: event))
                .font(DS.Typography.metaMono)
                .foregroundStyle(DS.Palette.textSecondary)
            Text(event.label)
                .font(DS.Typography.caption)
                .foregroundStyle(DS.Palette.textPrimary)
                .lineLimit(1)
        }
    }

    private static func time(of event: TimelineEvent) -> String {
        let millisecondsPerSecond = 1_000.0
        let date = Date(timeIntervalSince1970: Double(event.at) / millisecondsPerSecond)
        return date.formatted(date: .omitted, time: .shortened)
    }
}
