import logging

from flask import Blueprint

from flask import Flask, render_template, request, flash
from flask_wtf import FlaskForm
from wtforms import StringField, validators, SelectField, BooleanField
from wtforms.fields.html5 import IntegerRangeField
from wtforms.widgets import TextArea

import langid
from utils.utils import templated

blueprint_langid = Blueprint('langid', __name__)


class UrlForm(FlaskForm):
    url = StringField(
        'URL',
        validators=[validators.DataRequired(), validators.URL(message='Sorry, this is not a valid URL,')])

    wMin = IntegerRangeField(
        'Min. words',
        default=5,
        validators=[validators.DataRequired(), validators.NumberRange(min=1, max=20)])

    extractor_class = SelectField(
        'Extractor',
        default=langid.EXTRACTORS[0],
        choices=[(i, i) for i in langid.EXTRACTORS],
        validators=[validators.DataRequired()])

    model_class = SelectField(
        'Model',
        default=langid.MODELS[0],
        choices=[(i, i) for i in langid.MODELS],
        validators=[validators.DataRequired()])

    return_raw = BooleanField(
        'Display raw sentences',
        default=False
    )


class TextForm(FlaskForm):

    text = StringField(
        'Text',
        widget=TextArea(),
        validators=[validators.DataRequired()])

    model_class = SelectField(
        'Model',
        default=langid.MODELS[0],
        choices=[(i, i) for i in langid.MODELS],
        validators=[validators.DataRequired()])


@blueprint_langid.route('/', methods=['GET', 'POST'])
@templated('index.html')
def crawl():
    form = UrlForm(request.form)

    if request.method == 'GET':
        return dict(form=form)
    elif not form.validate():
        for f, errs in form.errors.items():
            flash("%s: %s" % (f, "<br>".join(errs)), 'danger')
        return dict(form=form)

    try:
        results = langid.mixed_sentences_from_urls(
            form.url.data.strip(), extractor_name=form.extractor_class.data, model=form.model_class.data,
            with_proba=True, min_words=form.wMin.data, return_raw=form.return_raw.data)
    except Exception as e:
        flash('Something went wrong %s' % e, 'danger')
        logging.exception(e)
        return dict(form=form)
    return dict(form=form, results=results, labels=langid.DEFAULT_LABELS)


@blueprint_langid.route('/text', methods=['GET', 'POST'])
@templated('langid.html')
def predict_text():
    form = TextForm(request.form)

    if request.method == 'GET':
        return dict(form=form)

    elif not form.validate():
        for f, errs in form.errors.items():
            flash("%s: %s" % (f, "<br>".join(errs)), 'danger')
        return dict(form=form)

    results = [[r] for r in langid.lang_of_text(
        form.text.data, model=form.model_class.data, with_proba=True)]
    return dict(form=form, results=results, labels=langid.DEFAULT_LABELS)

[(14, 'flask.Blueprint', 'Blueprint', False, 'from flask import Blueprint\n'), (60, 'utils.utils.templated', 'templated', False, 'from utils.utils import templated\n'), (83, 'utils.utils.templated', 'templated', False, 'from utils.utils import templated\n'), (39, 'wtforms.BooleanField', 'BooleanField', False, 'from wtforms import StringField, validators, SelectField, BooleanField\n'), (49, 'wtforms.widgets.TextArea', 'TextArea', False, 'from wtforms.widgets import TextArea\n'), (76, 'flask.flash', 'flash', False, 'from flask import Flask, render_template, request, flash\n'), (77, 'logging.exception', 'logging.exception', False, 'import logging\n'), (95, 'langid.lang_of_text', 'langid.lang_of_text', False, 'import langid\n'), (20, 'wtforms.validators.DataRequired', 'validators.DataRequired', False, 'from wtforms import StringField, validators, SelectField, BooleanField\n'), (20, 'wtforms.validators.URL', 'validators.URL', False, 'from wtforms import StringField, validators, SelectField, BooleanField\n'), (25, 'wtforms.validators.DataRequired', 'validators.DataRequired', False, 'from wtforms import StringField, validators, SelectField, BooleanField\n'), (25, 'wtforms.validators.NumberRange', 'validators.NumberRange', False, 'from wtforms import StringField, validators, SelectField, BooleanField\n'), (31, 'wtforms.validators.DataRequired', 'validators.DataRequired', False, 'from wtforms import StringField, validators, SelectField, BooleanField\n'), (37, 'wtforms.validators.DataRequired', 'validators.DataRequired', False, 'from wtforms import StringField, validators, SelectField, BooleanField\n'), (50, 'wtforms.validators.DataRequired', 'validators.DataRequired', False, 'from wtforms import StringField, validators, SelectField, BooleanField\n'), (56, 'wtforms.validators.DataRequired', 'validators.DataRequired', False, 'from wtforms import StringField, validators, SelectField, BooleanField\n')]