from enum import Enum
from typing import ClassVar, List, Optional

from pydantic import BaseModel


class ReactionFormat(Enum):
    SMILES = "smiles"
    # RXNBLOCK = 'rxnblock'


class Software(BaseModel):
    name: str
    version: str


class QueryReactionString(BaseModel):
    query_id: str
    input_string: str

    class Config:
        schema_extra = {
            "example": {
                "input_string": "CC(Cl)=O.CN>>CNC(C)=O",
                "query_id": "1",
            }
        }


class ResultsReactionString(BaseModel):
    query_id: str
    output_string: Optional[str] = None
    confidence: Optional[float] = None
    notes: Optional[dict] = None
    success: bool

    class Config:
        schema_extra = {
            "example": {
                "reaction_smiles_mapped": "Cl[C:3]([CH3:4])=[O:5].[CH3:1][NH2:2]>>[CH3:1][NH:2][C:3]([CH3:4])=[O:5]",
                "query_id": "1",
                "confidence": 0.981,
                "success": True,
                "notes": {},
            }
        }


## endpoints I/O
class Metadata(BaseModel):
    ci_toolkit: Software
    a2a_mapper: Software

    class Config:
        schema_extra = {
            "example": {
                "ci_toolkit": {"name": "RDKit", "version": "2022.09.1"},
                "a2a_mapper": {"name": "rxnmapper", "version": "0.2.4"},
            }
        }


class RunBatchInp(BaseModel):
    query_data: List[QueryReactionString]
    inp_fmt: str
    out_fmt: str

    query_data_field: ClassVar[str] = "query_data"
    parameter_fields: ClassVar[List[str]] = [
        "inp_fmt",
        "out_fmt",
    ]

    class Config:
        schema_extra = {
            "example": {
                "classification_code": "namerxn",
                "inp_fmt": "smiles",
                "out_fmt": "smiles",
                "mapping_style": "matching",
                "query_data": [
                    {"input_string": "CC(Cl)=O.CN.CC#N>>CNC(C)=O.O", "query_id": "1"}
                ],
            }
        }


class RunBatchOut(BaseModel):
    metadata: Metadata
    query_parameters: dict
    output: dict
    # success_list: List[ResultsReactionString]
    # failure_list: List[QueryReactionString]
    outcome: dict

    class Config:
        schema_extra = {
            "example": {
                "metadata": {
                    "ci_toolkit": {"name": "RDKit", "version": "2022.09.1"},
                    "a2a_mapper": {"name": "rxnmapper", "version": "0.2.4"},
                },
                "query_parameters": {"inp_fmt": "smiles", "out_fmt": "smiles"},
                "output": {
                    "successes_list": [
                        {
                            "query_id": "1",
                            "output_string": "CC#N.Cl[C:3]([CH3:4])=[O:5].[CH3:1][NH2:2]>>[CH3:1][NH:2][C:3]([CH3:4])=[O:5].[OH2:6]",
                            "confidence": 0.981,
                            "notes": {},
                            "success": True,
                        }
                    ],
                    "failure_list": [],
                },
                "outcome": {},
            }
        }


endpoint_info_map = {
    "metadata": {
        "ep_url": "metadata",
        "input_schema": None,
        "output_schema": Metadata,
        "request_method": "get",
    },
    "run_batch": {
        "ep_url": "run_batch",
        "input_schema": RunBatchInp,
        "output_schema": RunBatchOut,
        "request_method": "post",
    },
}
