///| PR Review operations

///|
/// Submit a review for a Pull Request
pub fn Hub::submit_review(
  self : Hub,
  objects : &@lib.ObjectStore,
  refs : &@lib.RefStore,
  clock : &@lib.Clock,
  pr_id : String,
  author : String,
  verdict : ReviewVerdict,
  body : String,
  commit_id : @bit.ObjectId,
) -> PrReview raise @bit.GitError {
  // Verify PR exists and is open
  let pr = self.get_pr(objects, pr_id)
  guard pr is Some(existing) else {
    raise @bit.GitError::InvalidObject("PR not found: \{pr_id}")
  }
  if existing.state != PrState::Open {
    raise @bit.GitError::InvalidObject("PR is not open: \{pr_id}")
  }
  let timestamp = clock.now()
  // Generate review ID from content hash
  let review = PrReview::new(
    "", pr_id, author, verdict, body, timestamp, commit_id,
  )
  let review_data = review.serialize()
  let (blob_id, _compressed) = @bit.create_blob_string(review_data)
  let review_id = short_hex(blob_id.to_hex(), 8)
  // Create final review with ID
  let final_review = PrReview::new(
    review_id, pr_id, author, verdict, body, timestamp, commit_id,
  )
  ignore(
    self.store.put_record(
      objects,
      refs,
      clock,
      pr_review_key(pr_id, review_id),
      "pr.review",
      final_review.serialize(),
      author,
    ),
  )
  final_review
}

///|
/// List reviews for a Pull Request
pub fn Hub::list_reviews(
  self : Hub,
  objects : &@lib.ObjectStore,
  pr_id : String,
) -> Array[PrReview] {
  let result : Array[PrReview] = []
  let records = self.store.list_records(objects, pr_review_prefix(pr_id))
  for record in records {
    if record.kind != "pr.review" {
      continue
    }
    let review = parse_pr_review(record.payload) catch { _ => continue }
    result.push(review)
  }
  result.sort_by(fn(a, b) {
    if a.created_at < b.created_at {
      -1
    } else if a.created_at > b.created_at {
      1
    } else {
      0
    }
  })
  result
}

///|
/// Check if a PR is approved (has at least one Approved review with no RequestChanges after it)
pub fn Hub::is_approved(
  self : Hub,
  objects : &@lib.ObjectStore,
  pr_id : String,
) -> Bool {
  let reviews = self.list_reviews(objects, pr_id)
  if reviews.length() == 0 {
    return false
  }
  let latest_verdicts : Map[String, ReviewVerdict] = Map([])
  for review in reviews {
    latest_verdicts[review.author] = review.verdict
  }
  let mut has_approval = false
  for item in latest_verdicts.to_array() {
    let (_, verdict) = item
    match verdict {
      Approved => has_approval = true
      RequestChanges => return false
      Comment => ()
    }
  }
  has_approval
}

///|