from flask import Blueprint, render_template
from .functions.Fpost import Fpost;
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from config import Config
from flask import jsonify,request

main = Blueprint('main', __name__)


@main.route('/apostlist',methods=['POST','GET'])
def postlist():
    data=request.get_json()
    print(data)
    engine=create_engine(Config.SQLURL)
    SessionLocal = sessionmaker(bind=engine)
    session = SessionLocal()
    f=Fpost(session)
    checres=f.checkid(data['userid'])
    if(not checres):
        return jsonify({'status': 'error', 'message': 'Unauthorized'})
    res=f.getlist()
    respons=[]
    for datai in res:
        respons.append({
            'id': datai[0],
            'title': datai[1],
            'status': datai[2]
        })
    return jsonify(respons)

@main.route('/agetpost',methods=['POST','GET'])
def post():
    data=request.get_json()
    engine=create_engine(Config.SQLURL)
    SessionLocal = sessionmaker(bind=engine)
    session = SessionLocal()
    f=Fpost(session)
    checres=f.checkid(data['userid'])
    if(not checres):
        return jsonify({'status': 'error', 'message': 'Unauthorized'})
    res=f.getpost(data['postid'])

    return jsonify(res.to_dict() if res else {})

@main.route('/areview',methods=['POST','GET'])
def review():
    data=request.get_json()
    engine=create_engine(Config.SQLURL)
    SessionLocal = sessionmaker(bind=engine)
    session = SessionLocal()
    f=Fpost(session)
    checres=f.checkid(data['userid'])
    if(not checres):
        return jsonify({'status': 'error', 'message': 'Unauthorized'})
    
    res=f.review(data['postid'],data['status'])
    if not res:
        return jsonify({'status': 'error', 'message': 'Post not found'})
    
    return jsonify({'status': 'success', 'message': 'Post reviewed successfully'})



@main.route('/nginxauth',methods=['POST','GET'])
def nginxauth():
    data=request.get_json()
    engine=create_engine(Config.SQLURL)
    SessionLocal = sessionmaker(bind=engine)
    session = SessionLocal()
    f=Fpost(session)
    checres=f.checkid(data['userid'])
    if(not checres):
        return jsonify({'status': 'error', 'message': 'Unauthorized'})
    
    res=f.nginxauth(data['postid'],data['status'])
    if not res:
        return jsonify({'status': 'error', 'message': 'Post not found'})
    
    return jsonify({'status': 'success', 'message': 'Nginx auth updated successfully'})