# -*- coding: utf-8 -*-
from __future__ import unicode_literals, absolute_import, division, print_function

import random
import functools
from collections.abc import Iterable

import warnings

warnings.catch_warnings()
warnings.filterwarnings('ignore', category=DeprecationWarning, message=r'inspect.getargspec()')
from aenum import MultiValueEnum, EnumMeta

class _PokerEnumMeta(EnumMeta):
    # def __init__(self, clsname, bases, classdict):
    #     # make sure we only have tuple values, not single values
    #     for member in self.__members__.values():
    #         values = member._value_
    #         if not isinstance(values, Iterable):# or isinstance(values, str):
    #             raise TypeError('{} = {!r}, should be iterable, not {}!'
    #                             .format(member._name_, values, type(values)))
    #         for alias in values:
    #             if isinstance(alias, str):
    #                 alias = alias.upper()
    #             self._value2member_map_.setdefault(alias, member)

    # def __call__(cls, value):
    #     """Return the appropriate instance with any of the values listed. If values contains
    #     text types, those will be looked up in a case insensitive manner."""
    #     if isinstance(value, str):
    #         value = value.upper()
    #     return super(_PokerEnumMeta, cls).__call__(value)

    def make_random(cls):
        return random.choice(list(cls))


@functools.total_ordering
class _OrderableMixin(object):
    # I couldn't inline this to PokerEnum because Enum do some magic which don't like it.

    # From Python manual:
    # If a class that overrides __eq__() needs to retain
    # the implementation of __hash__() from a parent class,
    # the interpreter must be told this explicitly
    def __hash__(self):
        return super(_OrderableMixin, self).__hash__()

    def __eq__(self, other):
        if self.__class__ is other.__class__:
            return self._value_ == other._value_
        return NotImplemented

    def __lt__(self, other):
        if self.__class__ is other.__class__:
            names = self.__class__._member_names_
            return names.index(self._name_) < names.index(other._name_)
        return NotImplemented

    def __reduce_ex__(self, proto):
        return self.__class__.__name__


class PokerEnum(_OrderableMixin, MultiValueEnum, metaclass=_PokerEnumMeta):
    #__metaclass__ = _PokerEnumMeta

    # def __new__(typ, *args, **kwargs):
    #     with warnings.catch_warnings():
    #         warnings.filterwarnings('ignore', category=DeprecationWarning)
    #         print('BOOM')
    #         # if len(args) > 0:
    #         #     for arg in args:
    #         #         print('Arg: %s-%s' % (arg, type(arg)))
    #         obj = super().__new__(typ, *args, **kwargs)
    #     return obj
    
    def __str__(self):
        return str(self._value_)

    def __repr__(self):
        val = self._value_[0]
        apostrophe = "'" if isinstance(val, str) else ''
        return "{0}({1}{2}{1})".format(self.__class__.__name__, apostrophe, val)

    # def __format__(self, format_spec):
    #     return str(self._value_[0])

    @property
    def val(self):
        """The first value of the Enum member."""
        return self._value_#[0]


class _ReprMixin(object):
    # def __str__(self):
    #     return str(self)

    def __repr__(self):
        return "{}('{}')".format(self.__class__.__name__, self.__str__())


def _make_float(string):
    return float(string.strip().replace(',', ''))


def _make_int(string):
    return int(string.strip().replace(',', ''))
