# -*- coding: UTF-8 -*-
# Copyright 2020 by Kurt Rathjen. All Rights Reserved.
#
# This library is free software: you can redistribute it and/or modify it 
# under the terms of the GNU Lesser General Public License as published by 
# the Free Software Foundation, either version 3 of the License, or 
# (at your option) any later version. This library 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 Lesser General Public License for more details.
# You should have received a copy of the GNU Lesser General Public
# License along with this library. If not, see <http://www.gnu.org/licenses/>.

import os
from datetime import datetime

from studiovendor.Qt import QtGui
from studiovendor.Qt import QtCore
from studiovendor.Qt import QtWidgets

import studioqt
import studiolibrary
import studiolibrary.widgets


class FolderItem(studiolibrary.LibraryItem):

    NAME = u"文件夹"
    TYPE = "Folder"

    MENU_ORDER = 0  # Show at the top of the menu
    SYNC_ORDER = 100  # Last item to run when syncing

    LOAD_WIDGET_CLASS = studiolibrary.widgets.PreviewWidget
    ENABLE_NESTED_ITEMS = True

    ICON_PATH = studiolibrary.resource.get("icons", "folder.svg")
    TYPE_ICON_PATH = ""  # Don't show a type icon for the folder item
    THUMBNAIL_PATH = studiolibrary.resource.get("icons", "folder_item.png")

    DEFAULT_ICON_COLOR = "rgba(150,150,150,100)"

    DEFAULT_ICON_COLORS = [
        "rgb(239, 112, 99)",
        "rgb(239, 207, 103)",
        "rgb(136, 200, 101)",
        "rgb(111, 183, 239)",
        "rgb(199, 142, 220)",
        DEFAULT_ICON_COLOR,
    ]

    DEFAULT_ICONS = [
        "folder.svg",
        "user.svg",
        "character.svg",
        "users.svg",
        "inbox.svg",
        "favorite.svg",
        "shot.svg",
        "asset.svg",
        "assets.svg",
        "cloud.svg",
        "book.svg",
        "archive.svg",
        "circle.svg",
        "share.svg",
        "tree.svg",
        "environment.svg",
        "vehicle.svg",
        "trash.svg",
        "layers.svg",
        "database.svg",
        "video.svg",
        "face.svg",
        "hand.svg",
        "globe.svg",
        "shuishan.png",
    ]

    _THUMBNAIL_ICON_CACHE = {}

    @classmethod
    def match(cls, path):
        """
        Return True if the given path is supported by the item.

        :type path: str 
        :rtype: bool 
        """
        if os.path.isdir(path):
            return True

    def itemData(self):
        """
        Reimplementing this method to set a trash folder icon.

        :rtype: dict
        """
        data = super(FolderItem, self).itemData()

        if self.path().endswith("Trash") and not data.get("icon"):
            data["icon"] = "trash.svg"

        return data

    def updateMetadata(self, metadata):
        """
        Overriding this method to support updating the library widget directly.

        :type metadata: dict
        """
        super(FolderItem, self).updateMetadata(metadata)

        if self.libraryWindow():
            self.libraryWindow().setFolderData(self.path(), self.itemData())
            self.updateIcon()

    def doubleClicked(self):
        """Overriding this method to show the items contained in the folder."""
        self.libraryWindow().selectFolderPath(self.path())

    def createOverwriteMenu(self, menu):
        """
        Overwriting this method to ignore/hide the overwrite menu action.

        :type menu: QtWidgets.QMenu
        """
        pass

    def _showPreviewFromMenu(self):

        self.libraryWindow().itemsWidget().clearSelection()
        self.showPreviewWidget(self.libraryWindow())

    def contextEditMenu(self, menu, items=None):
        """
        Called when creating the context menu for the item.

        :type menu: QtWidgets.QMenu
        :type items: list[FolderItem] or None
        """
        super(FolderItem, self).contextEditMenu(menu, items=items)

        action = QtWidgets.QAction(u"预览显示", menu)

        action.triggered.connect(self._showPreviewFromMenu)
        menu.addAction(action)
        menu.addSeparator()

        action = studiolibrary.widgets.colorpicker.ColorPickerAction(menu)
        action.picker().setColors(self.DEFAULT_ICON_COLORS)
        action.picker().colorChanged.connect(self.setIconColor)
        action.picker().setCurrentColor(self.iconColor())
        action.picker().menuButton().hide()
        menu.addAction(action)

        iconName = self.itemData().get("icon", "")

        action = studiolibrary.widgets.iconpicker.IconPickerAction(menu)
        action.picker().setIcons(self.DEFAULT_ICONS)
        action.picker().setCurrentIcon(iconName)
        action.picker().iconChanged.connect(self.setCustomIcon)
        action.picker().menuButton().hide()

        menu.addAction(action)

    def iconColor(self):
        """
        Get the icon color for the folder item.

        :rtype: str
        """
        return self.itemData().get("color", "")

    def setIconColor(self, color):
        """
        Set the icon color for the folder item.

        :type color: str
        """
        if color == self.DEFAULT_ICON_COLOR:
            color = ""

        self.updateMetadata({"color": color})

    def customIconPath(self):
        """
        Get the icon for the folder item.

        :rtype: str
        """
        return self.itemData().get("icon", "")

    def setCustomIcon(self, name):
        """
        Set the icon for the folder item.

        :type name: str
        """
        if name == "folder.svg":
            name = ""

        self.updateMetadata({"icon": name})

    def thumbnailIcon(self):
        """
        Overriding this method add support for dynamic icon colors.

        :rtype: QtGui.QIcon
        """
        customPath = self.customIconPath()

        if customPath and "/" not in customPath and "\\" not in customPath:
            customPath = studiolibrary.resource.get("icons", customPath)

        color = self.iconColor()
        if not color:
            color = self.DEFAULT_ICON_COLOR

        key = customPath + color
        icon = self._THUMBNAIL_ICON_CACHE.get(key)

        if not icon:
            color1 = studioqt.Color.fromString(color)
            pixmap1 = studioqt.Pixmap(self.THUMBNAIL_PATH)
            pixmap1.setColor(color1)
            pixmap1 = pixmap1.scaled(
                128,
                128,
                QtCore.Qt.KeepAspectRatio,
                QtCore.Qt.SmoothTransformation
            )

            color2 = studioqt.Color.fromString("rgba(255,255,255,150)")
            pixmap2 = studioqt.Pixmap(customPath)
            pixmap2.setColor(color2)
            pixmap2 = pixmap2.scaled(
                64,
                64,
                QtCore.Qt.KeepAspectRatio,
                QtCore.Qt.SmoothTransformation
            )

            x = (128 - pixmap2.width()) / 2
            y = (128 - pixmap2.height()) / 2

            painter = QtGui.QPainter(pixmap1)
            painter.drawPixmap(x, y+5, pixmap2)
            painter.end()

            icon = studioqt.Icon(pixmap1)

            self._THUMBNAIL_ICON_CACHE[key] = icon

        return self._THUMBNAIL_ICON_CACHE.get(key)

    def loadValidator(self, **kwargs):
        """
        The validator used for validating the load arguments.

        :type kwargs: dict
        """
        if kwargs.get("fieldChanged") == "color":
            self.setIconColor(kwargs.get("color"))

        if kwargs.get("fieldChanged") == "icon":
            self.setCustomIcon(kwargs.get("icon"))

    def loadSchema(self):
        """
        Get the info to display to user.
        
        :rtype: list[dict]
        """
        created = os.stat(self.path()).st_ctime
        created = datetime.fromtimestamp(created).strftime("%Y-%m-%d %H:%M %p")

        modified = os.stat(self.path()).st_mtime
        modified = datetime.fromtimestamp(modified).strftime("%Y-%m-%d %H:%M %p")

        iconName = self.itemData().get("icon", "")

        return [
            {
                "name": "infoGroup",
                "title": u"信息",
                "value": True,
                "type": "group",
                "persistent": True,
                "persistentKey": "BaseItem",
            },
            {
                "name": u"name",
                "title": u"名称",
                "value": self.name()
            },
            {
                "name": "path",
                "title": u"路径",
                "value": self.path()
            },
            {
                "name": "created",
                "title": u"创建",
                "value":  created,
            },
            {
                "name": "modified",
                "title": u"修改",
                "value": modified,
            },
            {
                "name": "optionsGroup",
                "title": u"选项",
                "type": "group",
            },

            {
                "name": "color",
                "type": "color",
                "value": self.iconColor(),
                "layout": "vertical",
                "label": {"visible": False},
                "colors": self.DEFAULT_ICON_COLORS,
            },

            {
                "name": "icon",
                "type": "iconPicker",
                "value": iconName,
                "layout": "vertical",
                "label": {"visible": False},
                "items": self.DEFAULT_ICONS,
            }
        ]

    @classmethod
    def showSaveWidget(cls, libraryWindow):
        """
        Show the dialog for creating a new folder.

        :rtype: None
        """
        path = libraryWindow.selectedFolderPath() or libraryWindow.path()

        name, button = studiolibrary.widgets.MessageBox.input(
            libraryWindow,
            u"创建文件夹",
            u"请输入文件夹名称:",
            buttons=[
                (u"创建", QtWidgets.QDialogButtonBox.AcceptRole),
                (u"取消", QtWidgets.QDialogButtonBox.RejectRole)
            ]
        )

        name = name.strip()

        if name and button == u"创建":
            path = os.path.join(path, name)

            item = cls(path, libraryWindow=libraryWindow)
            item.safeSave()

            if libraryWindow:
                libraryWindow.refresh()
                libraryWindow.selectFolderPath(path)

    def save(self, *args, **kwargs):
        """Adding this method to avoid NotImpementedError."""
        pass
