from app import app
from flask import render_template, url_for, request, flash, redirect, session,  make_response
import json
from werkzeug.utils import secure_filename
import os
from app.forms import ImageForm, ImageUpload
from app.models.sites import DataSite
from app.models.blocs import MyBlocs
from PIL import Image
from flask_bcrypt import Bcrypt
from copy import deepcopy
from app.forms import Login
from functools import wraps
from app.utils import login_required

app.config.from_pyfile('config.py')
DB = DataSite(app.config['JSON_FILE'], app.config['STATIC_PATH'])
DB.loadFile()
tmp = deepcopy(DB)
bcrypt = Bcrypt(app)

EXT_IMG = {'.jpg', '.JPG', '.png', '.PNG', '.gif', '.GIF', '.bmp', '.BMP', '.jpeg', '.JPEG' }

@app.route('/')
@app.route('/index.html')
def index():
    DB.loadFile()
    config = DB.datas['config']
    menu = DB.datas['menu']
    myblocs = DB.datas['blocs']
    return render_template('/index.html.tpl',
                           config=config,
                           menu=menu,
                           myblocs=myblocs)

@app.route('/edit/save')
@login_required
def savefile():
    DB.saveJson(tmp.datas)
    DB.loadFile()
    tmp.emptyTrash()
    return redirect(url_for('edit'))

@app.route('/edit')
@login_required
def edit():
    theme = tmp.datas['config']['theme']
    menu = DB.datas['menu']
    print('edit_menu' + str(menu))
    myblocs = tmp.datas['blocs']
    return render_template('/edit.html.tpl',
                           blocEdit="",
                           config=DB.datas['config'],
                           menu=menu,
                           myblocs=myblocs
                          )


@app.route('/edit/<bloc>', methods=['GET', 'POST'])
@login_required
def editBloc(bloc):
    theme = tmp.datas['config']['theme']
    menu= tmp.datas['menu']
    myblocs = tmp.datas['blocs']
    form = MyBlocs.makeForm(tmp.datas['blocs'][bloc])
    bloc = tmp.datas['blocs'][bloc]
    if request.method == 'POST':
        if form.validate_on_submit():
            tmp.updateDatas(bloc, form)
            flash(u'Vos changements on été pris en compte', 'success')

        if "hx-request"  in request.headers:
            return render_template(theme+'/_'+bloc['type']+'.html',
                               bloc=bloc)
        else:
            return redirect(url_for('edit'))

    if "hx-request"  in request.headers:
        return render_template(theme+'/_'+bloc['type']+'-edit.html',
                               bloc=bloc,
                               form=form)
    else:
        return render_template(theme+'/edit.html',
                               config=DB.datas['config'],
                               menu=menu,
                               myblocs=myblocs,
                               blocEdit=bloc['name'],
                               form=form)

@app.route('/view/<bloc>', methods=['GET'])
@login_required
def viewBloc(bloc):
    theme = tmp.datas['config']['theme']
    myblocs = tmp.datas['blocs']
    form = MyBlocs.makeForm(tmp.datas['blocs'][bloc])
    bloc = tmp.datas['blocs'][bloc]
    
    return render_template(theme+'/_'+bloc['type']+'.html',
                           bloc=bloc)



@app.route('/edit/images/<bloc>/<image>', methods=['GET', 'POST'])
@login_required
def editPhoto(image, bloc):
    theme = tmp.datas['config']['theme']
    form = ImageForm()
    mesimages = tmp.datas['blocs'][bloc]

    if request.method == 'POST':
        if form.validate_on_submit():
            tmp.updateImg(bloc, mesimages[image], form)
        else:
            flash(u'Image non modifier', error)

    
        form = MyBlocs.makeForm(tmp.datas['blocs'][bloc])
        if "hx-request"  in request.headers:
            return render_template(theme+'/_gallery-edit.html',
                                   bloc=mesimages,
                                   form=form)
        else:
            return redirect ('/edit#'+bloc)
    else:
        return render_template(theme+'/_image-edit'+'.html', form=form, image=mesimages[image], bloc=mesimages)
        
@app.route('/upload-gallery/<bloc>', methods=['POST'])
@login_required
def drop_upload(bloc):
    file = request.files['file']
    filename = secure_filename(file.filename)
    ext = os.path.splitext(filename)[-1]
    save_path = "./app/static/img/portfolio"
    if ext not in EXT_IMG :
        return make_response(('Le fichier n\'est pas une image', 400))

    current_chunk = int(request.form['dzchunkindex'])
    print (current_chunk)
    
    if (os.path.isfile(os.path.join(save_path, 'fullsize', filename ))) and  current_chunk == 0:
        return make_response(('Un fichier avec le même nom existe déjà', 400))

    try:
        with open(os.path.join(save_path, 'fullsize', filename ), 'ab') as f:
            f.seek(int(request.form['dzchunkbyteoffset']))
            f.write(file.stream.read())
    except OSError:
        return make_response(("Une erreur est survenue,"
                              " Impossible d'écrire le fichier sur le disque", 500))
    total_chunks = int(request.form['dztotalchunkcount'])

    if current_chunk + 1 == total_chunks:
        # This was the last chunk, the file should be complete and the size we expect
        if os.path.getsize(os.path.join(save_path, 'fullsize', filename )) != int(request.form['dztotalfilesize']):
            return make_response(('La taille du fichier source est différentes', 500))
        else:
            with Image.open(os.path.join(save_path, 'fullsize', filename )) as img :
                img.thumbnail((300,300))
                img.save(os.path.join(save_path, 'thumbnails', filename ) )
    tmp.addImg(bloc, filename)
    return make_response(('Chunk upload succesfull', 200))


@app.route('/edit/images/<bloc>/del/<image>', methods=['GET'])
@login_required
def delImage(bloc, image):
    tmp.delImg(image)
    return redirect ('/edit#'+bloc)

@app.route('/editmenu', methods=['POST'])
@login_required
def editMenu():
    print (request.form)
    DB.datas['menu']=dict()
    for menu in request.form:
        if '§§' in menu:
            submenu = menu.split("§§")
            if submenu[0] in DB.datas['menu'].keys():
                DB.datas['menu'][submenu[0]] = DB.datas['menu'][submenu[0]] | {submenu[1]: str(request.form[menu])}
            else:
                DB.datas['menu'][submenu[0]] = {submenu[1]: str(request.form[menu])}
        
        else:
            DB.datas['menu'][menu] = str(request.form[menu])
    print (DB.datas['menu'])
    flash (u'Le menu a bien été modifier', 'succes');
    return make_response(('Update menu succesfull', 200))
    



@app.route('/login', methods=['GET', 'POST'])
def login():
    theme = DB.datas['config']['theme']
    form = Login()
    if 'username' in session :
        resp = redirect(url_for('edit', _external=True))
    else :
        resp = redirect(url_for('login', _external=True))
        if request.method == 'POST' :
            password = str(request.form['passwd'])
            passwd_bcrypt = DB.datas['config']['passwd']
            
            if bcrypt.check_password_hash(passwd_bcrypt, password) is True:
                session['username'] = "logged"
                resp =  redirect(url_for('edit', _external=True))
            else:
                flash(u'Mauvais mot de passe', 'error')
           
        else:
            resp = render_template(theme+'/login.html', form=form)

    return resp

@app.route( '/logout/', methods=['GET'] )
@login_required
def logout():
    session.pop('username', None) # Supprimer username de la session s'il s'y trouve
    session.clear()
    return redirect(url_for('index'))
