# Helper functions for exercises 8: PCA
import os

from typing import List, Dict

import numpy as np
import SimpleITK as sitk
import pydicom

import matplotlib.pyplot as plt

def hide_axis_ticks(
    ax: plt.Axes
) -> None:
    """ Hides the ticks and the numbers on both axes in the matplotlib
    Axes instance provided as argument.
    """
    ax.tick_params(axis='both', which='both', length=0)
    plt.setp(ax.get_xticklabels(), visible=False)
    plt.setp(ax.get_yticklabels(), visible=False)
    return

def load_cine_mri_data(
    directory: str,
    verbose: bool = True,
) -> List[np.ndarray]:
    """
    """

    def getDicomsInDirectory(
        directory: str,
    ) -> List[str]:
        """
            Get all dicom file inside directory by test reading them.
        """
        dicoms_files: List[str] = []
        try:
            for entry in os.listdir(directory):
                file_path = os.path.join(directory, entry)
                if os.path.isfile(file_path):
                    try:
                        ds: pydicom.FileDataset = pydicom.dcmread(file_path,
                                                                  stop_before_pixels=False)
                        if hasattr(ds, 'pixel_array'):
                            dicoms_files.append(file_path)
                    except:
                        pass
        except Exception as e:
            print(f"Failed to get dicoms in {directory}")
            raise e
        return dicoms_files

    def loadDicomMetaData(
        filepath: str,
    ) -> Dict[str, str]:
        reader = sitk.ImageFileReader()
        reader.SetFileName(filepath)
        reader.LoadPrivateTagsOn()
        reader.ReadImageInformation()

        dicom_metadata: Dict[str, str] = {}
        for k in reader.GetMetaDataKeys():
            v = reader.GetMetaData(k)
            dicom_metadata[k] = v
        return dicom_metadata

    def getTemporalPositionIdentifier(
        dicom_metadata: Dict[str, str],
    ) -> int:
        """
        """
        value = -1
        try:
            value = int(dicom_metadata['0020|0100'])
        except:
            pass
        return value

    def loadDicom2D(
        filepath: str,
        output_pixel_type = sitk.sitkFloat32,
    ) -> sitk.Image:
        """
        """
        image = sitk.ReadImage(filepath, output_pixel_type)
        image = sitk.Extract(image,
                             (image.GetWidth(), image.GetHeight(), 0),
                             (0, 0, 0))
        return image

    if verbose:
        print("Loading images in:")
        print(f"    {directory}")

    files = getDicomsInDirectory(directory)
    images_dict: Dict[int, sitk.image] = {}

    if verbose:
        print(f"Found {len(files)} images.")

    for file in files:
        image = loadDicom2D(file)
        metadata = loadDicomMetaData(file)
        key = getTemporalPositionIdentifier(metadata)
        images_dict[key] = image

    #images_list: List[sitk.Image] = []
    images_list: List[np.ndarray] = []
    keys = list(images_dict.keys())
    for key in keys:
        image_arr = sitk.GetArrayFromImage(images_dict[key])
        images_list.append(image_arr)

    if verbose:
        print("Finished loading images.")

    return images_list
