from __future__ import annotations

from rdkit import Chem


def activate_fragment(smiles: str, strategy: str = "smart") -> Chem.Mol:
    mol = Chem.MolFromSmiles(smiles)
    if mol is None:
        raise ValueError(f"Invalid SMILES string: {smiles}")

    target_idx = -1

    if strategy == "smart":
        for smarts in ("[N;!H0]", "[O;H1]", "[S;H1]"):
            pattern = Chem.MolFromSmarts(smarts)
            if pattern is None:
                continue
            matches = mol.GetSubstructMatches(pattern)
            if matches:
                target_idx = matches[0][0]
                break
        if target_idx == -1:
            strategy = "random"

    if strategy == "random":
        carbon_candidates: list[int] = []
        other_candidates: list[int] = []
        for atom in mol.GetAtoms():
            if atom.GetTotalNumHs() == 0:
                continue
            if atom.GetAtomicNum() == 6:
                carbon_candidates.append(atom.GetIdx())
            else:
                other_candidates.append(atom.GetIdx())
        candidates = carbon_candidates or other_candidates
        if not candidates:
            raise ValueError("No suitable atoms with hydrogens found to attach to.")
        target_idx = candidates[0]

    if target_idx == -1:
        raise ValueError("Could not identify a target atom for activation.")

    rwmol = Chem.RWMol(mol)
    dummy_idx = rwmol.AddAtom(Chem.Atom(0))
    rwmol.AddBond(target_idx, dummy_idx, Chem.BondType.SINGLE)

    result = rwmol.GetMol()
    Chem.SanitizeMol(result)
    return result
