from gtagora.exception import AgoraException
from gtagora.models.base import LinkToFolderMixin, BaseModel, DownloadDatasetMixin, SearchMixin, TagMixin
from gtagora.models.dataset import Dataset
from gtagora.models.timeline import TimelineItem


class Series(LinkToFolderMixin, DownloadDatasetMixin, TagMixin, BaseModel, SearchMixin):
    BASE_URL = '/api/v1/serie/'
    BASE_URL_V2 = '/api/v2/series/'

    def get_datasets(self, filters=None):
        if filters and not isinstance(filters, dict):
            raise AgoraException('The filter must be a dict')

        url = f'{self.BASE_URL}{self.id}/datasets/?limit=10000000000'
        return self._get_object_list(url, filters, Dataset)

    def upload(self, input_files, target_files=None):
        if target_files and len(input_files) != len(target_files):
            raise AgoraException("The Inputfiles and TargetFiles must have the same length")

        if isinstance(input_files, str):
            files = [input_files]
        else:
            files = input_files

        datasets = []
        for index, curFile in enumerate(files):
            cur_target_file = None
            if target_files:
                cur_target_file = target_files[index]
            datasets.append(Dataset.upload_files(self.http_client, curFile, cur_target_file, series_id=self.id))
        return datasets

    def upload_dataset(self, input_files, dataset_type, target_files=None):
        # This function creates a dataset of a given type all files given as input will be added to one dataset.
        # Please note: At the moment there is no consistency check. We could create datasets with improper
        # files (e.g. a PAR/REC dataset without PAR/REC files)
        return self.http_client.upload_dataset(input_files, target_files, serie_id=self.id, dataset_type=dataset_type)

    def get_parameter(self, name):
        datasets = self.get_datasets()
        for dataset in datasets:
            par = dataset.get_parameter(name)
            if par:
                return par

    def search_parameter(self, search_string):
        datasets = self.get_datasets()
        pars = []
        for dataset in datasets:
            cur_pars = dataset.search_parameter(search_string)
            pars.extend(cur_pars)
        return pars

    def copy_to_folder(self, target_folder_id):
        url = f'{self.BASE_URL_V2}{self.id}/copy_to_project/{target_folder_id}/'
        response = self.http_client.post(url, json={}, timeout=60)
        if response.status_code != 200:
            raise AgoraException(f'Could not copy the series: status = {response.status_code}')

        return self._get_new_series_from_timeline(response)

    def __str__(self):
        return f"Series: {self.name}"

    def _get_new_series_from_timeline(self, response):
        timeline_item = TimelineItem.from_response(response.json(), self.http_client)
        timeline_item = timeline_item.poll()
        if not timeline_item.data:
            return None

        related_objects = timeline_item.data.get('related_objects')
        if related_objects:
            for obj in related_objects:
                if obj.get('id') and obj.get('id') != self.id:
                    try:
                        return self.get(obj.get('id'), self.http_client)
                    except:
                        pass

        return None
