import SwiftUI

/// Small pill shown in the Commits section header trailing slot when the
/// worktree is behind a tracked ref. Purely informative. The `role` selects
/// a distinct theme color so the "behind base" and "behind upstream" chips
/// read as different things at a glance; the `label` names the target.
struct BehindChip: View {
    /// Which "behind" signal this chip represents. Drives the color.
    enum Role {
        case base       // behind the trunk you compare against (e.g. main)
        case upstream   // behind your branch's own remote tracking ref

        /// Theme color token for this role.
        var colorToken: String {
            switch self {
            case .base: return "accent"
            case .upstream: return "caution"
            }
        }
    }

    let count: Int
    let label: String
    let role: Role

    @Environment(\.theme) private var theme

    /// Pure text composition: `↓N label` (e.g. "↓3 main"). `↓` reads as
    /// "commits to pull in."
    static func displayText(count: Int, label: String) -> String {
        "↓\(count) \(label)"
    }

    var body: some View {
        let tint = theme.color(role.colorToken)
        return Text(Self.displayText(count: count, label: label))
            .font(.system(size: 9.5, weight: .semibold))
            .foregroundColor(tint)
            .lineLimit(1)
            .padding(.horizontal, 6).padding(.vertical, 1)
            .background(tint.opacity(0.12))
            .clipShape(Capsule())
    }
}

struct CommitsSectionView: View {
    let commits: [CommitInfo]
    let olderCommits: [CommitInfo]
    let comparisonRef: String?
    let hasMoreOlder: Bool
    let isLoadingOlder: Bool
    let behindBase: GitService.BehindStatus?
    let behindUpstream: GitService.BehindStatus?
    @Binding var expanded: Bool
    @Binding var baseBranch: String
    let branches: [String]
    let isLoadingBranches: Bool
    let hasLoadedBranches: Bool
    let onSelect: (CommitInfo) -> Void
    let onCopySHA: (CommitInfo) -> Void
    let onEdit: (CommitInfo) -> Void
    let onLoadOlder: () -> Void
    let onSelectBaseBranch: (String) -> Void
    let onOpenBaseBranchSelector: () -> Void
    let rps: RightPaneState

    @Environment(\.theme) private var theme

    var body: some View {
        Section {
            if expanded {
                expandedBody
            }
        } header: {
            SectionHeader(
                title: "Commits",
                count: totalCount,
                expanded: expanded,
                onToggle: { expanded.toggle() }
            ) {
                HStack(spacing: 6) {
                    if let s = behindBase {
                        BehindChip(count: s.count, label: baseBranch, role: .base)
                            .help("\(s.count) behind \(s.ref)")
                    }
                    if let s = behindUpstream {
                        BehindChip(count: s.count, label: "remote", role: .upstream)
                            .help("\(s.count) behind \(s.ref)")
                    }
                    BaseBranchSelector(
                        baseBranch: $baseBranch,
                        branches: branches,
                        isLoadingBranches: isLoadingBranches,
                        hasLoadedBranches: hasLoadedBranches,
                        currentRef: comparisonRef,
                        onSelect: onSelectBaseBranch,
                        onOpen: onOpenBaseBranchSelector
                    )
                    BranchOpsMenu(rps: rps)
                }
            }
        }
    }

    private var totalCount: Int? {
        let n = commits.count + olderCommits.count
        return n == 0 ? nil : n
    }

    @ViewBuilder
    private var expandedBody: some View {
        // 1. Worktree commits ("your work") OR today's empty placeholder.
        if !commits.isEmpty {
            ForEach(Array(commits.enumerated()), id: \.element.id) { idx, commit in
                CommitRow(
                    commit: commit,
                    isLast: idx == commits.count - 1 && olderCommits.isEmpty,
                    onSelect: { onSelect(commit) },
                    onCopySHA: { onCopySHA(commit) },
                    onEdit: { onEdit(commit) },
                    onCherryPick: { rps.runCherryPick(sha: commit.sha) }
                )
            }
        } else if olderCommits.isEmpty {
            emptyPlaceholder
        }

        // 2. Divider — only when older commits are shown AND we have a
        // comparison ref to label the boundary against.
        if !olderCommits.isEmpty, let ref = comparisonRef {
            dividerRow(label: ref)
        }

        // 3. Older commits — dimmed when comparisonRef exists, plain when not.
        if !olderCommits.isEmpty {
            ForEach(Array(olderCommits.enumerated()), id: \.element.id) { idx, commit in
                CommitRow(
                    commit: commit,
                    isLast: idx == olderCommits.count - 1,
                    isHistorical: comparisonRef != nil,
                    onSelect: { onSelect(commit) },
                    onCopySHA: { onCopySHA(commit) },
                    onCherryPick: { rps.runCherryPick(sha: commit.sha) }
                )
            }
        }

        // 4. Footer.
        footer
    }

    private var emptyPlaceholder: some View {
        Text(comparisonRef.map { "up to date with \($0)" } ?? "no comparison branch")
            .font(.system(size: 11))
            .foregroundColor(theme.color("fg-faint"))
            .padding(.horizontal, 12).padding(.vertical, 8)
            .frame(maxWidth: .infinity, alignment: .leading)
    }

    private func dividerRow(label: String) -> some View {
        HStack(spacing: 8) {
            Rectangle()
                .fill(theme.color("line"))
                .frame(height: 1)
            Text(label)
                .font(.system(size: 10, design: .monospaced))
                .foregroundColor(theme.color("fg-faint"))
                .textCase(.uppercase)
                .tracking(0.4)
            Rectangle()
                .fill(theme.color("line"))
                .frame(height: 1)
        }
        .padding(.horizontal, 12)
        .padding(.vertical, 6)
    }

    @ViewBuilder
    private var footer: some View {
        if isLoadingOlder {
            HStack(spacing: 6) {
                Spinner(lineWidth: 1.5, duration: 0.7)
                    .frame(width: 10, height: 10)
                Text("Loading…")
                    .font(.system(size: 11))
                    .foregroundColor(theme.color("fg-faint"))
            }
            .frame(maxWidth: .infinity, alignment: .center)
            .padding(.vertical, 8)
        } else if hasMoreOlder {
            Button(action: onLoadOlder) {
                Text("↓ Load older commits")
                    .font(.system(size: 11))
                    .foregroundColor(theme.color("accent"))
                    .frame(maxWidth: .infinity, alignment: .center)
                    .padding(.vertical, 8)
                    .contentShape(Rectangle())
            }
            .buttonStyle(.plain)
        } else if !olderCommits.isEmpty {
            Text("End of history")
                .font(.system(size: 11))
                .foregroundColor(theme.color("fg-faint"))
                .frame(maxWidth: .infinity, alignment: .center)
                .padding(.vertical, 8)
        }
    }
}
