import SwiftUI

/// A `git commit` rendered as a structured card — the remote's echo of the desktop `GitBlockCard`:
/// the commit subject reads as a headline and the message body as Markdown, so a commit in the
/// transcript is legible at a glance instead of a raw `git commit -F - <<'EOF' …` blob. The literal
/// command stays one tap away under "Show command", so the card never hides what actually ran.
struct GitCommitCard: View {
    let commit: GitCommitSummary.Commit
    /// The literal command, revealed under "Show command". Omit to hide the disclosure.
    var rawCommand: String? = nil
    /// The tool result text (e.g. the hash a trailing `git log --oneline -1` prints), shown
    /// beneath the card once the command has run. Omit inside an expanded tool card, where the
    /// result already shows as its own block.
    var output: String? = nil

    private var accent: Color { Palette.accent }

    var body: some View {
        VStack(alignment: .leading, spacing: 8) {
            HStack(alignment: .firstTextBaseline, spacing: 9) {
                Image(systemName: commit.amend ? "pencil.circle" : "checkmark.seal")
                    .font(.callout).foregroundStyle(accent).frame(width: 16)
                VStack(alignment: .leading, spacing: 2) {
                    Text(commit.amend ? "Amend commit" : "Commit")
                        .font(.caption.weight(.semibold))
                        .foregroundStyle(.secondary)
                    if !commit.subject.isEmpty {
                        Text(commit.subject)
                            .font(.callout.weight(.semibold))
                            .fixedSize(horizontal: false, vertical: true)
                            .textSelection(.enabled)
                    }
                }
            }
            if !commit.body.isEmpty {
                // The body is real commit-message Markdown (paragraphs, bullet lists) — render it
                // formatted, indented under the subject.
                MarkdownText(markdown: commit.body)
                    .padding(.leading, 25)
                    .textSelection(.enabled)
            }
            if let output, !output.isEmpty { outputRow(output) }
            if let rawCommand, !rawCommand.isEmpty {
                CommandDisclosure(command: rawCommand, accent: accent)
            }
        }
        .padding(.horizontal, 12).padding(.vertical, 10)
        .frame(maxWidth: .infinity, alignment: .leading)
        .background(accent.opacity(0.06))
        .overlay(RoundedRectangle(cornerRadius: 8).strokeBorder(accent.opacity(0.16), lineWidth: 1))
        .clipShape(RoundedRectangle(cornerRadius: 8))
    }

    /// The result text beneath the commit (e.g. the new hash a trailing `git log` prints), in the
    /// muted monospaced style the Mac's `GitBlockCard.outputRow` uses.
    private func outputRow(_ output: String) -> some View {
        HStack(alignment: .top, spacing: 9) {
            Image(systemName: "arrow.turn.down.right")
                .font(.caption2).foregroundStyle(.tertiary).frame(width: 16)
            Text(output)
                .font(.system(.caption, design: .monospaced))
                .foregroundStyle(.secondary)
                .lineLimit(3).truncationMode(.tail)
                .textSelection(.enabled)
            Spacer(minLength: 0)
        }
    }
}

/// A disclosure that reveals the literal shell command beneath a structured command card — so a
/// command rendered as a GUI element never hides what's actually being run. The remote's port of
/// the desktop `CommandDisclosure`.
struct CommandDisclosure: View {
    /// The literal command to reveal.
    let command: String
    /// The card's accent, applied to the toggle and the revealed block.
    let accent: Color

    @State private var showCommand = false

    var body: some View {
        VStack(alignment: .leading, spacing: 6) {
            Button {
                withAnimation(.easeInOut(duration: 0.15)) { showCommand.toggle() }
            } label: {
                HStack(spacing: 5) {
                    Image(systemName: "chevron.right")
                        .font(.caption2.weight(.semibold))
                        .rotationEffect(.degrees(showCommand ? 90 : 0))
                    Text(showCommand ? "Hide command" : "Show command")
                        .font(.caption.weight(.medium))
                }
                .foregroundStyle(accent)
                .contentShape(Rectangle())
            }
            .buttonStyle(.plain)
            if showCommand {
                Text(command)
                    .font(.system(.caption, design: .monospaced))
                    .foregroundStyle(.secondary)
                    .textSelection(.enabled)
                    .multilineTextAlignment(.leading)
                    .frame(maxWidth: .infinity, alignment: .leading)
                    .padding(8)
                    .background(accent.opacity(0.05), in: RoundedRectangle(cornerRadius: 6))
            }
        }
    }
}
