import pubchempy as pcp
from pubchemprops.pubchemprops import get_second_layer_props

from pif_compiler.functions.common_log import get_logger

logger = get_logger()

def clean_property_data(api_response):
    """
    Simplifies the API response data by flattening nested structures.
    
    Args:
        api_response (dict): Raw API response containing property data
        
    Returns:
        dict: Cleaned data with simplified structure
    """
    cleaned_data = {}
    
    for property_name, measurements in api_response.items():
        cleaned_measurements = []
        
        for measurement in measurements:
            cleaned_measurement = {
                'ReferenceNumber': measurement.get('ReferenceNumber'),
                'Description': measurement.get('Description', ''),
            }
            
            # Handle Reference field
            if 'Reference' in measurement:
                # Check if Reference is a list or string
                ref = measurement['Reference']
                cleaned_measurement['Reference'] = ref[0] if isinstance(ref, list) else ref
            
            # Handle Value field
            value = measurement.get('Value', {})
            if isinstance(value, dict) and 'StringWithMarkup' in value:
                cleaned_measurement['Value'] = value['StringWithMarkup'][0]['String']
            else:
                cleaned_measurement['Value'] = str(value)
                
            # Remove empty values
            cleaned_measurement = {k: v for k, v in cleaned_measurement.items() if v}
            
            cleaned_measurements.append(cleaned_measurement)
            
        cleaned_data[property_name] = cleaned_measurements
    
    return cleaned_data

def pubchem_dap(cas):
    '''
    Data un CAS in input ricerca le informazioni per la scheda di sicurezza su PubChem.
    Per estrarre le proprietà di 1o (sinonimi, cid, logP, MolecularWeight, ExactMass, TPSA) livello uso Pubchempy.
    Per quelle di 2o livello uso pubchemprops (Melting point)

    args:
    cas : string

    '''
    try:
        # Ricerca iniziale
        logger.info(f"Searching PubChem for CAS: {cas}")
        out = pcp.get_synonyms(cas, 'name')
        if out:
            out = out[0]
            output = {'CID' : out['CID'],
                    'CAS' : cas,
                    'first_pubchem_name' : out['Synonym'][0],
                    'pubchem_link' : f"https://pubchem.ncbi.nlm.nih.gov/compound/{out['CID']}"}
            logger.info(f"Found PubChem entry for {cas}: CID {out['CID']}")
        else:
            logger.warning(f"No results on PubChem for {cas}")
            return f'No results on PubChem for {cas}'

    except Exception as E:
        logger.error(f'Error during pubchem search for {cas}', exc_info=True)
        return None

    try:
        # Ricerca delle proprietà
        logger.debug(f"Fetching first level properties for CID {output['CID']}")
        properties = pcp.get_properties(['xlogp', 'molecular_weight', 'tpsa', 'exact_mass'], identifier = out['CID'], namespace='cid', searchtype=None, as_dataframe=False)
        if properties:
            output = {**output, **properties[0]}
            logger.debug(f"Successfully retrieved first level properties for {cas}")
        else:
            logger.warning(f"No first level properties found for {cas}")
            return output
    except Exception as E:
        logger.error(f'Error during pubchem first level properties extraction for {cas}', exc_info=True)

    try:
        # Ricerca del Melting Point
        logger.debug(f"Fetching second level properties for {output['first_pubchem_name']}")
        second_layer_props = get_second_layer_props(output['first_pubchem_name'], ['Melting Point', 'Dissociation Constants', 'pH'])
        if second_layer_props:
            second_layer_props = clean_property_data(second_layer_props)
            output = {**output, **second_layer_props}
            logger.debug(f"Successfully retrieved second level properties for {cas}")
    except Exception as E:
        logger.error(f'Error during pubchem second level properties extraction for {cas}', exc_info=True)

    return output

if __name__ == "__main__":
    # Esempio di utilizzo
    cas_number = "64-17-5"  # CAS per l'etanolo
    result = pubchem_dap(cas_number)
    print(result)