// Definition for a binary tree node.
// #[derive(Debug, PartialEq, Eq)]
// pub struct TreeNode {
//   pub val: i32,
//   pub left: Option<Rc<RefCell<TreeNode>>>,
//   pub right: Option<Rc<RefCell<TreeNode>>>,
// }
//
// impl TreeNode {
//   #[inline]
//   pub fn new(val: i32) -> Self {
//     TreeNode {
//       val,
//       left: None,
//       right: None
//     }
//   }
// }

use std::cell::RefCell;
use std::convert::TryInto;
use std::rc::Rc;

impl Solution {
    fn max_sum(levels: &mut Vec<i32>, level: usize, root: Option<Rc<RefCell<TreeNode>>>) {
        if root == None {
            return;
        }

        let r = root.unwrap();

        if level >= levels.len() {
            levels.resize(level + 1, 0);
        }
        levels[level] += r.borrow().val;

        Solution::max_sum(levels, level + 1, r.borrow().left.clone());
        Solution::max_sum(levels, level + 1, r.borrow().right.clone());
    }

    pub fn max_level_sum(root: Option<Rc<RefCell<TreeNode>>>) -> i32 {
        let mut levels = vec![];

        Solution::max_sum(&mut levels, 0, root);

        levels
            .iter()
            .enumerate()
            .fold((0, i32::MIN), |(max_l, max_s), (l, s)| {
                if *s > max_s {
                    (l + 1, *s)
                } else {
                    (max_l, max_s)
                }
            })
            .0
            .try_into()
            .unwrap()
    }
}