from typing import Optional

from chemrecon.chem.mol import Mol
from chemrecon.chem.create_mol import mol_from_structurerepresentation
from chemrecon.schema import MolStructureRepr, MolStructure
from chemrecon.schema.db_object import ProceduralGeneratorError, ProceduralRelation


class MolStructureConvert(ProceduralRelation[MolStructureRepr, MolStructure]):
    """ Standardized and canonical conversion of molecular structure representations (e.g. SMILES, InChI, ...) into
        a consistent format, stored as a canonical SMILES string.
    """
    # Attributes

    # Database
    entrytype_name = 'MolStructureConvert'
    _table_name = 'MolStructureConvert'
    symmetric = False
    source_entrytype = MolStructureRepr
    target_entrytype = MolStructure
    _attribute_columns = []
    _index = []

    def __init__(
        self,
        recon_id_1: Optional[int] = None,
        recon_id_2: Optional[int] = None
    ):
        super().__init__(recon_id_1, recon_id_2)


    @classmethod
    def generate(
        cls, take_entry: MolStructureRepr
    ) -> list[tuple[ProceduralRelation[MolStructureRepr, MolStructure], MolStructure]]:

        try:
            mol: Mol = mol_from_structurerepresentation(take_entry, template = True)
            new_entry: MolStructure = mol.to_database_struct()
            return [
                (
                    MolStructureConvert(),
                    new_entry
                )
            ]

        except Exception as e:
            # Failed for this item
            raise ProceduralGeneratorError(f'Creating molecule failed for {take_entry.source_id}') from e