from collections import defaultdict
from datetime import timedelta

from allotropy.allotrope.models.shared.definitions.custom import (
    TNullableQuantityValueGramPerLiter,
    TNullableQuantityValueMillimolePerLiter,
    TNullableQuantityValueUnitPerLiter,
)

# Measurements of a sample have different timestamps, typically spaced closely together (max diff observed - 9 min)
# Some result files have multiple sets of measurements, over multiple days.
# Measurements with a time difference greater than MAX_MEASUREMENT_TIME_GROUP_DIFFERENCE from the last
# measurement recorded will be put into separate groups.
MAX_MEASUREMENT_TIME_GROUP_DIFFERENCE = timedelta(hours=1)


MOLAR_CONCENTRATION_CLASSES: list[
    (
        type[TNullableQuantityValueMillimolePerLiter]
        | type[TNullableQuantityValueGramPerLiter]
        | type[TNullableQuantityValueUnitPerLiter]
    )
] = [
    TNullableQuantityValueMillimolePerLiter,
    TNullableQuantityValueGramPerLiter,
    TNullableQuantityValueUnitPerLiter,
]

MOLAR_CONCENTRATION_CLS_BY_UNIT = {cls.unit: cls for cls in MOLAR_CONCENTRATION_CLASSES}


INFO_HEADER = [
    "row type",
    "data processing time",
    "col3",
    "col4",
    "col5",
    "col6",
    "model number",
    "device serial number",
    "software version",
    "analyst",
]

DATA_HEADER_V6 = [
    "row type",
    "measurement time",
    "sample identifier",
    "batch identifier",
    "sample role type",
    "col6",
    "analyte name",
    "col8",
    "concentration unit",
    "flag",
    "concentration value",
    "col12",
    "col13",
]

DATA_HEADER_V5 = [
    "row type",
    "measurement time",
    "analyte name",
    "col4",
    "col5",
    "sample identifier",
    "sample role type",
    "concentration unit",
    "flag",
    "concentration value",
    "col10",
    "col11",
]


ANALYTES_LOOKUP = {
    "AC2B": "acetate",
    "AC2D": "acetate",
    "AQB": "alanine-glutamine",
    "AQD": "alanine-glutamine",
    "AQQB": "alanine-glutamine corrected",
    "NH3LB": "ammonia",
    "NH3B": "ammonia",
    "NH3D": "ammonia",
    "ARAB": "arabinose",
    "ARAD": "arabinose",
    "ASNLB": "asparagine",
    "ASNHB": "asparagine",
    "ASNHD": "asparagine",
    "ASPB": "aspartate",
    "ASPD": "aspartate",
    "CA2B": "calcium",
    "CA2D": "calcium",
    "CHO2B": "cholesterol",
    "CHO2D": "cholesterol",
    "ETOHB": "ethanol",
    "ETOHD": "ethanol",
    "FORB": "formate",
    "FORD": "formate",
    "GAL2B": "galactose",
    "GAL2D": "galactose",
    "GLC2L": "glucose",
    "GLC2B": "glucose",
    "GLC2D": "glucose",
    "GLC3D": "glucose",
    "GLC3B": "glucose",
    "GLC3L": "glucose",
    "GLU2B": "glutamate",
    "GLU2D": "glutamate",
    "GLN2B": "glutamine",
    "GLN2D": "glutamine",
    "GLYB": "glycerol",
    "GLYD": "glycerol",
    "GLYE": "glycerol",
    "FABLA": "Ig Fab human",
    "FABLB": "Ig Fab human",
    "FABHB": "Ig Fab human",
    "FABHD": "Ig Fab human",
    "IGGLB": "IgG human",
    "IGGHB": "IgG human",
    "IGGHD": "IgG human",
    "MIGLB": "IgG mouse",
    "MIGHB": "IgG mouse",
    "MIGHD": "IgG mouse",
    "FE2B": "iron",
    "FE2D": "iron",
    "LAC2B": "lactate",
    "LAC2D": "lactate",
    "LDH2B": "ldh",
    "LDH2D": "ldh",
    "MG2L": "magnesium",
    "MG2B": "magnesium",
    "MG2D": "magnesium",
    "NO3L": "nitrate",
    "NO3B": "nitrate",
    "NO3D": "nitrate",
    "PHO2L": "phosphate",
    "PHO2B": "phosphate",
    "PHO2D": "phosphate",
    "KB": "potassium",
    "KD": "potassium",
    "PYRB": "pyruvate",
    "PYRD": "pyruvate",
    "NAB": "sodium",
    "NAD": "sodium",
    "SUCB": "sucrose",
    "SUCD": "sucrose",
    "SUGLB": "sucrose corrected",
    "SUGLD": "sucrose corrected",
    "TP2B": "total protein",
    "TP2D": "total protein",
    "TP2LB": "total protein",
    "ODB": "optical_density",
    "ODD": "optical_density",
    "OSM2B": "osmolality",
}

DETECTION_KIT_LOOKUP = {
    "AC2B": "Standard",
    "AC2D": "High with Pre - Dilution",
    "AQB": "Standard",
    "AQD": "High with Pre - Dilution",
    "AQQB": "Standard",
    "NH3LB": "Low",
    "NH3B": "Standard",
    "NH3D": "High with Pre - Dilution",
    "ARAB": "Standard",
    "ARAD": "High with Pre - Dilution",
    "ASNLB": "Low",
    "ASNHB": "Standard",
    "ASNHD": "High with Pre - Dilution",
    "ASPB": "Standard",
    "ASPD": "High with Pre - Dilution",
    "CA2B": "Standard",
    "CA2D": "High with Pre - Dilution",
    "CHO2B": "Standard",
    "CHO2D": "High with Pre - Dilution",
    "ETOHB": "Standard",
    "ETOHD": "High with Pre - Dilution",
    "FORB": "Standard",
    "FORD": "High with Pre - Dilution",
    "GAL2B": "Standard",
    "GAL2D": "High with Pre - Dilution",
    "GLC2L": "Low",
    "GLC2B": "Standard",
    "GLC2D": "High with Pre - Dilution",
    "GLC3D": "High with Pre - Dilution",
    "GLC3B": "Standard",
    "GLC3L": "Low",
    "GLU2B": "Standard",
    "GLU2D": "High with Pre - Dilution",
    "GLN2B": "Standard",
    "GLN2D": "High with Pre - Dilution",
    "GLYB": "Low",
    "GLYD": "Standard",
    "GLYE": "High with Pre - Dilution",
    "FABLA": "Low",
    "FABLB": "Standard",
    "FABHB": "High",
    "FABHD": "High with Pre - Dilution",
    "IGGLB": "Low",
    "IGGHB": "Standard",
    "IGGHD": "High with Pre - Dilution",
    "MIGLB": "Low",
    "MIGHB": "Standard",
    "MIGHD": "High with Pre - Dilution",
    "FE2B": "Standard",
    "FE2D": "High with Pre - Dilution",
    "LAC2B": "Standard",
    "LAC2D": "High with Pre - Dilution",
    "LDH2B": "Standard",
    "LDH2D": "High with Pre - Dilution",
    "MG2L": "Low",
    "MG2B": "Standard",
    "MG2D": "High with Pre - Dilution",
    "NO3L": "Low",
    "NO3B": "Standard",
    "NO3D": "High with Pre - Dilution",
    "PHO2L": "Low",
    "PHO2B": "Standard",
    "PHO2D": "High with Pre - Dilution",
    "KB": "Standard",
    "KD": "High with Pre - Dilution",
    "PYRB": "Standard",
    "PYRD": "High with Pre - Dilution",
    "NAB": "Standard",
    "NAD": "High with Pre - Dilution",
    "SUCB": "Standard",
    "SUCD": "High with Pre - Dilution",
    "SUGLB": "Standard",
    "SUGLD": "High with Pre - Dilution",
    "TP2B": "Standard",
    "TP2D": "High with Pre - Dilution",
    "TP2LB": "Low",
}

DETECTION_KIT_RANGE_LOOKUP = {
    "AC2B": "0.25 - 38.9 mmol/L",
    "AC2D": "14 - 389 mmol/L",
    "AQB": "0.1 - 10 mmol/L",
    "AQD": "1 - 100 mmol/L",
    "NH3LB": "0.0278 - 1.389 mmol/L",
    "NH3B": " 0.278 - 13.89 mmol/L",
    "NH3D": "5.56 - 277.8 mmol/L",
    "ARAB": "0.055 - 27.75 mmol/L",
    "ARAD": "0.55 - 277.5 mmol/L",
    "ASNLB": "0.1 - 1 mmol/L",
    "ASNHB": "0.5 - 9 mmol/L",
    "ASNHD": "2.5 - 45 mmol/L",
    "ASPB": "0.1 - 9 mmol/L",
    "ASPD": "1 - 45 mmol/L",
    "CA2B": "0.2 - 5 mmol/L",
    "CA2D": "2 - 50 mmol/L",
    "CHO2B": "0.025 - 2.07 mmol/L",
    "CHO2D": "0.25 - 20.7 mmol/L",
    "ETOHB": "11 - 220 mmol/L",
    "ETOHD": "220 - 4400 mmol/L",
    "FORB": "0.2 - 20 mmol/L",
    "FORD": "2 - 200 mmol/L",
    "GAL2B": "0.055 - 27.75 mmol/L",
    "GAL2D": "0.55 - 277.5 mmol/L",
    "GLC2L": "0.011 - 4.163 mmol/L",
    "GLC2B": "0.111 - 41.63 mmol/L",
    "GLC2D": "1.11 - 416.3 mmol/L",
    "GLC3D": "1.11 - 416.3 mmol/L",
    "GLC3B": "0.111 - 41.63 mmol/L",
    "GLC3L": "0.011 - 4.163 mmol/L",
    "GLU2B": "0.099 - 10.2 mmol/L",
    "GLU2D": "0.99 - 102 mmol/L",
    "GLN2B": "0.1 - 10.26 mmol/L",
    "GLN2D": "0.5 - 51.3 mmol/L",
    "GLYB": "0.1 - 10 mmol/L",
    "GLYD": "1 - 100 mmol/L",
    "GLYE": "10 - 1000 mmol/L ",
    "FABLA": "0.13 - 0.35 g/L",
    "FABLB": "0.01 - 0.4 g/L",
    "FABHB": "0.3 - 8 g/L",
    "FABHD": "6 - 40 g/L",
    "IGGLB": "0.000067 - 0.000533 mmol/L",
    "IGGHB": "0.000533 - 0.01067 mmol/L",
    "IGGHD": "0.002665 - 0.05335 mmol/L ",
    "MIGLB": "0.01 - 0.2 g/L",
    "MIGHB": "0.2 - 1.5 g/L",
    "MIGHD": "1 - 7.5 g/L",
    "FE2B": "0.0009 - 0.179 mmol/L",
    "FE2D": "0.009 - 1.79 mmol/L ",
    "LAC2B": "0.0444 - 15.55 mmol/L",
    "LAC2D": "0.444 - 155.5 mmol/L ",
    "LDH2B": "20 - 1000 U/L",
    "LDH2D": "200 - 10000 U/L",
    "MG2L": "0.01 - 0.25 mmol/L",
    "MG2B": "0.1 - 2.5 mmol/L",
    "MG2D": "2.3 - 25 mmol/L",
    "NO3L": "0.2 - 4 mmol/L",
    "NO3B": "1 - 25 mmol/L",
    "NO3D": "15 - 250 mmol/L",
    "PHO2L": "0.01 - 0.837 mmol/L",
    "PHO2B": "0.1 - 8.37 mmol/L",
    "PHO2D": "1.1 - 92.07 mmol/L",
    "KB": "2 - 28 mmol/L",
    "KD": "24 - 280 mmol/L",
    "PYRB": "0.2 - 8 mmol/L",
    "PYRD": "2 - 80 mmol/L",
    "NAB": "50 - 275 mmol/L",
    "NAD": "250 - 1375 mmol/L",
    "SUCB": "0.292 - 40.9 mmol/L",
    "SUCD": "2.92 - 409 mmol/L",
    "SUGLB": "0.292 - 40.9 mmol/L",
    "SUGLD": "2.92 - 409 mmol/L",
    "TP2B": "4 - 120 g/L",
    "TP2D": "40 - 1200 g/L",
    "TP2LB": "0.3 - 6.0 g/L",
}

SAMPLE_ROLE_TYPES = {"SAM": "Sample"}

SOLUTION_ANALYZER = "solution-analyzer"
OPTICAL_DENSITY = "optical_density"
BELOW_TEST_RANGE = "< TEST RNG"

FLAG_TO_ERROR = defaultdict(
    lambda: "unknown",
    {
        "v": "verification",
        "c": "calibration",
        BELOW_TEST_RANGE: BELOW_TEST_RANGE,
    },
)
