use std::collections::HashMap;

fn is_symbol(character: &char) -> bool {
    return !character.is_digit(10) && *character != '.';
}

#[derive(Debug, Clone)]
struct SchematicNumber {
    number: u16,
    surroundings: Vec<char>
}

impl SchematicNumber {
    fn is_part_number(&self) -> bool {
        self.surroundings.iter().any(is_symbol)
    }
}

#[derive(Debug)]
struct Gear {
    surroundings: Vec<SchematicNumber>
}

impl Gear {
    fn sum(&self) -> u64 {
        let mut part_number_count = 0;
        let mut part_number_mul: u64 = 1;

        for schematic_number in self.surroundings.iter() {
            if schematic_number.is_part_number() {
                part_number_count += 1;
                part_number_mul *= Into::<u64>::into(schematic_number.number);
            }
        }

        if part_number_count != 2 {
            return 0;
        }

        return part_number_mul;
    }
    fn add_number(&mut self, number: SchematicNumber) {
        self.surroundings.push(number);
    }
}

fn process_gear(number: &SchematicNumber, gears: &mut HashMap<(usize, usize), Gear>, row: usize, col: usize) {
    let position = gears.get_mut(&(row, col));

    if let Some(gear) = position {
        gear.add_number(number.clone())
    } else {
        gears.insert((row, col), Gear { surroundings: vec![ number.clone() ] });
    }
}

fn process_number(gears: &mut HashMap<(usize, usize), Gear>, input: &str, digits: String, row: usize, start_col: usize, end_col: usize) -> SchematicNumber {
    let mut surroundings: Vec<char> = vec![];

    let input_lines: Vec<&str> = input.split('\n').collect();
    let prev_line: Vec<char> = (if row > 0 { input_lines[row - 1] } else { "" }).chars().collect();
    let current_line: Vec<char> = input_lines[row].chars().collect();
    let next_line: Vec<char> = (if row < input_lines.len() - 1 { input_lines[row + 1] } else { "" }).chars().collect();

    let mut gear_positions: Vec<(usize, usize)> = vec![];

    if start_col > 0 {
        surroundings.push(current_line[start_col - 1]);
        if current_line[start_col - 1] == '*' {
            gear_positions.push((row, start_col - 1));
        }
    }

    if end_col < current_line.len() - 1 {
        surroundings.push(current_line[end_col + 1]);
        if current_line[end_col + 1] == '*' {
            gear_positions.push((row, end_col + 1));
        }
    }

    if !prev_line.is_empty() {
        for col in start_col..end_col+1 {
            surroundings.push(prev_line[col]);
            if prev_line[col] == '*' {
                gear_positions.push((row - 1, col));
            }
        }
        if start_col > 0 {
            surroundings.push(prev_line[start_col - 1]);
            if prev_line[start_col - 1] == '*' {
                gear_positions.push((row - 1, start_col - 1));
            }
        }
        if end_col < prev_line.len() - 1 {
            surroundings.push(prev_line[end_col + 1]);
            if prev_line[end_col + 1] == '*' {
                gear_positions.push((row - 1, end_col + 1));
            }
        }
    }

    if !next_line.is_empty() {
        for col in start_col..end_col+1{
            surroundings.push(next_line[col]);
            if next_line[col] == '*' {
                gear_positions.push((row + 1, col));
            }
        }
        if start_col > 0 {
            surroundings.push(next_line[start_col - 1]);
            if next_line[start_col - 1] == '*' {
                gear_positions.push((row + 1, start_col - 1));
            }
        }
        if end_col < next_line.len() - 1 {
            surroundings.push(next_line[end_col + 1]);
            if next_line[end_col + 1] == '*' {
                gear_positions.push((row + 1, end_col + 1));
            }
        }
    }

    println!("Surroundings: {:?}, digits: {}", surroundings, digits);

    let schematic_number = SchematicNumber {
        number: digits.parse().unwrap(),
        surroundings
    };

    println!("{:#?}: is_part_number: {}", schematic_number, schematic_number.is_part_number());

    for pos in gear_positions {
        process_gear(&schematic_number, gears, pos.0, pos.1);
    }

    schematic_number
}

fn main() {
    let input = include_str!("../input.txt");

    let mut numbers: Vec<SchematicNumber> = vec![];
    let mut gears: HashMap<(usize, usize), Gear> = HashMap::new();

    let mut number_start: Option<usize> = None;
    let mut number_digits = "".to_owned();

    // Find numbers and their surroundings
    for (row, line) in input.split('\n').enumerate() {
        for (col, character) in line.chars().enumerate() {
            match (number_start, character.is_digit(10)) {
                (Some(_), true) => {
                    number_digits.push(character);
                    println!("{} is still a digit. number_digits is now {}", character, number_digits);
                },
                (Some(start_col), false) => {
                    numbers.push(process_number(&mut gears, input, number_digits, row, start_col, col - 1));
                    number_digits = "".to_owned();
                    number_start = None;
                },
                (None, true) => {
                    number_digits.push(character);
                    number_start = Some(col);
                    println!("{} is a digit. Starting a new number at postition {} with number_digits {}", character, number_start.unwrap(), number_digits);
                },
                (None, false) => {}
            }
        }
        if let Some(start_col) = number_start {
            numbers.push(process_number(&mut gears, input, number_digits, row, start_col, line.len() - 1));
            number_digits = "".to_owned();
            number_start = None;
        }
    }

    let mut numbers_total: u64 = 0;
    let mut gears_total: u64 = 0;

    for number in numbers {
        println!("{:?}, part_no: {}", number, number.is_part_number());
        if number.is_part_number() {
            numbers_total += Into::<u64>::into(number.number);
        }
    }

    for gear in gears.values() {
        println!("{:?}, sum: {}", gear, gear.sum());
        gears_total += gear.sum();
    }

    println!("{}", numbers_total);
    println!("{}", gears_total);
}
