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):
    pass


class PasswordChangeForm(Form):
    pass


class UserEncoder(JSONEncoder):
    def default(self, obj):
        if isinstance(obj, User):
            data = {}
            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):
        return self.render('admin/index.html')