#!/usr/bin/env python

import yaml

from re import sub

from evennia.commands.default.muxcommand import MuxCommand
from evennia import CmdSet
from evennia.utils import logger

from utils.word_list import choices, routput


class CmdHint(MuxCommand):
    """
    Get a hint about an area or thing.

    Usage:

      |ghint [ thing or key ]|n

    To make this system more helpful, each message contains colored
    text, like |Ythis|n. Call |ghint|n again, but with the |wkey|n as
    a parameter, and you can get more direct hints.

    Keep in mind the hint tree is |warea specific|n, so getting a hint
    with a key of |gjump|n will be different if you are in the Grove
    or in the Marsh.

    This system tries to wrap the hint in the fiction. If that doesn't
    work for you,  use |ghint/x|n instead.
    """
    key = "hint"
    hints = None

    def hint_data(self):
        if not self.hints:
            with open("world/hints.yaml", "r") as yamlfile:
                try:
                    self.hints = yaml.safe_load(yamlfile)
                except yaml.YAMLError as e:
                    logger.info(f"Error parsing hints file: {e}")
                    return None

        return self.hints

    def get_hint(self, room, cleaned=False, search_string=None):
        room_key = sub(r" ", "_", room.name).lower()
        logger.info(f"Character: {self.caller.key}  "
                    f"Room: {room_key}  "
                    f"Hint: '{search_string}'")

        data = self.hint_data()
        if data:
            room_hints = data.get(room_key)
            if not room_hints:
                return "<< Sorry, the hint system for this area has not been created, yet. >>"

            narrative = room_hints.get('narrative')
            if narrative:
                narrative = sub(r"\n", " ", narrative)
            hints = room_hints.get('hints')

            if not search_string or search_string == "":
                hint = hints.get('default')
            else:
                hint = hints.get(search_string)

            if hint:
                hint = sub(r"\n", " ", hint)

            return self.display_hint(narrative, hint, cleaned)

    def display_hint(self, narrative, phrase, cleaned):
        if phrase:
            if cleaned or not narrative:
                self.caller.msg(routput(phrase))
            else:
                self.caller.msg(choices(narrative, routput(phrase)))
        else:
            self.caller.msg("[This is a new system, and the hint system has nothing to offer here.]")

    def func(self):
        cleaner = True if "x" in self.switches else False
        self.get_hint(self.caller.location, cleaner, self.lhs)


class CmdSetHint(CmdSet):
    def at_cmdset_creation(self):
        self.add(CmdHint)
