from flask import Blueprint, render_template, request, jsonify, flash, redirect, url_for, send_from_directory
from flask_login import login_required, current_user, login_user, logout_user
from werkzeug.security import generate_password_hash, check_password_hash
from src.extensions import db
from src.models import AgenteTreino, User, Chat, Message, Agente
import sys
import os
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
from ..services.agent_service import AgentService
from ..services.chat_service import ChatService
import requests
from .auth import auth
from .chat_routes import chat_bp
from .stats_routes import stats_bp
from .playground_routes import playground_bp
from .agente import agent_bp
from .profile_routes import profile_bp
from src.discord.discord_webhook import send_discord_audit_log

main_bp = Blueprint('main', __name__)

@main_bp.route('/history')
@login_required
def history():
    return render_template('history.html')

@main_bp.route('/settings')
@login_required
def settings():
    return render_template('settings.html')

@main_bp.route('/agents')
@login_required
def agents():
    return render_template('agents.html')

@main_bp.route('/new-agent')
@login_required
def new_agent():
    return render_template('new-agent.html', user=current_user)

@main_bp.route('/profile')
@login_required
def profile():
    user = current_user
    user_data = {
        'name': getattr(user, 'name', user.username),
        'email': getattr(user, 'email', ''),
        'avatar_url': getattr(user, 'avatar_url', None),
        'default_model': getattr(user, 'default_model', 'llama3:latest'),
        'default_temperature': getattr(user, 'default_temperature', 0.7),
        'default_max_tokens': getattr(user, 'default_max_tokens', 2000),
        'save_history': getattr(user, 'save_history', True),
        'total_conversations': getattr(user, 'total_conversations', 0),
        'total_tokens': getattr(user, 'total_tokens', 0),
        'join_date': getattr(user, 'join_date', user.created_at.strftime('%d/%m/%Y') if hasattr(user, 'created_at') else '')
    }
    return render_template('profile.html', user=user_data)

@main_bp.route('/help')
@login_required
def help():
    return render_template('help.html', user=current_user)

@main_bp.route('/status')
@login_required
def status():
    return render_template('status.html')

def init_app(app):
    from flask_login import LoginManager
    login_manager = LoginManager()
    login_manager.init_app(app)
    login_manager.login_view = 'auth.login'

    @login_manager.user_loader
    def load_user(user_id):
        return User.query.get(int(user_id))

    @login_manager.unauthorized_handler
    def unauthorized_callback():
        if request.is_json or request.accept_mimetypes['application/json']:
            return jsonify({'error': 'Não autenticado'}), 401
        return redirect(url_for('auth.login'))

    app.register_blueprint(auth, url_prefix='/auth')
    app.register_blueprint(chat_bp)
    app.register_blueprint(agent_bp, url_prefix='/agente')
    app.register_blueprint(main_bp)
    app.register_blueprint(stats_bp)
    app.register_blueprint(playground_bp)
    app.register_blueprint(profile_bp)

    from src.exceptions import AppException
    from flask import render_template
    import traceback

    @app.errorhandler(AppException)
    def handle_app_exception(e):
        if request.is_json or request.accept_mimetypes['application/json']:
            return jsonify({'error': e.message}), e.status_code
        flash(e.message, 'danger')
        return render_template('error.html', error=e.message), e.status_code

    @app.errorhandler(404)
    def not_found(e):
        msg = 'Recurso não encontrado'
        if request.is_json or request.accept_mimetypes['application/json']:
            return jsonify({'error': msg}), 404
        return render_template('error.html', error=msg), 404

    @app.errorhandler(Exception)
    def handle_generic_exception(e):
        import traceback
        from sqlalchemy.exc import OperationalError
        from flask import flash
        app.logger.error(f'Erro não tratado: {str(e)}\n{traceback.format_exc()}')
        try:
            send_discord_audit_log(
                action="Erro crítico",
                user_id=getattr(current_user, 'id', None),
                object_type="Backend",
                details=f"Erro não tratado: {str(e)}\n{traceback.format_exc()[:500]}",
                ip_address=request.remote_addr
            )
        except Exception as discord_err:
            app.logger.error(f'Falha ao enviar log Discord: {discord_err}')
        if "Can't connect to MySQL server" in str(e) or "OperationalError" in str(type(e)) or "timed out" in str(e):
            flash('Erro crítico: Não foi possível conectar ao banco de dados. Tente novamente mais tarde.', 'danger')
            return redirect(url_for('auth.login'))
        msg = 'Erro interno do servidor'
        if request.is_json or request.accept_mimetypes['application/json']:
            return jsonify({'error': msg}), 500
        return redirect(url_for('main.history'))  

    @app.route('/')
    def root_index():
        if current_user.is_authenticated:
            return redirect(url_for('playground.playground'))
        return render_template('home.html') 