import logging

from PyQt5.QtCore import Qt, QUrl
from PyQt5.QtGui import QPixmap, QFont, QDesktopServices
from PyQt5.QtWidgets import (
    QWidget,
    QLabel,
    QPushButton,
    QHBoxLayout,
    QSpacerItem,
    QGroupBox,
    QTabWidget,
    QGridLayout,
)

from rare.components.tabs.store.shop_models import ShopGame
from rare.shared import LegendaryCoreSingleton
from rare.ui.components.tabs.store.shop_game_info import Ui_shop_info
from rare.utils.extra_widgets import ImageLabel
from rare.utils.misc import icon
from rare.widgets.loading_widget import LoadingWidget

logger = logging.getLogger("ShopInfo")


class ShopGameInfo(QWidget, Ui_shop_info):
    game: ShopGame
    data: dict

    # TODO Design
    def __init__(self, installed_titles: list, api_core):
        super(ShopGameInfo, self).__init__()
        self.setupUi(self)
        self.core = LegendaryCoreSingleton()
        self.api_core = api_core
        self.installed = installed_titles
        self.open_store_button.clicked.connect(self.button_clicked)
        self.image = ImageLabel()
        self.image_stack.addWidget(self.image)
        self.image_stack.addWidget(LoadingWidget())
        warn_label = QLabel()
        warn_label.setPixmap(
            icon("fa.warning").pixmap(160, 160).scaled(240, 320, Qt.IgnoreAspectRatio)
        )
        self.image_stack.addWidget(warn_label)

        self.wishlist_button.clicked.connect(self.add_to_wishlist)
        self.in_wishlist = False
        self.wishlist = []

    def handle_wishlist_update(self, data):
        if data and data[0] == "error":
            return
        self.wishlist = [i["offer"]["title"] for i in data]
        if self.title_str in self.wishlist:
            self.in_wishlist = True
            self.wishlist_button.setVisible(True)
            self.wishlist_button.setText(self.tr("Remove from Wishlist"))
        else:
            self.in_wishlist = False
            self.wishlist_button.setVisible(False)

    def update_game(self, data: dict):
        self.image_stack.setCurrentIndex(1)
        self.title.setText(data["title"])
        self.title_str = data["title"]
        self.api_core.get_wishlist(self.handle_wishlist_update)
        for i in reversed(range(self.req_group_box.layout().count())):
            self.req_group_box.layout().itemAt(i).widget().deleteLater()
        slug = data["productSlug"]
        if not slug:
            for mapping in data["offerMappings"]:
                if mapping["pageType"] == "productHome":
                    slug = mapping["pageSlug"]
                    break
            else:
                logger.error("Could not get page information")
                slug = ""
        if "/home" in slug:
            slug = slug.replace("/home", "")
        self.slug = slug

        if data["namespace"] in self.installed:
            self.open_store_button.setText(self.tr("Show Game on Epic Page"))
            self.owned_label.setVisible(True)
        else:
            self.open_store_button.setText(self.tr("Buy Game in Epic Games Store"))
            self.owned_label.setVisible(False)

        for i in range(self.req_group_box.layout().count()):
            self.req_group_box.layout().itemAt(i).widget().deleteLater()

        self.price.setText(self.tr("Loading"))
        self.wishlist_button.setVisible(False)
        # self.title.setText(self.tr("Loading"))
        self.image.setPixmap(QPixmap())
        self.data = data
        is_bundle = False
        for i in data["categories"]:
            if "bundles" in i.get("path", ""):
                is_bundle = True

        # init API request
        if slug:
            self.api_core.get_game(slug, is_bundle, self.data_received)
        else:
            self.data_received({})

    def add_to_wishlist(self):
        if not self.in_wishlist:
            return
            # self.api_core.add_to_wishlist(self.game.namespace, self.game.offer_id,
            #                             lambda success: self.wishlist_button.setText(self.tr("Remove from wishlist"))
            #                              if success else self.wishlist_button.setText("Something goes wrong"))
        else:
            self.api_core.remove_from_wishlist(
                self.game.namespace,
                self.game.offer_id,
                lambda success: self.wishlist_button.setVisible(False)
                if success
                else self.wishlist_button.setText("Something goes wrong"),
            )

    def data_received(self, game):
        try:
            self.game = ShopGame.from_json(game, self.data)
        except Exception as e:
            logger.error(str(e))
            self.price.setText("Error")
            self.req_group_box.setVisible(False)
            for img in self.data.get("keyImages"):
                if img["type"] in [
                    "DieselStoreFrontWide",
                    "OfferImageTall",
                    "VaultClosed",
                    "ProductLogo",
                ]:
                    self.image.update_image(img["url"], self.title_str, size=(240, 320))
                    self.image_stack.setCurrentIndex(0)
                    break
            else:
                self.image_stack.setCurrentIndex(2)
            self.price.setText("")
            self.discount_price.setText("")
            self.social_link_gb.setVisible(False)
            self.tags.setText("")
            self.dev.setText(self.data.get("seller", {}).get("name", ""))
            return
        self.title.setText(self.game.title)

        self.price.setFont(QFont())
        if self.game.price == "0" or self.game.price == 0:
            self.price.setText(self.tr("Free"))
        else:
            self.price.setText(self.game.price)
        if self.game.price != self.game.discount_price:
            font = QFont()
            font.setStrikeOut(True)
            self.price.setFont(font)
            self.discount_price.setText(
                self.game.discount_price
                if self.game.discount_price != "0"
                else self.tr("Free")
            )
            self.discount_price.setVisible(True)
        else:
            self.discount_price.setVisible(False)

        bold_font = QFont()
        bold_font.setBold(True)

        if self.game.reqs:
            req_tabs = QTabWidget()
            for system in self.game.reqs:
                min_label = QLabel(self.tr("Minimum"))
                min_label.setFont(bold_font)
                rec_label = QLabel(self.tr("Recommend"))
                rec_label.setFont(bold_font)
                req_widget = QWidget()
                req_widget.setLayout(QGridLayout())
                req_widget.layout().addWidget(min_label, 0, 1)
                req_widget.layout().addWidget(rec_label, 0, 2)
                for i, (key, value) in enumerate(
                        self.game.reqs.get(system, {}).items()
                ):
                    req_widget.layout().addWidget(QLabel(key), i + 1, 0)
                    min_label = QLabel(value[0])
                    min_label.setWordWrap(True)
                    req_widget.layout().addWidget(min_label, i + 1, 1)
                    rec_label = QLabel(value[1])
                    rec_label.setWordWrap(True)
                    req_widget.layout().addWidget(rec_label, i + 1, 2)
                req_tabs.addTab(req_widget, system)
            self.req_group_box.layout().addWidget(req_tabs)
        else:
            self.req_group_box.layout().addWidget(
                QLabel(self.tr("Could not get requirements"))
            )
        self.req_group_box.setVisible(True)
        if self.game.image_urls.front_tall:
            img_url = self.game.image_urls.front_tall
        elif self.game.image_urls.offer_image_tall:
            img_url = self.game.image_urls.offer_image_tall
        elif self.game.image_urls.product_logo:
            img_url = self.game.image_urls.product_logo
        else:
            img_url = ""
        self.image.update_image(img_url, self.game.title, (240, 320))

        self.image_stack.setCurrentIndex(0)
        try:
            if isinstance(self.game.developer, list):
                self.dev.setText(", ".join(self.game.developer))
            else:
                self.dev.setText(self.game.developer)
        except KeyError:
            pass
        self.tags.setText(", ".join(self.game.tags))

        # clear Layout
        for widget in (
                self.social_link_gb.layout().itemAt(i)
                for i in range(self.social_link_gb.layout().count())
        ):
            if not isinstance(widget, QSpacerItem):
                widget.widget().deleteLater()
        self.social_link_gb.deleteLater()
        self.social_link_gb = QGroupBox(self.tr("Social Links"))
        self.social_link_gb.setLayout(QHBoxLayout())

        self.layout().insertWidget(3, self.social_link_gb)

        self.social_link_gb.layout().addStretch(1)
        link_count = 0
        for name, url in self.game.links:

            if name.lower() == "homepage":
                icn = icon("mdi.web", "fa.search", scale_factor=1.5)
            else:
                try:
                    icn = icon(f"mdi.{name.lower()}", f"fa.{name.lower()}", scale_factor=1.5)
                except Exception as e:
                    logger.error(str(e))
                    continue

            button = SocialButton(icn, url)
            self.social_link_gb.layout().addWidget(button)
            link_count += 1
            self.social_link_gb.layout().addStretch(1)

        if link_count == 0:
            self.social_link_gb.setVisible(False)
        else:
            self.social_link_gb.setVisible(True)
        self.social_link_gb.layout().addStretch(1)

    def add_wishlist_items(self, wishlist):
        wishlist = wishlist["data"]["Wishlist"]["wishlistItems"]["elements"]
        for game in wishlist:
            self.wishlist.append(game["offer"]["title"])

    def button_clicked(self):
        QDesktopServices.openUrl(QUrl(f"https://www.epicgames.com/store/{self.core.language_code}/p/{self.slug}"))


class SocialButton(QPushButton):
    def __init__(self, icn, url):
        super(SocialButton, self).__init__(icn, "")
        self.url = url
        self.clicked.connect(lambda: QDesktopServices.openUrl(QUrl(url)))
        self.setToolTip(url)
