"""LICENSE
Copyright 2020 Hermann Krumrey <hermann@krumreyh.com>

This file is part of otaku-info.

otaku-info is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

otaku-info is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with otaku-info.  If not, see <http://www.gnu.org/licenses/>.
LICENSE"""

from typing import Dict, Any, Optional
from otaku_info.enums import MediaType, MediaSubType, \
    ReleasingState, MediaRelationType, ListService
from otaku_info.external.entities.AnimeListItem import AnimeListItem


class AnilistItem(AnimeListItem):
    """
    Class that models a general anilist list item
    Represents the information fetched using anilist's API
    """

    @property
    def myanimelist_id(self) -> Optional[int]:
        """
        :return: The myanimelist ID
        """
        mal_id = self.extra_ids.get(ListService.MYANIMELIST)
        if mal_id is not None and mal_id.isdigit():
            return int(mal_id)
        else:
            return None

    @classmethod
    def from_query(cls, media_type: MediaType, data: Dict[str, Any]) \
            -> "AnilistItem":
        """
        Generates an AnilistItem from a dictionary generated by an APi query
        :param media_type: The media type of the item
        :param data: The data to use
        :return: The generated AnilistItem
        """
        _media_subtype = data["format"]
        if _media_subtype is None:
            _media_subtype = "unknown"
        media_subtype = MediaSubType(_media_subtype.lower())

        _releasing_state = data["status"]
        if _releasing_state is None:
            _releasing_state = "unknown"
        releasing_state = ReleasingState(_releasing_state.lower())

        relations = {}
        for edge in data["relations"]["edges"]:
            node_id = edge["node"]["id"]
            node_type = MediaType(edge["node"]["type"].lower())
            relation_type = MediaRelationType(edge["relationType"].lower())
            relations[(node_type, node_id)] = relation_type

        extra_ids = {}
        mal_id = data["idMal"]
        if mal_id is not None:
            extra_ids[ListService.MYANIMELIST] = str(mal_id)

        return AnilistItem(
            data["id"],
            ListService.ANILIST,
            extra_ids,
            media_type,
            media_subtype,
            data["title"]["english"],
            data["title"]["romaji"],
            data["coverImage"]["large"],
            data["chapters"],
            data["volumes"],
            data["episodes"],
            releasing_state,
            relations
        )
