from flask import Flask, jsonify, request, abort
from flask_sqlalchemy import SQLAlchemy
import requests
import jwt
import time
import pymysql
import redis
import json

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://myuser:mypassword@mysql:3306/mydb'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

db = SQLAlchemy(app)

MYSQL_HOST = "mysql"
MYSQL_PORT = 3306
MYSQL_USER = "myuser"
MYSQL_PASSWORD = "mypassword"
MYSQL_DB = "mydb"

# Connexion Redis
redis_client = redis.Redis(host='redis', port=6379, decode_responses=True)

while True:
    try:
        conn = pymysql.connect(
            host=MYSQL_HOST,
            port=MYSQL_PORT,
            user=MYSQL_USER,
            password=MYSQL_PASSWORD,
            database=MYSQL_DB
        )
        conn.close()
        print("MySQL is up - continuing.")
        break
    except pymysql.err.OperationalError as e:
        print("Waiting for MySQL...", e)
        time.sleep(2)

class Visite(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    galerie_id = db.Column(db.Integer, nullable=False)

class Critique(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    oeuvre_id = db.Column(db.Integer, nullable=False)
    texte = db.Column(db.Text, nullable=False)
    username = db.Column(db.String(100), nullable=False)


@app.route("/", methods=["GET"])
def index():
    return f"User API - Authenticated as {request.user}", 200

@app.route("/galerie/<int:galerie_id>/entrer", methods=["POST"])
def entrer_galerie(galerie_id):
    visite = Visite(galerie_id=galerie_id)
    db.session.add(visite)
    db.session.commit()
    return jsonify({"message": "Entré dans la galerie"}), 201

@app.route("/galerie/<int:galerie_id>/sortir", methods=["POST"])
def sortir_galerie(galerie_id):
    Visite.query.filter_by(galerie_id=galerie_id).delete()
    db.session.commit()
    return jsonify({"message": "Sorti de la galerie"}), 200

@app.route("/oeuvres", methods=["POST"])
def create_oeuvre():
    data = flask.request.get_json()
    titre = data.get("titre")
    if not titre:
        return {"error": "Titre requis"}, 400
    oeuvre = Oeuvre(titre=titre, exposee=True)
    db.session.add(oeuvre)
    db.session.commit()
    # Publier l'événement
    event = {
        "type": "oeuvre_created",
        "data": {"id": oeuvre.id, "titre": oeuvre.titre}
    }
    redis_client.publish('events', json.dumps(event))
    return {"id": oeuvre.id, "titre": oeuvre.titre}, 201

@app.route("/oeuvre/<int:oeuvre_id>/critiquer", methods=["POST"])
def critiquer_oeuvre(oeuvre_id):
    data = request.get_json()
    if not data or not data.get("texte"):
        abort(400)
    critique = Critique(oeuvre_id=oeuvre_id, texte=data["texte"], username=request.user)
    db.session.add(critique)
    db.session.commit()
    return jsonify({"message": "Critique ajoutée"}), 201

# ROUTE CREATION GALERIE
@app.route("/galeries", methods=["POST"])
def create_galerie():
    data = request.get_json()
    nom = data.get("nom")
    if not nom:
        return {"error": "Nom requis"}, 400
    galerie = Galerie(nom=nom, auteur=request.user)
    db.session.add(galerie)
    db.session.commit()
    # Publier l'événement
    event = {
        "type": "galerie_created",
        "data": {"id": galerie.id, "nom": galerie.nom, "auteur": galerie.auteur}
    }
    redis_client.publish('events', json.dumps(event))
    return {"id": galerie.id, "nom": galerie.nom, "auteur": galerie.auteur}, 201

if __name__ == "__main__":
    with app.app_context():
        db.create_all()
    app.run(host='0.0.0.0',port=5002, debug=True)

