import datetime
import inspect
import os
from urllib import parse

import filetype
import pytz
from flask import Blueprint, current_app, make_response, render_template, request
from flask_login import login_required

import func
import database

Comics = Blueprint("comics", __name__, template_folder="templates")

MOBILE_DEVICES = ["android", "blackberry", "ipad", "iphone"]


@Comics.route("/comics")
@login_required
def index():
    try:
        page = request.args.get("page", 1, type=int)
        max_items = request.args.get("max_items", 30, type=int)
        publishers = database.get_publishers()
        start = max_items * (page - 1)
        end = len(publishers) if len(publishers) < max_items * page else max_items * page
        return render_template(
            "comics/index.html",
            title="Comics",
            publishers=publishers,
            page=page,
            max_items=max_items,
            start=start,
            end=end,
            item_count=len(publishers),
        )
    except Exception as e:
        current_app.logger.error(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
        return str(type(e)) + " " + str(e)


@Comics.route("/comics/search")
@login_required
def search():
    try:
        page = request.args.get("page", 1, type=int)
        max_items = request.args.get("max_items", 30, type=int)
        publisher_end = 0
        series_end = 0
        comics_end = 0
        publisher_start = 0
        series_start = 0
        comics_start = 0
        item_count = 0
        query = request.args.get("q")
        results = {"publisher": [], "series": [], "comics": []}
        if query:
            results = database.db_search_comics(query)
            item_count = len(results["publisher"]) + len(results["series"]) + len(results["comics"])
            for temp_page in range(1, page + 1):
                publisher_start = publisher_end
                series_start = series_end
                comics_start = comics_end
                items = 0
                publisher_end = len(results["publisher"]) if len(results["publisher"]) < max_items * temp_page else max_items * temp_page
                items += publisher_end - publisher_start
                if items < max_items:
                    series_end = (
                        len(results["series"]) if len(results["series"]) < (max_items * temp_page) - items else (max_items * temp_page) - items
                    )
                    items += series_end - series_start
                    if items < max_items:
                        comics_end = (
                            len(results["comics"])
                            if len(results["comics"]) < (max_items * temp_page) - series_end - publisher_end
                            else (max_items * temp_page) - series_end - publisher_end
                        )
        return render_template(
            "comics/search.html",
            title="Comics: Search",
            publishers=results["publisher"],
            publisher_series=results["series"],
            comics=results["comics"],
            page=page,
            max_items=max_items,
            item_count=item_count,
            publisher_start=publisher_start,
            series_start=series_start,
            comics_start=comics_start,
            publisher_end=publisher_end,
            series_end=series_end,
            comics_end=comics_end,
        )
    except Exception as e:
        current_app.logger.error(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
        return str(type(e)) + " " + str(e)


@Comics.route("/comics/<publisher>")
@login_required
def comics_publisher(publisher):
    try:
        publisher = parse.unquote(publisher)
        series = request.args.get("series")
        series_year = request.args.get("seriesYear")
        issue = request.args.get("issue")
        page_number = request.args.get("pageNumber")
        page = request.args.get("page", 1, type=int)
        max_items = request.args.get("max_items", 30, type=int)
        publisher_series = database.db_get_series_by_publisher(publisher)
        start = max_items * (page - 1)
        end = len(publisher_series) if len(publisher_series) < max_items * page else max_items * page
        if series:
            comics = database.db_get_comics_in_series(series, publisher, series_year)
            start = max_items * (page - 1)
            end = len(comics) if len(comics) < max_items * page else max_items * page
            if issue:
                return comic_gallery(publisher, series, series_year, issue)
            comics_dict = []
            for i in comics:
                item = i.__dict__
                item.pop("_sa_instance_state", None)
                item.pop("path", None)
                comics_dict.append(item)
            return render_template(
                "comics/seriesView.html",
                title="Comics",
                comics=comics_dict,
                start=start,
                end=end,
                page=page,
                max_items=max_items,
                item_count=len(comics),
            )
        pub_series_dict = []
        for i in publisher_series:
            item = i.__dict__
            item.pop("_sa_instance_state", None)
            item.pop("path", None)
            pub_series_dict.append(item)
        return render_template(
            "comics/publisherSeriesView.html",
            title="Comics",
            publisher_series=pub_series_dict,
            start=start,
            end=end,
            page=page,
            max_items=max_items,
            item_count=len(publisher_series),
        )
    except Exception as e:
        current_app.logger.error(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
        return str(type(e)) + " " + str(e)


@Comics.route("/comics/<int:comic_id>")
@login_required
def comic_gallery(comic_id):
    try:
        page = request.args.get("page", 1, type=int)
        max_items = request.args.get("max_items", 30, type=int)
        meta = database.db_get_comic(comic_id)
        start = max_items * (page - 1)
        end = meta.pagecount if meta.pagecount < max_items * page else max_items * page
        comic_dict = meta.__dict__
        comic_dict.pop("_sa_instance_state", None)
        comic_dict.pop("path", None)
        return render_template(
            "comics/comicGallery.html",
            title="Comics",
            comic=comic_dict,
            start=start,
            end=end,
            page=page,
            max_items=max_items,
            item_count=meta.pagecount,
        )
    except Exception as e:
        current_app.logger.error(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
        return str(type(e)) + " " + str(e)


@Comics.route("/comics/get_comic/<int:comic_id>/<int:page_number>")
@login_required
def get_comic_page(comic_id, page_number):
    meta = database.db_get_comic_by_id(comic_id)
    if not os.path.exists(meta.path):
        return "File not found", 404
    comic = func.open_comic(meta.path)
    byte_image = comic.getPage(page_number)
    type = filetype.guess(byte_image).mime
    response = make_response(byte_image)
    response.headers["content-type"] = type
    response.headers["cache-control"] = "public"
    date = pytz.utc.localize(datetime.datetime.utcfromtimestamp(os.path.getmtime(meta.path)))
    response.headers["last-modified"] = date.strftime("%a, %d %b %Y %H:%M:%S %Z")
    response.headers["Content-Disposition"] = 'attachment; filename="{} {}_{}{}"'.format(
        str(meta.series), meta.issuetext, str(page_number), filetype.guess(byte_image).extension
    )
    return response


@Comics.route("/comics/get_comic/<int:comic_id>/<int:page_number>/thumbnail")
@login_required
def get_comic_thumbnail(comic_id, page_number):
    meta = database.db_get_comic_by_id(comic_id)
    thumb = database.db_get_thumbnail_by_id_page(comic_id, page_number)
    response = make_response(thumb.image)
    response.headers["cache-control"] = "public"
    if os.path.exists(meta.path):
        date = pytz.utc.localize(datetime.datetime.utcfromtimestamp(os.path.getmtime(meta.path)))
        response.headers["last-modified"] = date.strftime("%a, %d %b %Y %H:%M:%S %Z")
    response.headers["content-type"] = thumb.type
    response.headers["Content-Disposition"] = 'filename="{} {}_{}_thumbnail"'.format(str(meta.series), meta.issuetext, str(page_number))
    return response
