from datetime import datetime
from django.core.paginator import Paginator
from domain.dataset import DataSet
from imdb.models import EpisodeModel, MediaModel, EpisodeEffectiveTimeModel


class Episode(DataSet):
    """media在数据库中允许重复"""
    model = EpisodeModel

    def detail(self, episode_id):
        episode_obj = self.model.objects.filter(pk=episode_id).first()
        episode = self.to_dict(episode_obj)
        return episode

    def check(self, _ids):
        count = 0
        if _ids and str(_ids).find("-") != -1:
            _ids = str(_ids).replace("\t", "").replace(" ", "")
            media_id, episode_id = _ids.split("-")
            count = self.model.objects.filter(pk=episode_id, media_id=media_id).count()
        return {"count": count}

    @classmethod
    def _get_list(cls, query_set, page, page_size):
        pager = Paginator(query_set, page_size)
        obj_list = pager.get_page(page)
        episode_list = []
        for i in obj_list:
            episode = Episode.to_dict(i)
            episode_list.append(episode)

        data = {
            "total_page": pager.num_pages,
            "data_list": episode_list
        }
        return data

    @staticmethod
    def to_dict(obj):
        ret = {
            'id': obj.id,
            'serial_num': obj.serial_num,
            'storyline': obj.storyline,
            'episode_horpic': obj.episode_horpic,
            'horpic_size': obj.horpic_size,
            "title": obj.title,
            "begin": obj.begin,
            "end": obj.end,
            'media': {
                "id": obj.media.id,
                "category": obj.media.category,
                "languages": obj.media.languages,
                "name": obj.media.name,
                "year": obj.media.year
            }
        }
        return ret

    @classmethod
    def get_list(cls, page=1, page_size=20):
        query = cls.model.objects.all().select_related("media").order_by("-id")
        return cls._get_list(query, page, page_size)

    @classmethod
    def search_by_media_name(cls, media_name="", page=1, page_size=20):
        if not media_name:
            return cls.get_list(page, page_size)

        query = cls.model.objects.filter(media__name__icontains=media_name).select_related("media").order_by("-id")
        return cls._get_list(query, page, page_size)

    @classmethod
    def search_by_media_id(cls, media_id, page=1, page_size=20):
        query = cls.model.objects.filter(media_id=media_id)
        return cls._get_list(query, page, page_size)

    @classmethod
    def generate(cls, media_id, start, total, storyline, episode_horpic, horpic_size, **kwargs):
        """
        生成分集;目前综艺是单集添加的
        :param int media_id: 媒体id
        :param int start: 开始集数，1代表第1集，20200101 代表第几期（综艺发期数）
        :param int total: 总集数
        :param str storyline: 简介
        :param str episode_horpic: 横图地址
        :param str horpic_size: 横图尺寸
        :return: code
        """
        episode_list = []
        total = start + total if total < start else total + 1
        for i in range(start, total):
            data = {
                "media": MediaModel(id=media_id),
                "serial_num": i,
                "storyline": storyline,
                "episode_horpic": episode_horpic,
                "horpic_size": horpic_size,
                "begin": kwargs.get("begin", ""),
                "end": kwargs.get("end", "")
            }
            episode_list.append(cls.model(**data))

        cls.model.objects.bulk_create(episode_list)
        return len(episode_list)

    @classmethod
    def set_effective_time(cls, data_list):
        """设置节目有效时间"""
        effective_time_map = {}
        for data in data_list:
            for serial_num in range(data["start_serial_num"], data["end_serial_num"] + 1):
                effective_time_map[serial_num] = (data["start_date"], data["end_date"])

        media_id = data_list[0]["media_id"]
        partner_id = data_list[0]["partner_id"]
        query = EpisodeEffectiveTimeModel.objects.filter(media_id=media_id, partner_id=partner_id).first()
        # 该媒体未设置过有效时间
        if not query:
            EpisodeEffectiveTimeModel(media_id=media_id, partner_id=partner_id,
                                      effective_times=effective_time_map).save()
            return

        # 已设置过
        effective_times = query.effective_times
        effective_times.update(effective_time_map)
        EpisodeEffectiveTimeModel.objects.filter(media_id=media_id, partner_id=partner_id).update(
            effective_times=effective_times)
        return

    @classmethod
    def get_episode_effective_time(cls, media_id, serial_num: int, partner_id):
        query_info = {"media_id": media_id, "partner_id": partner_id}
        query = EpisodeEffectiveTimeModel.objects.filter(**query_info).first()
        if not query:
            return {"start_date": "", "end_date": ""}

        if str(serial_num) not in query.effective_times.keys():
            serial_num = list(query.effective_times.keys())[0]
        effective_times = query.effective_times
        start_date = effective_times[str(serial_num)][0]
        end_date = effective_times[str(serial_num)][1]
        return {"start_date": start_date, "end_date": end_date}

    @classmethod
    def get_media_effective_time(cls, media_id, partner_id):
        query_info = {"media_id": media_id, "partner_id": partner_id}
        query = EpisodeEffectiveTimeModel.objects.filter(**query_info).first()
        if not query:
            return {"start_date": "", "end_date": ""}

        effective_times = query.effective_times
        s_list = []
        e_list = []
        for i in effective_times.values():
            s_list.append(int(i[0].replace("-", "")))
            e_list.append(int(i[1].replace("-", "")))

        min_s = min(s_list)
        max_e = max(e_list)
        start_date = datetime.strptime(str(min_s), "%Y%m%d").strftime("%Y-%m-%d")
        end_date = datetime.strptime(str(max_e), "%Y%m%d").strftime("%Y-%m-%d")
        return {"start_date": str(start_date), "end_date": str(end_date)}

    @classmethod
    def get_bulk_update_character_kwargs(cls, episode, mode):
        """
        提取批量修改分集的参数，整合成有用的资源
        :param episode: 需要修改的分集信息
        :param mode: 强更新（hard）表格里面字段为空会更新为空| 软更新（soft）表格里面为空的字段不更新
        :return: 分集id，及需要更新的信息
        """
        _update = dict()
        eid = episode.get("id", "")
        _update["title"] = episode.get("title", "")
        _update["storyline"] = episode.get("storyline", "")
        _update["begin"] = episode.get("begin", "")
        _update["end"] = episode.get("end", "")
        if mode == "hard":
            update_dict = _update
        else:
            update_dict = {k: v for k, v in _update.items() if v}
        return eid, update_dict

    @classmethod
    def get_bulk_update_picture_kwargs(cls, episode):
        _update = dict()
        eid = episode.get("id", "")
        if episode.get("url", ""):
            _update["episode_horpic"] = episode.get("url")
        if episode.get("size", ""):
            _update["horpic_size"] = episode.get("size")
        return eid, _update

    def update(self, query_info, update_info):
        self.model.objects.filter(**query_info).update(**update_info)
