import os
from pathlib import Path
from flask import Blueprint, Response, request
from flask_cors import CORS
from datetime import datetime
import json
import hashlib
import time
from webservice.auth import Auth
from webservice.planner_load import PlannerLoad
from webservice.config_load import ConfigLoad

bp = Blueprint('file_io', __name__)
# cors = CORS(app, resources={r"/*": {"origins": "http://localhost:4200/"}})
CORS(bp)

script_dir = Path(__file__).parent
save_dir = script_dir.parent.joinpath('save')
planner_dir = script_dir.parent.joinpath('export')
config_dir = script_dir.parent.joinpath('config')
# save_dir = Path('C:\\Projekte\\Python\\Planung\\save')
user_info = None
timestamp_keywords = ('accounts', 'plan', 'marketing')


@bp.route('/login/', methods=['POST'])
def login():
    user = request.get_json()['data']['user']
    password = request.get_json()['data']['password']
    user_info = Auth().get_user(user, password)

    return Response(
        response=json.dumps(user_info),
        mimetype='application/json'
    )


@bp.route('/list', methods=['GET'])
def list_json():
    return json.dumps(list_dict(), indent=2)


def list_dict():
    result = {'list': [], 'tree': {}}
    for currentFile in save_dir.iterdir():
        if currentFile.is_file() and currentFile.name[-5:] == '.json':
            year, version, timestamp = currentFile.name[:-5].split("_")
            if year not in result['tree']:
                result['tree'][year] = {}
            if version not in result['tree'][year]:
                result['tree'][year][version] = []
            result['tree'][year][version].append(timestamp)
            result['list'].append({'year': year, 'version': version, 'timestamp': timestamp})
            result['list'].sort(key=lambda x: x['timestamp'])
    return result


@bp.route('/load/<year>/<version>/<timestamp>', methods=['GET'])
def load(year, version, timestamp):
    file = full_filename(year, version, timestamp)

    if timestamp == 'new':
        return Response(
            response=new_file(year),
            mimetype='application/json'
        )

    if timestamp == 'current' or not Path(file).exists():
        file_list = list_dict()
        timestamp2 = file_list['tree'][year][version][-1]
        file = full_filename(year, version, timestamp2)

    print(file)

    with open(file, 'r') as frh:
        structure = json.loads(frh.read())
        if 'options' not in structure[0]:
            p_load = PlannerLoad(planner_dir)
            structure = p_load.convert_file(structure)
        elif timestamp in timestamp_keywords:
            p_load = PlannerLoad(planner_dir)
            p_load.load_values(year)
            p_load.set_structure(structure)
            structure = p_load.update_values(timestamp)

        return Response(
            response=json.dumps(structure),
            mimetype='application/json'
        )


def full_filename(year, version, timestamp):
    return f'{str(save_dir)}/{year}_{version}_{timestamp}.json'


@bp.route('/new/<year>', methods=['GET'])
def new_file(year):
    p_load = PlannerLoad(planner_dir)
    structure = p_load.new_file(year)
    return json.dumps(structure)


@bp.route('/load/<filename>', methods=['GET'])
def load_file(filename):
    full_filename = f'{str(save_dir)}/{filename}.json'
    if not Path(full_filename).exists():
        file_list = list_dict()
        timestamp = file_list[filename][-1]
        full_filename = f'{full_filename[:-5]}_{timestamp}.json'

    print(full_filename)
    with open(full_filename, 'r') as frh:
        return frh.read()


@bp.route('/save/<year>/<version>', methods=['POST'])
def save_version(year, version):
    return save(year + '_' + version)


@bp.route('/save/<filename>', methods=['POST'])
def save(filename):
    if request.method != 'POST':
        return 'File is missing!'

    new_filename = str(save_dir) + '/' + filename + '_' + datetime.now().strftime('%Y%m%d%H%M%S') + '.json'
    data = request.get_json()['data']
    with open(new_filename, 'w') as fwh:
        json.dump(data, fwh, indent=2)
    print(new_filename)

    try:
        file_list = list_dict()
        timestamp = file_list[filename][-2]
        old_filename = str(save_dir) + '/' + filename + "_" + timestamp + '.json'

        if old_filename != new_filename and hash(old_filename) == hash(new_filename):
            Path(old_filename).unlink()
            return 'File saved with no changes!'
    except KeyError:
        pass
    return 'File saved with new data!'


@bp.route('/config', methods=['GET'])
def config():
    cfg = ConfigLoad(str(config_dir))
    return Response(
        response=json.dumps(cfg.load_file('reisacher', '2023')),
        mimetype='application/json'
    )


@bp.route('/accounts/<period>', methods=['GET'])
def accounts(period):
    with open(planner_dir.joinpath(f'accounts_{period}.json'), 'r') as frh:
        return frh.read()


def hash(filename):
    BUF_SIZE = 65536
    sha1 = hashlib.sha1()
    with open(filename, 'rb') as g:
        while True:
            hashdata = g.read(BUF_SIZE)
            if not hashdata:
                break
            sha1.update(hashdata)
    return sha1.hexdigest()
