from enum import Enum
from typing import Callable, Optional

from backend.app.db.models.uploaded_file import FileTypeEnum


class CoreFiles(Enum):
    PHOTOPACK = "Photopack"
    SITENOTE = "SiteNote"
    RDSAP_SITENOTE = "RdSAP_SiteNote"
    PAS2023_VENTILATION = "PAS 2023 Ventilation Assessment Report"
    PAS2023_CONDITION = "PAS 2023 Condition Report"
    PAS_SIGNIFICANCE = "PAS Significance"
    PAR_PHOTOPACK = "PAR Photo Pack"
    PAS2023_PROPERTY = "PAS 2023 Property Assessment Report"
    PAS2023_OCCUPANCY = "PAS 2023 Occupancy Assessment Report"
    IMPROVEMENT_OPTION_EVALUATION = "Improvement Option Evaluation"
    MEDIUM_TERM_IMPROVEMENT_PLAN = "Medium Term Improvement Plan"
    RETROFIT_DESIGN_DOC = "Retrofit Design Doc"


_MATCHERS: list[tuple[Callable[[str], bool], str]] = [
    (lambda f: f.startswith(CoreFiles.PHOTOPACK.value), FileTypeEnum.PHOTO_PACK.value),
    (lambda f: f.startswith(CoreFiles.SITENOTE.value), FileTypeEnum.SITE_NOTE.value),
    (
        lambda f: f.startswith(CoreFiles.RDSAP_SITENOTE.value),
        FileTypeEnum.RD_SAP_SITE_NOTE.value,
    ),
    (
        lambda f: f.startswith(CoreFiles.PAS2023_VENTILATION.value),
        FileTypeEnum.PAS_2023_VENTILATION.value,
    ),
    (
        lambda f: f.startswith(CoreFiles.PAS2023_CONDITION.value),
        FileTypeEnum.PAS_2023_CONDITION.value,
    ),
    (
        lambda f: f.startswith(CoreFiles.PAS_SIGNIFICANCE.value),
        FileTypeEnum.PAS_SIGNIFICANCE.value,
    ),
    (
        lambda f: f.startswith(CoreFiles.PAR_PHOTOPACK.value),
        FileTypeEnum.PAR_PHOTO_PACK.value,
    ),
    (
        lambda f: f.startswith(CoreFiles.PAS2023_PROPERTY.value),
        FileTypeEnum.PAS_2023_PROPERTY.value,
    ),
    (
        lambda f: f.startswith(CoreFiles.PAS2023_OCCUPANCY.value),
        FileTypeEnum.PAS_2023_OCCUPANCY.value,
    ),
    (
        lambda f: CoreFiles.IMPROVEMENT_OPTION_EVALUATION.value in f,
        FileTypeEnum.IMPROVEMENT_OPTION_EVALUATION.value,
    ),
    (
        lambda f: CoreFiles.MEDIUM_TERM_IMPROVEMENT_PLAN.value in f,
        FileTypeEnum.MEDIUM_TERM_IMPROVEMENT_PLAN.value,
    ),
    (lambda f: "-OSM-" in f and "DR-N-A" in f, FileTypeEnum.RETROFIT_DESIGN_DOC.value),
]


def infer_file_type(filename: str) -> Optional[str]:
    for matcher, file_type in _MATCHERS:
        if matcher(filename):
            return file_type
    return None
