import os
from datetime import date, datetime
from importlib.metadata import PackageNotFoundError, version
from importlib.resources import as_file, files


_DEFAULT_TEMPLATE_RESOURCE = "assets/RWE_template.pptx"

_DEFAULT_SLIDE4_ANCHORS = {
    "aou": (306000, 1110629, 5315528, 2686727),
    "ukb": (6276035, 1114132, 5419390, 2732276),
    "survey": (599025, 4035903, 4688785, 2360422),
}


def _send_shape_to_back(slide, shape) -> None:
    sp_tree = slide.shapes._spTree
    sp = shape._element
    sp_tree.remove(sp)
    sp_tree.insert(2, sp)


def _replace_title_slide_text(slide, gene: str, indications: list[str], report_date: str) -> None:
    from pptx.util import Pt
    cleaned_indications = [indication.replace("_", " ").strip() for indication in indications if indication.strip()]
    indication_text = ", ".join(cleaned_indications) if cleaned_indications else "general"
    for shape in slide.shapes:
        if not getattr(shape, "has_text_frame", False):
            continue
        text = shape.text.strip()
        if "Real world evidence for" in text:
            text_frame = shape.text_frame
            title_font_size = Pt(60)
            text_frame.clear()
            p = text_frame.paragraphs[0]
            lead_run = p.add_run()
            lead_run.text = "Real world evidence for "
            lead_run.font.size = title_font_size
            gene_run = p.add_run()
            gene_run.text = gene
            gene_run.font.italic = True
            gene_run.font.size = title_font_size
            suffix_run = p.add_run()
            suffix_run.text = f" - {indication_text}"
            suffix_run.font.size = title_font_size
        elif "Deepro Banerjee" in text and "Arrowhead Pharmaceuticals" in text:
            shape.text = (
                "Deepro Banerjee, Shicheng Guo\n"
                f"{report_date}\n"
                "Translational Genetics and Data Science\n"
                "Arrowhead Pharmaceuticals"
            )
    return

def _extract_slide4_anchors(slide, mso_shape_type):
    picture_shapes = [s for s in slide.shapes if s.shape_type == mso_shape_type.PICTURE]
    picture_shapes = sorted(picture_shapes, key=lambda s: (s.top, s.left))
    if len(picture_shapes) >= 3:
        return {
            "aou": (picture_shapes[0].left, picture_shapes[0].top, picture_shapes[0].width, picture_shapes[0].height),
            "ukb": (picture_shapes[1].left, picture_shapes[1].top, picture_shapes[1].width, picture_shapes[1].height),
            "survey": (picture_shapes[2].left, picture_shapes[2].top, picture_shapes[2].width, picture_shapes[2].height),
        }
    return _DEFAULT_SLIDE4_ANCHORS.copy()


def _populate_slide4(slide, aou_plot: str | None, ukb_plot: str | None, survey_plot: str | None, mso_shape_type) -> None:
    anchors = _extract_slide4_anchors(slide, mso_shape_type)

    for shape in list(slide.shapes):
        if shape.shape_type == mso_shape_type.PICTURE:
            shape.element.getparent().remove(shape.element)
    if aou_plot and os.path.exists(aou_plot):
        left, top, width, height = anchors["aou"]
        aou_picture = slide.shapes.add_picture(aou_plot, left, top, width=width, height=height)
        _send_shape_to_back(slide, aou_picture)
    if ukb_plot and os.path.exists(ukb_plot):
        left, top, width, height = anchors["ukb"]
        ukb_picture = slide.shapes.add_picture(ukb_plot, left, top, width=width, height=height)
        _send_shape_to_back(slide, ukb_picture)
    if survey_plot and os.path.exists(survey_plot):
        left, top, width, height = anchors["survey"]
        survey_picture = slide.shapes.add_picture(survey_plot, left, top, width=width, height=height)
        _send_shape_to_back(slide, survey_picture)
    return

def generate_rwe_presentation(
    gene: str,
    indications: str | list[str] | None = None,
    output_dir: str = "",
    report_date: str = "",
    allofus: bool = True,
    astrazeneca: bool = True,
    genebass: bool = True,
) -> str:
    """
    Generate a 6-slide RWE PPTX from the template.

    Slide behavior:
    1. Title slide: update gene, indications, and date.
    2. Keep as template.
    3. Keep as template.
    4. Clinical safety slide with AoU + UKB (AZN preferred, GeneBass fallback) Manhattan plots and AoU survey plot.
       These plots are expected to already exist in output_dir from the DOCX generation step.
    5. Keep as template.
    6. Keep as template.
    """
    try:
        from pptx import Presentation
        from pptx.enum.shapes import MSO_SHAPE_TYPE
    except ImportError as exc:
        raise ImportError(
            "python-pptx is required to generate PowerPoint files. Install with: pip install python-pptx"
        ) from exc

    if isinstance(indications, str):
        indications_list = [x for x in indications.split(",") if x]
    else:
        indications_list = indications or []
    if not report_date:
        report_date = date.today().strftime("%B %d, %Y")

    if not output_dir:
        output_dir = "./rwe_reports"
    os.makedirs(output_dir, exist_ok=True)

    date_tag = datetime.today().strftime("%m%d%y")
    indication_part = "-".join(indications_list) if indications_list else "general"
    try:
        pkg_version = version("rwe")
    except PackageNotFoundError:
        pkg_version = "unknown"
    out_pptx_path = os.path.join(
        output_dir,
        f"RWE_{gene}_{indication_part}_report_{date_tag}_v{pkg_version}.pptx",
    )

    aou_plot = None
    if allofus:
        candidate = os.path.join(output_dir, f"{gene}_aou_phewas.png")
        if os.path.exists(candidate):
            aou_plot = candidate

    ukb_plot = None
    if astrazeneca:
        candidate = os.path.join(output_dir, f"{gene}_azn_phewas.png")
        if os.path.exists(candidate):
            ukb_plot = candidate
    if ukb_plot is None and genebass:
        candidate = os.path.join(output_dir, f"{gene}_genebass_phewas.png")
        if os.path.exists(candidate):
            ukb_plot = candidate

    survey_plot = None
    if allofus:
        candidate = os.path.join(output_dir, f"{gene}_aou_surveys.png")
        if os.path.exists(candidate):
            survey_plot = candidate
        else:
            candidate = os.path.join(output_dir, f"{gene}_aou_survey.png")
            if os.path.exists(candidate):
                survey_plot = candidate

    template_resource = files("rwe").joinpath(_DEFAULT_TEMPLATE_RESOURCE)
    with as_file(template_resource) as template_fs_path:
        prs = Presentation(str(template_fs_path))

    if len(prs.slides) < 6:
        raise ValueError("Template must contain at least 6 slides.")

    _replace_title_slide_text(prs.slides[0], gene, indications_list, report_date)
    _populate_slide4(prs.slides[3], aou_plot, ukb_plot, survey_plot, MSO_SHAPE_TYPE)

    prs.save(out_pptx_path)
    return out_pptx_path
