"""
LicenciasMIG - aplicacion Flask que reemplaza al sistema antiguo (179.50.90.179).

Sirve:
  /                     -> Dashboard admin (HTML)
  /login                -> Login de admin
  /api/v1/...           -> REST JSON para el panel
  /LicenciasService.asmx-> SOAP compatible con el cliente MIG (Web Reference)
"""
from __future__ import annotations

import os
from datetime import datetime, timedelta

from dotenv import load_dotenv
from flask import Flask, jsonify, redirect, render_template, request, url_for
from flask_cors import CORS
from flask_login import LoginManager, current_user, login_required

from models import Usuario, db
from routes.auth import bp as auth_bp
from routes.empresas import bp as empresas_bp
from routes.licencias import bp as licencias_bp
from routes.logs import bp as logs_bp
from routes.pages import bp as pages_bp
from routes.usuarios import bp as usuarios_bp
from soap_service import register_soap

load_dotenv()


def create_app() -> Flask:
    app = Flask(__name__)

    # ----- Config -----
    db_server   = os.getenv('DB_SERVER',   'localhost')
    db_port     = os.getenv('DB_PORT',     '1433')
    db_name     = os.getenv('DB_DATABASE', 'LicenciasMIG')
    db_user     = os.getenv('DB_USERNAME', 'sa')
    db_pass     = os.getenv('DB_PASSWORD', '')
    db_driver   = os.getenv('DB_DRIVER',   'ODBC Driver 17 for SQL Server').replace(' ', '+')

    app.config['SQLALCHEMY_DATABASE_URI'] = (
        f'mssql+pyodbc://{db_user}:{db_pass}@{db_server}:{db_port}/{db_name}'
        f'?driver={db_driver}&TrustServerCertificate=yes&Encrypt=yes'
    )
    app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
    app.config['SECRET_KEY']                    = os.getenv('FLASK_SECRET_KEY', 'cambia-esto')
    app.config['DEBUG']                         = os.getenv('FLASK_DEBUG', 'False').lower() in ('1', 'true', 'yes')

    app.config['REMEMBER_COOKIE_DURATION']      = timedelta(days=14)
    app.config['SESSION_COOKIE_HTTPONLY']       = True
    app.config['SESSION_COOKIE_SAMESITE']       = 'Lax'

    # ----- Init -----
    CORS(app, supports_credentials=True)
    db.init_app(app)

    login_manager = LoginManager()
    login_manager.init_app(app)
    login_manager.login_view = 'auth.login_page'

    @login_manager.user_loader
    def load_user(user_id):
        try:
            return Usuario.query.get(int(user_id))
        except (TypeError, ValueError):
            return None

    @login_manager.unauthorized_handler
    def unauthorized():
        if request.path.startswith('/api/'):
            return jsonify(ok=False, error='No autenticado'), 401
        return redirect(url_for('auth.login_page', next=request.path))

    # ----- Blueprints REST + paginas -----
    app.register_blueprint(auth_bp)
    app.register_blueprint(pages_bp)
    app.register_blueprint(empresas_bp,  url_prefix='/api/v1/empresas')
    app.register_blueprint(licencias_bp, url_prefix='/api/v1/licencias')
    app.register_blueprint(usuarios_bp,  url_prefix='/api/v1/usuarios')
    app.register_blueprint(logs_bp,      url_prefix='/api/v1/logs')

    # ----- Endpoint SOAP compatible con cliente MIG -----
    register_soap(app)

    # ----- Inyectar usuario al template -----
    @app.context_processor
    def inject_user():
        return {'current_user': current_user}

    # ----- Errores -----
    @app.errorhandler(404)
    def not_found(_e):
        if request.path.startswith('/api/'):
            return jsonify(ok=False, error='No encontrado'), 404
        return render_template('404.html'), 404

    @app.errorhandler(500)
    def internal_error(e):
        app.logger.exception(e)
        if request.path.startswith('/api/'):
            return jsonify(ok=False, error='Error interno'), 500
        return render_template('404.html', mensaje='Error interno'), 500

    # ----- Endpoint utilitario: inicializar BD y admin por defecto -----
    @app.route('/init-db')
    def init_db():
        with app.app_context():
            db.create_all()
            if not Usuario.query.filter_by(Username='admin').first():
                u = Usuario(
                    Username='admin',
                    NombreCompleto='Administrador',
                    Email='admin@migsistemas.com',
                    Rol='Admin',
                    Activo=True,
                )
                u.set_password('admin123')
                db.session.add(u)
                db.session.commit()
                return jsonify(ok=True, mensaje='BD inicializada. Usuario admin/admin123 creado.')
            return jsonify(ok=True, mensaje='BD ya inicializada.')

    @app.route('/health')
    def health():
        return jsonify(ok=True, ts=datetime.utcnow().isoformat() + 'Z')

    return app


app = create_app()


if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000, debug=app.config['DEBUG'])
