// ─── Result Types ────────────────────────────────────────────────────────────
//
// All pub result structs and enums for the `who` command family.
// Zero logic — pure data definitions.

/// Top-level run result: carries resolved inputs + the mode-specific result.
pub struct WhoRun {
    pub resolved_input: WhoResolvedInput,
    pub result: WhoResult,
}

/// Resolved query parameters -- computed once, used for robot JSON reproducibility.
pub struct WhoResolvedInput {
    pub mode: String,
    pub project_id: Option<i64>,
    pub project_path: Option<String>,
    pub since_ms: Option<i64>,
    pub since_iso: Option<String>,
    /// "default" (mode default applied), "explicit" (user provided --since), "none" (no window)
    pub since_mode: String,
    pub limit: Option<u16>,
}

/// Top-level result enum -- one variant per mode.
pub enum WhoResult {
    Expert(ExpertResult),
    Workload(WorkloadResult),
    Reviews(ReviewsResult),
    Active(ActiveResult),
    Overlap(OverlapResult),
}

// --- Expert ---

pub struct ExpertResult {
    pub path_query: String,
    /// "exact" or "prefix" -- how the path was matched in SQL.
    pub path_match: String,
    pub experts: Vec<Expert>,
    pub truncated: bool,
}

pub struct Expert {
    pub username: String,
    pub score: i64,
    /// Unrounded f64 score (only populated when explain_score is set).
    pub score_raw: Option<f64>,
    /// Per-component score breakdown (only populated when explain_score is set).
    pub components: Option<ScoreComponents>,
    pub review_mr_count: u32,
    pub review_note_count: u32,
    pub author_mr_count: u32,
    pub last_seen_ms: i64,
    /// Stable MR references like "group/project!123"
    pub mr_refs: Vec<String>,
    pub mr_refs_total: u32,
    pub mr_refs_truncated: bool,
    /// Per-MR detail breakdown (only populated when --detail is set)
    pub details: Option<Vec<ExpertMrDetail>>,
}

/// Per-component score breakdown for explain mode.
pub struct ScoreComponents {
    pub author: f64,
    pub reviewer_participated: f64,
    pub reviewer_assigned: f64,
    pub notes: f64,
}

#[derive(Clone)]
pub struct ExpertMrDetail {
    pub mr_ref: String,
    pub title: String,
    /// "R", "A", or "A+R"
    pub role: String,
    pub note_count: u32,
    pub last_activity_ms: i64,
}

// --- Workload ---

pub struct WorkloadResult {
    pub username: String,
    pub assigned_issues: Vec<WorkloadIssue>,
    pub authored_mrs: Vec<WorkloadMr>,
    pub reviewing_mrs: Vec<WorkloadMr>,
    pub unresolved_discussions: Vec<WorkloadDiscussion>,
    pub assigned_issues_truncated: bool,
    pub authored_mrs_truncated: bool,
    pub reviewing_mrs_truncated: bool,
    pub unresolved_discussions_truncated: bool,
}

pub struct WorkloadIssue {
    pub iid: i64,
    /// Canonical reference: `group/project#iid`
    pub ref_: String,
    pub title: String,
    pub project_path: String,
    pub updated_at: i64,
}

pub struct WorkloadMr {
    pub iid: i64,
    /// Canonical reference: `group/project!iid`
    pub ref_: String,
    pub title: String,
    pub draft: bool,
    pub project_path: String,
    pub author_username: Option<String>,
    pub updated_at: i64,
}

pub struct WorkloadDiscussion {
    pub entity_type: String,
    pub entity_iid: i64,
    /// Canonical reference: `group/project!iid` or `group/project#iid`
    pub ref_: String,
    pub entity_title: String,
    pub project_path: String,
    pub last_note_at: i64,
}

// --- Reviews ---

pub struct ReviewsResult {
    pub username: String,
    pub total_diffnotes: u32,
    pub categorized_count: u32,
    pub mrs_reviewed: u32,
    pub categories: Vec<ReviewCategory>,
}

pub struct ReviewCategory {
    pub name: String,
    pub count: u32,
    pub percentage: f64,
}

// --- Active ---

pub struct ActiveResult {
    pub discussions: Vec<ActiveDiscussion>,
    /// Count of unresolved discussions *within the time window*, not total across all time.
    pub total_unresolved_in_window: u32,
    pub truncated: bool,
}

pub struct ActiveDiscussion {
    pub discussion_id: i64,
    pub entity_type: String,
    pub entity_iid: i64,
    pub entity_title: String,
    pub project_path: String,
    pub last_note_at: i64,
    pub note_count: u32,
    pub participants: Vec<String>,
    pub participants_total: u32,
    pub participants_truncated: bool,
}

// --- Overlap ---

pub struct OverlapResult {
    pub path_query: String,
    /// "exact" or "prefix" -- how the path was matched in SQL.
    pub path_match: String,
    pub users: Vec<OverlapUser>,
    pub truncated: bool,
}

pub struct OverlapUser {
    pub username: String,
    pub author_touch_count: u32,
    pub review_touch_count: u32,
    pub touch_count: u32,
    pub last_seen_at: i64,
    /// Stable MR references like "group/project!123"
    pub mr_refs: Vec<String>,
    pub mr_refs_total: u32,
    pub mr_refs_truncated: bool,
}

/// Maximum MR references to retain per user in output (shared across modes).
pub const MAX_MR_REFS_PER_USER: usize = 50;
