#
#   Copyright © 2021,2022 IsardVDI S.L.
#   Copyright © 2022 Evilham <contact@evilham.com>
#
#   This file is part of DD
#
#   DD is free software: you can redistribute it and/or modify
#   it under the terms of the GNU Affero General Public License as published by
#   the Free Software Foundation, either version 3 of the License, or (at your
#   option) any later version.
#
#   DD 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 Affero General Public License for more
#   details.
#
#   You should have received a copy of the GNU Affero General Public License
#   along with DD. If not, see <https://www.gnu.org/licenses/>.
#
# SPDX-License-Identifier: AGPL-3.0-or-later
import logging as log
import os
import shutil
import traceback
from io import BytesIO
from pprint import pprint

import requests
import yaml
from PIL import Image
from schema import And, Optional, Schema, SchemaError, Use

from typing import TYPE_CHECKING, Any, Dict
if TYPE_CHECKING:
    from admin.flaskapp import AdminFlaskApp

from werkzeug.datastructures import FileStorage

class Dashboard:
    app : "AdminFlaskApp"
    def __init__(
        self,
        app : "AdminFlaskApp",
    ) -> None:
        self.app = app

    @property
    def custom_menu(self) -> str:
        return os.path.join(self.app.custom_dir, "menu/custom.yaml")

    def _update_custom_menu(self, custom_menu_part : Dict[str, Any]) -> bool:
        with open(self.custom_menu) as yml:
            menu = yaml.load(yml, Loader=yaml.FullLoader)
        menu = {**menu, **custom_menu_part}
        with open(self.custom_menu, "w") as yml:
            yml.write(yaml.dump(menu, default_flow_style=False))
        return True

    def update_colours(self, colours : Dict[str, Any]) -> bool:
        schema_template = Schema(
            {
                "background": And(Use(str)),
                "primary": And(Use(str)),
                "secondary": And(Use(str)),
            }
        )

        try:
            schema_template.validate(colours)
        except SchemaError:
            return False

        self._update_custom_menu({"colours": colours})
        return self.apply_updates()

    def update_menu(self, menu : Dict[str, Any]) -> bool:
        items = []
        for menu_item in menu.keys():
            for mustexist_key in ["href", "icon", "name", "shortname"]:
                if mustexist_key not in menu[menu_item].keys():
                    return False
            items.append(menu[menu_item])
        self._update_custom_menu({"apps_external": items})
        return self.apply_updates()

    def update_logo(self, logo : FileStorage) -> bool:
        img = Image.open(logo.stream)
        img.save(os.path.join(self.app.custom_dir, "img/logo.png"))
        return self.apply_updates()

    def update_background(self, background : FileStorage) -> bool:
        img = Image.open(background.stream)
        img.save(os.path.join(self.app.custom_dir, "img/background.png"))
        return self.apply_updates()

    def apply_updates(self) -> bool:
        resp = requests.get("http://dd-sso-api:7039/restart")
        return True
