class MoveIssues(object):
    def __init__(self, api_key: str, api_path: str, move_from: str, move_to: str, age: int):
        """
        Move Issues Init
        :param api_key: The api key for auth user
        :param api_path: Path to the api
        :param move_from: ID string of project to move tasks from
        :param move_to: ID string of project to move tasks from
        :param age: Find issues with an actual completion date greater than this value in months.
        """
        self.api_key = api_key
        self.api_path = api_path
        self.move_from = move_from
        self.move_to = move_to
        self.age = age
        # Can't bluk move more than 100 elements as per API restrictions
        self.max_results = 100
        self.completion_date_str = "$$TODAY-{age}m".format(age=self.age)
        self.client = StreamClient(self.api_path, self.api_key)

    def go(self):
        """
        Starts the moving process.
        """
        results_len = 1  # Just something to get us started
        while results_len > 0:
            issues = self.find_issues()
            results_len = len(issues)
            iss_move_count = self.move_issues(issues)
            if results_len > 0:
                results_str = "Moved {result_count} items".format(result_count=iss_move_count)
                print(results_str)

        print("Operation complete")

    def find_issues(self):
        """
        Finds issues in 'from' project to be moved.
        :return: a list of issues that meet the criteria
        """
        params = {
            "$$LIMIT": self.max_results,
            "projectID": self.move_from,
            "projectID_Mod": "in",
            "actualCompletionDate": self.completion_date_str,
            "actualCompletionDate_Mod": "lte"
        }
        fields = {}
        results = AtTaskObject(self.client.search(ObjCode.ISSUE, params, fields))
        return results.data

    def move_issues(self, data) -> int:
        """
        Moves issues between projects
        :param data: list of issues
        :return: count of issues moved
        """
        counter = 0
        for item in data:
            # Get the ID number
            uid = item['ID']
            params = {'projectID': self.move_to}
            AtTaskObject(self.client.action(ObjCode.ISSUE, 'move', params, objid=uid))
            print(".", end="", flush=True)
            counter += 1
        return counter

    def get_proj_name(self, proj_id: str):
        """
        Gets the name of a project from ID
        :param proj_id: ID number of the project to get the name of
        :return: Name of the project
        """
        results = AtTaskObject(self.client.get(ObjCode.PROJECT, proj_id))
        return results.data['name']

    def get_number_of_issues_to_move(self):
        """
        Get's a count of the number of issues to be moved
        :return: a count of the number of issues to be moved
        """
        params = {
            "projectID": self.move_from,
            "projectID_Mod": "in",
            "actualCompletionDate": self.completion_date_str,
            "actualCompletionDate_Mod": "lte"
        }
        results = AtTaskObject(self.client.report(ObjCode.ISSUE, params, 'sum'))
        return results.data['dcount_ID']