from flask.json import JSONEncoder
from flask_admin import BaseView, expose
from flask_babel import lazy_gettext as _

from providers import User


__author__ = 'hanl'

from flask_wtf import Form
from wtforms import PasswordField, StringField, validators, RadioField

CHOICES = [('male', _('male')), ('female', _('female'))]


class ReadonlyStringField(StringField):
    def __call__(self, *args, **kwargs):
        kwargs.setdefault('readonly', True)
        # c = kwargs.pop('class', '') or kwargs.pop('class_', '')
        #kwargs['class'] = u'%s %s' % ('form-control-static', c)
        return super(ReadonlyStringField, self).__call__(*args, **kwargs)


class SigninForm(Form):
    username = StringField(_("username"), [validators.DataRequired(_("enter.username"))])
    password = PasswordField(_('password'), [validators.DataRequired(_("enter.password"))])
    # submit = SubmitField("Sign in")

    def __init__(self, *args, **kwargs):
        Form.__init__(self, *args, **kwargs)

    def validate(self):
        if not Form.validate(self):
            return False
            # user = User.query.filter_by(email = self.email.data.lower()).first()
            # if user and user.check_password(self.password.data):
        return True
        # else:
        # self.email.errors.append("Invalid e-mail or password")
        # return False


class SignupForm(Form):
    gender = RadioField(_("gender"), validators=[validators.DataRequired()], choices=CHOICES)
    username = StringField(_("username"), [validators.DataRequired(_("enter.username"))])
    password = PasswordField(_("password"), [validators.DataRequired(_("enter.password")),
                                             validators.EqualTo("confirm", message=_("password.match"))])
    confirm = PasswordField(_("confirm"))
    firstName = StringField(_("firstName"), [validators.DataRequired(_("enter.firstName"))])
    lastName = StringField(_("lastName"), [validators.DataRequired(_("enter.lastName"))])

    email = StringField(_("email"), [validators.DataRequired(_("enter.email")),
                                     validators.Email(_("enter.valid.email"))])

    address = StringField(_("address"))
    phone = StringField(_("phone"))
    institution = StringField(_("institution"))
    # recaptcha = RecaptchaField()

    def __init__(self, *args, **kwargs):
        Form.__init__(self, *args, **kwargs)

    def validate(self):
        if not Form.validate(self):
            return False

            # user = User.query.filter_by(email = self.email.data.lower()).first()
            # if user:
            # self.email.errors.append("That email is already taken")
            # return False
            # else:
        return True


class ProfileForm(Form):
    username = ReadonlyStringField(_("username"))
    email = StringField(_("email"), [validators.DataRequired(_("enter.email")),
                                     validators.Email(_("enter.valid.email"))])
    firstName = StringField(_("firstName"), [validators.DataRequired(_("enter.firstName"))])
    lastName = StringField(_("lastName"), [validators.DataRequired(_("enter.lastName"))])

    address = StringField(_("address"))
    phone = StringField(_("phone"))
    institution = StringField(_("institution"))

    def __init__(self, *args, **kwargs):
        Form.__init__(self, *args, **kwargs)

    def validate(self):
        if not Form.validate(self):
            return False
        return True


class PasswordReset(Form):
    username = ReadonlyStringField(_("username"))
    email = StringField(_("email"), [validators.DataRequired(_("enter.email")),
                                     validators.Email(_("enter.valid.email"))])


class PasswordChangeForm(Form):
    password = PasswordField(_("password"), [validators.DataRequired(_("enter.password")),
                                             validators.EqualTo("confirm", message=_("password.match"))])
    confirm = PasswordField(_("confirm"))
    pass


class UserEncoder(JSONEncoder):
    def default(self, obj):
        if isinstance(obj, User):
            data = {}
            if obj.username:
                data['username'] = obj.username
            if obj.firstName:
                data['firstName'] = obj.firstName
            if obj.lastName:
                data['lastName'] = obj.lastName
            if obj.email:
                data['email'] = obj.email
            if obj.country:
                data['country'] = obj.country
            if obj.institution:
                data['institution'] = obj.institution
            if obj.address:
                data['address'] = obj.address
            if obj.phone:
                data['phone'] = obj.phone
            return data
        return super(UserEncoder, self).default(obj)


class AdminView(BaseView):

    @expose('/')
    def index(self):
        print "rendering an admin view"
        return self.render('index.html')

    @expose('/test')
    def test(self):
        print "rendering an admin view"
        return self.render('index.html')