use crate::graph::Hybridization;

/// Assign a UFF atom type label to an atom given its element, hybridization, and aromaticity.
///
/// Rules mirror RDKit's UFF atom-typing (rdForceFieldHelpers.cpp).
/// Atoms that cannot be typed fall back to "C_3" so the force field always has parameters.
pub fn assign_uff_type(element: u8, hyb: &Hybridization, is_aromatic: bool) -> &'static str {
    match element {
        1 => "H_",
        5 => "B_2",
        6 => {
            if is_aromatic {
                "C_R"
            } else {
                match hyb {
                    Hybridization::SP => "C_1",
                    Hybridization::SP2 => "C_2",
                    _ => "C_3", // SP3 and Unknown
                }
            }
        }
        7 => {
            if is_aromatic {
                "N_R"
            } else {
                match hyb {
                    Hybridization::SP => "N_1",
                    Hybridization::SP2 => "N_2",
                    _ => "N_3",
                }
            }
        }
        8 => {
            if is_aromatic {
                "O_R"
            } else {
                match hyb {
                    Hybridization::SP => "O_1",
                    Hybridization::SP2 => "O_2",
                    _ => "O_3",
                }
            }
        }
        9 => "F_",
        14 => "Si3",
        15 => "P_3",
        16 => {
            if is_aromatic {
                "S_R"
            } else {
                match hyb {
                    Hybridization::SP2 => "S_2",
                    _ => "S_3",
                }
            }
        }
        17 => "Cl",
        // Transition metals
        22 => "Ti3+4",
        23 => "V_3+5",
        24 => "Cr6+3",
        25 => "Mn6+2",
        26 => "Fe3+2",
        27 => "Co6+3",
        28 => "Ni4+2",
        29 => "Cu3+1",
        30 => "Zn3+2",
        // Additional main-group
        32 => "Ge3",
        33 => "As3",
        34 => "Se3",
        35 => "Br",
        42 => "Mo3+6",
        46 => "Pd4+2",
        47 => "Ag1+1",
        50 => "Sn3",
        51 => "Sb3",
        52 => "Te3",
        53 => "I_",
        78 => "Pt4+2",
        79 => "Au4+3",
        _ => "C_3",
    }
}

/// Determine whether a given atom is part of an aromatic ring by checking if any of its
/// bonds have `BondOrder::Aromatic`.
pub fn is_atom_aromatic(mol: &crate::graph::Molecule, idx: usize) -> bool {
    use petgraph::graph::NodeIndex;
    let node = NodeIndex::new(idx);
    for edge in mol.graph.edges(node) {
        if edge.weight().order == crate::graph::BondOrder::Aromatic {
            return true;
        }
    }
    false
}
