# project/server/admin/views.py


#################
#### imports ####
#################

import datetime
from flask import render_template, Blueprint, url_for, \
    redirect, flash, request, make_response, abort, jsonify
from flask_login import login_required
from werkzeug.debug import get_current_traceback
from sqlalchemy import and_
from .forms import LanguageForm, LanguageModForm, LexiconForm, LexiconSearchForm
from .. import db
from ..models import Lexicon, Language, Translation, Permission, ProductLexicon, Product
from ..config import BaseConfig
from ..utils import datetime_utcnow, Audit, get_value_with_fallback
from ..decorators import admin_required, permission_required

################
#### config ####
################

LEXICON_BLUEPRINT = Blueprint('lexicon', __name__,)


##################
#### language ####
##################

@LEXICON_BLUEPRINT.route('/language', methods=['GET', 'POST'])
@login_required
@permission_required(Permission.POWERUSER)
def language():
    form = LanguageForm(request.form)
    if form.validate_on_submit():
        try:
            lang = Language(
                locale_code=form.locale_code.data,
                description=form.description.data,
                description_en=form.description_en.data
            )
            db.session.add(lang)
            db.session.commit()
            flash('Thank you for adding language.', 'success')
        except:
            db.session.rollback()
            flash('Something went wrong when adding language.', 'danger')

    languages = Language.query.all()
    return render_template('lexicon/language.html', form=form, languages=languages)

@LEXICON_BLUEPRINT.route('/language/mod/<locale_code>', methods=['POST', 'GET'])
@LEXICON_BLUEPRINT.route('/language/mod/', methods=['POST'])
@login_required
@permission_required(Permission.POWERUSER)
def mod_language(locale_code=None):
    if request.method == 'GET':
        lang = Language.query.filter_by(locale_code=locale_code).first()
        form = LanguageModForm(obj=lang)
    if request.method == 'POST':
        form = LanguageModForm(request.form)
        locale_code=form.locale_code.data
        lang = Language.query.filter_by(locale_code=locale_code).first()
    #this will run for POST only
    if form.validate_on_submit():
        try:
            lang.description=form.description.data
            lang.description_en=form.description_en.data
            lang.mod_date=datetime_utcnow()
            lang.process_code=Audit.PROCESS_WEB
            lang.process_status=Audit.STATUS_SUCCESS
            db.session.commit()
            flash('Thank you for saving language.', 'success')
        except:
            db.session.rollback()
            flash('Something went wrong when saving language.', 'danger')

    languages = Language.query.all()
    return render_template('lexicon/language.html', form=form, languages=languages, locale_code=locale_code)

@LEXICON_BLUEPRINT.route('/language/del/<locale_code>', methods=['GET'])
@login_required
@permission_required(Permission.POWERUSER)
def del_language(locale_code):
    lang = Language.query.filter_by(locale_code=locale_code).first()
    try:
        db.session.delete(lang)
        db.session.commit()
        flash('Language deleted.', 'info')
    except:
        track = get_current_traceback(skip=1, show_hidden_frames=True, ignore_system_exceptions=False)
        track.log()            
        db.session.rollback()
        flash('Something went wrong when deleting language.', 'danger')

    return redirect(url_for('lexicon.language'))

##################
#### lexicon #####
##################

@LEXICON_BLUEPRINT.route('/items', methods=['GET'])
@LEXICON_BLUEPRINT.route('/items/<int:page>', methods=['GET'])
@login_required
@permission_required(Permission.POWERUSER)
def items(page=1):
    """Return all items."""
    form = LexiconSearchForm()
    description = get_value_with_fallback("lexicon_description")
    if request.method == 'GET':
        if description:
            form.lexicon_description.data = description
            lexicons = Lexicon.query.filter(Lexicon.description.like("%"+description+"%")).order_by(Lexicon.description).paginate(page,BaseConfig.PRODUCTS_PER_PAGE,error_out=False)
        else:
            lexicons = Lexicon.query.order_by(Lexicon.description).paginate(page,BaseConfig.PRODUCTS_PER_PAGE,error_out=False)
    response = make_response(render_template('lexicon/items.html', form=form, lexicons=lexicons))
    expires = datetime.datetime.now() + datetime.timedelta(days=365)
    if description:
        response.set_cookie("lexicon_description", description, expires=expires)
    return response

@LEXICON_BLUEPRINT.route('/item', methods=['GET', 'POST'])
@login_required
@permission_required(Permission.POWERUSER)
def newitem():
    """Empty form setup."""
    form = LexiconForm()
    form.products.choices = []
    return render_template('lexicon/item.html', form=form)

@LEXICON_BLUEPRINT.route('/item/<lexicon_id>', methods=['GET'])
@login_required
@permission_required(Permission.POWERUSER)
def item(lexicon_id):
    """display lexicon"""
    lexicon = Lexicon.query.filter_by(lexicon_id=lexicon_id).first()
    if lexicon:
        form = LexiconForm(obj=lexicon)        
        for t in lexicon.translations:
            form.locale_code.data=t.locale_code
            form.translation_description.data=t.description
            break
        form.products.choices = [(p.product_id, p.product_code, True) for p in lexicon.products]
    return render_template('lexicon/item.html', form=form, lexicon_item=lexicon)

@LEXICON_BLUEPRINT.route('/save', methods=['POST'])
@login_required
@permission_required(Permission.POWERUSER)
def save():
    """Add or modify Lexicon data"""    
    form = LexiconForm(request.form)
    if form.validate_on_submit():
        lexicon = Lexicon.query.filter_by(lexicon_id=form.lexicon_id.data).first()
        translation = Translation.query.filter(and_(Translation.lexicon_id == form.lexicon_id.data, Translation.locale_code == form.locale_code.data)).first()
        try:
            if translation:
                translation.description = form.translation_description.data    
                translation.mod_date = datetime_utcnow()
                translation.process_code = Audit.PROCESS_WEB
                translation.process_status = Audit.STATUS_SUCCESS
            else:
                translation = Translation(
                    locale_code=form.locale_code.data,
                    description=form.translation_description.data,
                )
            if lexicon:
                if translation not in lexicon.translations:
                    lexicon.translations.append(translation)         
                lexicon.description=form.description.data
                lexicon.tags=form.tags.data
                lexicon.lexicon_type_code=form.lexicon_type_code.data,
                lexicon.mod_date=datetime_utcnow(),
                lexicon.process_code=Audit.PROCESS_WEB,
                lexicon.process_status=Audit.STATUS_SUCCESS
            else:
                lexicon = Lexicon(
                    lexicon_type_code=form.lexicon_type_code.data,
                    description=form.description.data,
                    tags=form.tags.data
                )
                lexicon.translations.append(translation)        
                db.session.add(lexicon)
            if form.products.data:
                lexicon.products[:] = []
                for product_id in form.products.data:
                    product = Product.query.filter_by(product_id=int(product_id)).first()
                    if product:
                        productlexicon = ProductLexicon(
                            lexicon_id=form.lexicon_id.data,
                            product_id=product.product_id,
                            product_code=product.product_code
                        )
                        lexicon.products.append(productlexicon)
                form.products.choices = [(p.product_id, p.product_code, True) for p in lexicon.products]
            else:
                lexicon.products[:] = []
                form.products.choices = []
            flash('Thank you for saving lexicon.', 'success')
            db.session.commit()
        except:
            track = get_current_traceback(skip=1, show_hidden_frames=True, ignore_system_exceptions=False)
            track.log()            
            db.session.rollback()
            flash('Something went wrong when adding new customer.', 'danger')
    return render_template('lexicon/item.html', form=form)
