import os
import datetime
import tempfile
import jinja2
from pykindle import items as _items
from pykindle import readers as _readers


class Book(list):
    """
    This is a base class.
    You should extend it, rather than use it directly.
    See MagazineBook.

    This class is inherited from python list class.
    You can use all list functions.

    Required attributes: None

    Alternative attributes: title, language, uid, creator, publisher, subject, author, date, description
    """

    def __init__(self):
        super(Book, self).__init__()
        self.title = 'Auto Generted by PyKindle'
        self.language = 'zh-cn'
        self.uid = '0000000000'
        self.creator = 'PyKindle'
        self.publisher = 'https://github.com/panhaoyu/pykindle'
        self.subject = 'PyKindle'
        self.author = 'Yourself'
        self.date = datetime.datetime.now().strftime('%Y-%m-%d')
        self.description = 'Auto generated by pykindle. You can get more information at our website: https://github.com/panhaoyu/pykindle.'
        self._ncx = None

        self._jinja = jinja2.Environment(
            loader=jinja2.FileSystemLoader(os.path.join(os.path.dirname(os.path.relpath(__file__)), 'templates')))

    def _write_items(self, directory):
        for item in self:
            item.write(directory)
        self._ncx.write(directory)

    def _write_opf(self, directory):
        content = self._jinja.get_template('magazine.opf').render({
            'title': self.title, 'language': self.language, 'uid': self.uid, 'creator': self.creator,
            'publisher': self.publisher, 'subject': self.subject, 'date': self.date, 'description': self.description,
            'cover_image_url': self._cover_image_url, 'ncx': self._ncx, 'items': self, 'articles': self._articles
        })
        with open(os.path.join(directory, 'index.opf'), mode='w', encoding='utf-8') as file:
            file.write(content)

    def _generate_ncx(self):
        self._ncx = _items.MagazineNcxItem()
        self._ncx.id = 'ncx'
        self._ncx.path = 'toc.ncx'
        self._ncx.title = self.title
        self._ncx.author = self.author
        categories = dict()
        for item in self:
            category = categories.setdefault(item.category, list())
            category.append(item)
        self._ncx.categories = list(categories.items())

    def _generate_book(self, directory):
        opf_file = os.path.join(directory, 'index.opf')
        os.system('kindlegen {} -o output.mobi'.format(opf_file))
        output_path = os.path.join(directory, 'output.mobi')
        if not os.path.exists(output_path):
            raise ValueError('Mobi file generated failed. Please raise an issue.')
        with open(output_path, mode='rb') as file:
            content = file.read()
        return content

    @property
    def _cover_image_url(self):
        for item in self:
            if isinstance(item, _items.CoverImageItem):
                return item.href

    @property
    def _articles(self):
        return [item for item in self if isinstance(item, _items.ArticleItem)]

    def _generate_article_id(self):
        for index, item in enumerate(self):
            item.id = str(index)

    def create(self):
        with tempfile.TemporaryDirectory() as directory:
            self._generate_article_id()
            self._generate_ncx()
            self._write_opf(directory)
            self._write_items(directory)
            content = self._generate_book(directory)
        return content


class NormalBook(Book):
    """
    This class represents a normal book.
    Normal means the book has a toc, and readers will read from first paragraph to last paragraph.
    """
    pass


class MagazineBook(Book):
    pass


__all__ = ['Book', 'MagazineBook', 'NormalBook']
