from flask import Flask, render_template, request, redirect, abort
import requests
from todo_app.flask_config import Config
from todo_app.trello_api_calls import fetch_all_cards, change_card_status, \
    TrelloCard

from todo_app.view_model import ViewModel
from todo_app.Authenticated_User import Authenticated_User
import os

from loggly.handlers import HTTPSHandler
from logging import Formatter

from flask_login import LoginManager, login_required, login_user, current_user
from oauthlib.oauth2 import WebApplicationClient

login_manager = LoginManager()
oauth_client_id = os.environ.get('OAUTH_CLIENT_ID')
oauth_client = WebApplicationClient(oauth_client_id)
oauth_client_secret = os.environ.get('OAUTH_CLIENT_SECRET')

def create_app():
    app = Flask(__name__)
    app.config.from_object(Config)
    
    app.logger.setLevel(os.environ.get("LOG_LEVEL"))
    
    if os.environ.get("LOGGLY_TOKEN") is not None:
        args = "https://logs-01.loggly.com/inputs/" + os.environ.get("LOGGLY_TOKEN") + "/tag/todo-app"
        handler = HTTPSHandler(args)
        handler.setFormatter(
            Formatter("[%(asctime)s] %(levelname)s in %(module)s: %(message)s")
            )
        app.logger.addHandler(handler)

    @login_manager.unauthorized_handler
    def unauthenticated():
        uri = oauth_client.prepare_request_uri('https://github.com/login/oauth/authorize')
        return redirect(uri)

    @login_manager.user_loader
    def load_user(user_id):
        return Authenticated_User(user_id)

    @app.route('/login/callback', methods = ['GET'])
    def login_callback():
        token_url, headers, body = oauth_client.prepare_token_request(
            'https://github.com/login/oauth/access_token',
            authorization_response = request.url,
            code = request.args.get('code')
            )
        
        token_response = requests.post(
            token_url, 
            headers=headers, 
            data=body, 
            auth=(oauth_client_id, oauth_client_secret)
            )

        oauth_client.parse_request_body_response(token_response.text)

        userinfo_endpoint = 'https://api.github.com/user'
        uri, headers, body = oauth_client.add_token(userinfo_endpoint)
        user_response = requests.get(uri, headers=headers, data=body)
        authenticated_user = Authenticated_User(user_response.json()['login'])
        login_user(authenticated_user)

        return redirect('/')

    @app.route('/')
    @login_required
    def index():
        app.logger.info("Start rendering template for get call")
        app.logger.info(f'Env variables are {os.environ.get("MONGO_USER_NAME")}')
        cards = fetch_all_cards("To Do", "Doing", "Done")  
        view_model_obj = ViewModel(cards) 
        if app.config.get('LOGIN_DISABLED') or current_user.role == 'writer':
            user_role = 'writer'
        else:
            user_role = 'reader'
        app.logger.debug(f'Inside app.py - create_app() {view_model_obj}')
        app.logger.info("Rendering of the template follows...")
        return render_template('index.html',
        todo_cards = view_model_obj.get_cards('To Do'),
        doing_cards = view_model_obj.get_cards('Doing'),
        done_cards = view_model_obj.return_all_done_cards(5),
        user_role = user_role)

    @app.route('/add-card', methods = ["POST"])
    @login_required
    def add_item():
        if app.config.get('LOGIN_DISABLED') or current_user.role == 'writer':
            title = request.form['title_of_todo']
            status = request.form['status_of_todo']
            if (title != ""):
                TrelloCard.create_card(title, status)
            return redirect("/")
        else:
            return abort(403)


    @app.route('/complete/<id>', methods = ["POST"])
    @login_required
    def complete_item(id): 
        if app.config.get('LOGIN_DISABLED') or current_user.role == 'writer':
            todo_id = request.form['card_id_form']
            change_card_status(todo_id)
            return redirect("/")
        else:
            return abort(403)
    
    return app

wsgi_c = create_app()

login_manager.init_app(wsgi_c)

if __name__ == '__main__':
    wsgi_c.run()