cell_lines = {
    "1205lu": "1205Lu",
    "22rv1": "22Rv1",
    "293t": "293T",
    "2ftgh": "2fTGH",
    "3t3-l1": "3T3-L1",
    "46c mescs": "46C mESCs",
    "786-o": "786-O",
    "8988t": "8988T",
    "a172": "A172",
    "a375": "A375",
    "a498": "A498",
    "a549": "A549",
    "a673": "A673",
    "ag04450": "AG04450",
    "ag04503": "AG04503",
    "ag04504": "AG04504",
    "ag06561": "AG06561",
    "ag09309": "AG09309",
    "ag09319": "AG09319",
    "ag10803": "AG10803",
    "an3ca": "AN3CA",
    "aspc-1": "AsPC-1",
    "asc52telo": "ASC52telo",
    "be2c": "BE2C",
    "bin67": "BIN67",
    "bj": "BJ",
    "blaer1": "BLaER1",
    "bt474": "BT474",
    "bt549": "BT549",
    "c2c12": "C2C12",
    "c3h/10t1/2": "C3H/10T1/2",
    "c4-2b": "C4-2B",
    "caco-2": "Caco-2",
    "caki2": "Caki2",
    "calu-3": "Calu-3",
    "calu3": "Calu3",
    "colo320dm": "COLO320DM",
    "cov434": "COV434",
    "d341med": "D341Med",
    "dnd-41": "DND-41",
    "dohh2": "DOHH2",
    "du145": "DU145",
    "e14tg2a": "E14tg2a",
    "elf-1": "ELF-1",
    "f123 hybrid esc": "F123 hybrid ESC",
    "g401": "G401",
    "gbm002": "GBM002",
    "gm03348": "GM03348",
    "gm04504": "GM04504",
    "gm06990": "GM06990",
    "gm12865": "GM12865",
    "gm12878": "GM12878",
    "gm12891": "GM12891",
    "gm12892": "GM12892",
    "gm18505": "GM18505",
    "gm18870": "GM18870",
    "gm18907": "GM18907",
    "gm18909": "GM18909",
    "gm18951": "GM18951",
    "gm19025": "GM19025",
    "gm19099": "GM19099",
    "gm19239": "GM19239",
    "gm19324": "GM19324",
    "gm21526": "GM21526",
    "gm23248": "GM23248",
    "gm23338": "GM23338",
    # "h1": "H1",
    "h1-hesc": "H1-hESC",
    "h1975": "H1975",
    "h4": "H4",
    "h54": "H54",
    "h7": "H7",
    "h9": "H9",
    "hap-1": "HAP-1",
    "hap1": "HAP1",
    "hcec 1ct": "HCEC 1CT",
    "hcc1954": "HCC1954",
    "hcc3153": "HCC3153",
    "hct116": "HCT116",
    "hek293": "HEK293",
    "hek293t": "HEK293T",
    "hek293wt": "HEK293WT",
    "hela-s3": "HeLa-S3",
    "hela": "HeLa",
    "hepg2": "HepG2",
    "hff-myc": "HFF-Myc",
    "hg02798": "HG02798",
    "hg02970": "HG02970",
    "hg03045": "HG03045",
    "hl-60": "HL-60",
    "hoxb8": "HoxB8",
    "ht-29": "HT-29",
    "ht1080": "HT1080",
    "ht1376": "HT1376",
    "ht29": "HT29",
    "hudep-2": "HUDEP-2",
    "hudep2": "HUDEP2",
    "hues48": "HUES48",
    "hues6": "HUES6",
    "hues64": "HUES64",
    "huh-7": "HuH-7",
    "huh7": "Huh7",
    "huvec": "HUVEC",
    "imr-90": "IMR-90",
    "ips df 19.11": "iPS DF 19.11",
    "ips df 6.9": "iPS DF 6.9",
    "ips-20b": "iPS-20b",
    "ips-nihi7": "iPS-NIHi7",
    "ishikawa": "Ishikawa",
    "jurkat": "Jurkat",
    "k562": "K562",
    "karpas-422": "Karpas-422",
    "kc167": "Kc167",
    "kms-11": "KMS-11",
    "koptk1": "KOPTK1",
    "l1-s8": "L1-S8",
    "l1-s8r": "L1-S8R",
    "lncap": "LNCaP",
    "loucy": "Loucy",
    "luhmes": "LUHMES",
    "mcf 10a": "MCF 10A",
    "mcf-7": "MCF-7",
    "mcf7": "MCF-7",
    "mcf10a": "MCF10A",
    "mda-mb-231": "MDA-MB-231",
    "mda-mb-453": "MDA-MB-453",
    # "mg63": "MG63",
    "mkl-1": "MKL-1",
    "molm-13": "MOLM-13",
    "mm.1s": "MM.1S",
    "mv4-11": "MV4-11",
    "namalwa": "NAMALWA",
    "nalm6": "Nalm6",
    "nb4": "NB4",
    "nci-h1417": "NCI-H1417",
    "nci-h1436": "NCI-H1436",
    "nci-h187": "NCI-H187",
    "nci-h2081": "NCI-H2081",
    "nci-h2171": "NCI-H2171",
    "nci-h226": "NCI-H226",
    "nci-h446": "NCI-H446",
    "nci-h510a": "NCI-H510A",
    "nci-h524": "NCI-H524",
    "nci-h526": "NCI-H526",
    "nci-h82": "NCI-H82",
    "nci-h929": "NCI-H929",
    "nih-3t3": "NIH-3T3",
    "nt2/d1": "NT2/D1",
    "oci-ly1": "OCI-LY1",
    "oci-ly3": "OCI-LY3",
    "oci-ly7": "OCI-LY7",
    "panc1": "PANC1",
    "pc-3": "PC-3",
    "pc-9": "PC-9",
    "pfsk-1": "PFSK-1",
    "raw264.7": "RAW264.7",
    "rh30": "RH30",
    "riva": "RIVA",
    "rko": "RKO",
    "rpmi-7951": "RPMI-7951",
    "rpmi-8226": "RPMI-8226",
    "rpmi7951": "RPMI-7951",
    "rpmi8226": "RPMI-8226",
    "rues2": "RUES2",
    "rues02": "RUES02",
    "sh-sy5y": "SH-SY5Y",
    "shp-77": "SHP-77",
    "shp77": "SHP-77",
    "sjsa1": "SJSA1",
    "sk-mel-5": "SK-MEL-5",
    "sk-n-dz": "SK-N-DZ",
    "sk-n-mc": "SK-N-MC",
    "sk-n-sh": "SK-N-SH",
    "skbr3": "SKBR3",
    "sp-49": "SP-49",
    "su-dhl-6": "SU-DHL-6",
    "sum149": "SUM149",
    "sum159": "SUM159",
    "sw480": "SW480",
    "t47d": "T47D",
    "thp-1": "THP-1",
    "u2os": "U2OS",
    "u937": "U937",
    "uacc-257": "UACC-257",
    "ut-7": "UT-7",
    "vcap": "VCaP",
    "vero e6": "VERO E6",
    "weri-rb-1": "WERI-Rb-1",
    "wi38": "WI38",
    "wtc11": "WTC11",
    "zr-75-1": "ZR-75-1",
}


assay_map = {
    # ---- TF & Histone ChIP (most specific first) ----
    "tf chip-seq": "TF ChIP-seq",
    "histone chip-seq": "Histone ChIP-seq",
    # "h3k27ac": "H3K27ac",
    # "h3k27me3": "H3K27me3",
    # "h3k9me2": "H3K9me2",
    # "h3k9me3": "H3K9me3",
    # "h3k4me3": "H3K4me3",
    # "h3k4me2": "H3K4me2",
    # "h3k4me1": "H3K4me1",
    # "h3k36me3": "H3K36me3",
    # "h3k79me2": "H3K79me2",
    # "h3k79me3": "H3K79me3",
    # "h3k27me1": "H3K27me1",
    # "h3k9ac": "H3K9ac",
    # "h3k14ac": "H3K14ac",
    # "h3k18ac": "H3K18ac",
    # "h3k23ac": "H3K23ac",
    # "h4k20me1": "H4K20me1",
    # "h4k20me3": "H4K20me3",
    # "h2ak119ub": "H2AK119ub",
    # "h2bk120ub": "H2BK120ub",
    "biotin chip-seq": "Biotin ChIP-seq",
    # ---- Generic ChIP ----
    "chip-seq": "ChIP-seq",
    "chip seq": "ChIP-seq",
    # ---- CUT-based assays ----
    "cut&tag": "CUT&Tag",
    "cut&run": "CUT&RUN",
    # ---- ATAC variants ----
    "snail atac-seq": "SNAIL ATAC-seq",
    "csnail atac-seq": "cSNAIL ATAC-seq",
    "scatac-seq": "scATAC-seq",
    "roboatac": "roboATAC",
    "atac-seq": "ATAC-seq",
    "atac": "ATAC-seq",
    # ---- DNase ----
    "gm dnase-seq": "GM DNase-seq",
    "dnase-hypersensitivity": "DNase-Hypersensitivity",
    "dnase-seq": "DNase-seq",
    # ---- RNA & derivatives ----
    "rampage": "RAMPAGE",
    "cage": "CAGE",
    "rna-seq": "RNA-Seq",
    "ncrna-seq": "ncRNA-Seq",
    "mirna-seq": "miRNA-Seq",
    "rip-seq": "RIP-Seq",
    "eclip": "eCLIP",
    "icl ip-seq": "iCLIP-seq",
    # ---- Chromatin conformation ----
    "hi-c": "Hi-C",
    "chia-pet": "ChIA-PET",
    # ---- Methylation & accessibility ----
    "medip-seq": "MeDIP-Seq",
    "mbd-seq": "MBD-Seq",
    "bisulfite-seq": "Bisulfite-Seq",
    "faire-seq": "FAIRE-seq",
    "mnase-seq": "MNase-Seq",
    # ---- Specialized ----
    "end-seq": "END-seq",
    "tn-seq": "Tn-Seq",
    "bruuvseq": "bruUVseq",
    "bruseq": "BruSeq",
    "selex": "SELEX",
    "starr-seq": "STARR-seq",
    "microrna counts": "microRNA counts",
    "mitoperturb-seq": "MitoPerturb-Seq",
    # ---- Fallback ----
    "other": "OTHER",
}


antibody = [
    "H3K27ac",
    "H3K27me3",
    "H3K9me2",
    "H3K9me3",
    "H3K4me3",
    "H3K4me2",
    "H3K4me1",
    "H3K36me3",
    "H3K79me2",
    "H3K79me3",
    "H3K27me1",
    "H3K9ac",
    "H3K14ac",
    "H3K18ac",
    "H3K23ac",
    "H4K20me1",
    "H4K20me3",
    "H2AK119ub",
    "H2BK120ub",
]


def standardize_cell_line(cell_line: str) -> str:
    """
    Standardize cell line names to a consistent format.

    :param cell_line: The input cell line name.
    :return: The standardized cell line name.
    """

    key = cell_line.lower()
    if key not in cell_lines:
        return cell_line
    return cell_lines.get(key, cell_line)


def standardize_assay(assay: str) -> str:
    """
    Standardize assay names to a consistent format.

    :param assay: The input assay name.
    :return: The standardized assay name.
    """

    key = assay.lower()
    if key not in assay_map:
        return assay
    return assay_map.get(key, assay)


def find_assay(description: str) -> str:
    """
    Identify the assay type from a given description string.
    e.g. "encff285mhb_idr_thresholded_peaks_grch38_bed TF ChIP-seq from K562 (ENCSR861UWB)"
    will return "TF ChIP-seq"

    :param description: The input description string.
    :return: The identified assay type or "" (empty string) if not found.
    """
    description_lower = description.lower()
    for key in assay_map.keys():
        if key in description_lower:
            return assay_map[key]
    return ""


def find_cell_line(description: str) -> str:
    """
    Identify the cell line from a given description string.

    e.g. encff285mhb_idr_thresholded_k562_peaks_grch38_bed
    will return "K562"

    :param description: The input description string.
    :return: The identified cell line or "" (empty string) if not found.
    """
    description_lower = description.lower()
    for key in cell_lines.keys():
        if key in description_lower:
            return cell_lines[key]
    return ""
