from flask import Blueprint, request, jsonify
from server.permissions import editor_or_higher
from server.database import Session
from models.models import EventException, Event
from datetime import datetime, date

event_exceptions_bp = Blueprint("event_exceptions", __name__, url_prefix="/api/event_exceptions")


@event_exceptions_bp.route("", methods=["POST"])
@editor_or_higher
def create_exception():
    data = request.json
    session = Session()
    # required: event_id, exception_date
    required = ["event_id", "exception_date"]
    for f in required:
        if f not in data:
            return jsonify({"error": f"Missing field: {f}"}), 400

    # Validate event exists
    event = session.query(Event).filter_by(id=data["event_id"]).first()
    if not event:
        session.close()
        return jsonify({"error": "Event not found"}), 404

    exc_date = datetime.fromisoformat(data["exception_date"]).date() if isinstance(data["exception_date"], str) else data["exception_date"]
    # Check if an exception for this event and date already exists
    existing_exc = session.query(EventException).filter_by(event_id=event.id, exception_date=exc_date).first()
    if existing_exc:
        # Optionally, update the existing exception fields if needed
        existing_exc.is_skipped = bool(data.get("is_skipped", existing_exc.is_skipped))
        existing_exc.override_title = data.get("override_title", existing_exc.override_title)
        existing_exc.override_description = data.get("override_description", existing_exc.override_description)
        existing_exc.override_start = datetime.fromisoformat(data["override_start"]) if data.get("override_start") else existing_exc.override_start
        existing_exc.override_end = datetime.fromisoformat(data["override_end"]) if data.get("override_end") else existing_exc.override_end
        session.commit()
        return jsonify({"success": True, "id": existing_exc.id, "updated": True})
    # Otherwise, create a new exception
    exc = EventException(
        event_id=event.id,
        exception_date=exc_date,
        is_skipped=bool(data.get("is_skipped", False)),
        override_title=data.get("override_title"),
        override_description=data.get("override_description"),
        override_start=(datetime.fromisoformat(data["override_start"]) if data.get("override_start") else None),
        override_end=(datetime.fromisoformat(data["override_end"]) if data.get("override_end") else None),
    )
    session.add(exc)
    session.commit()
    return jsonify({"success": True, "id": exc.id})


@event_exceptions_bp.route("/<exc_id>", methods=["PUT"])
@editor_or_higher
def update_exception(exc_id):
    data = request.json
    session = Session()
    exc = session.query(EventException).filter_by(id=exc_id).first()
    if not exc:
        session.close()
        return jsonify({"error": "Exception not found"}), 404

    if "exception_date" in data:
        exc.exception_date = datetime.fromisoformat(data["exception_date"]).date()
    if "is_skipped" in data:
        exc.is_skipped = bool(data["is_skipped"])
    if "override_title" in data:
        exc.override_title = data.get("override_title")
    if "override_description" in data:
        exc.override_description = data.get("override_description")
    if "override_start" in data:
        exc.override_start = datetime.fromisoformat(data["override_start"]) if data.get("override_start") else None
    if "override_end" in data:
        exc.override_end = datetime.fromisoformat(data["override_end"]) if data.get("override_end") else None

    session.commit()
    session.close()
    return jsonify({"success": True})


@event_exceptions_bp.route("/<exc_id>", methods=["DELETE"])
@editor_or_higher
def delete_exception(exc_id):
    session = Session()
    exc = session.query(EventException).filter_by(id=exc_id).first()
    if not exc:
        session.close()
        return jsonify({"error": "Exception not found"}), 404
    session.delete(exc)
    session.commit()
    session.close()
    return jsonify({"success": True})


@event_exceptions_bp.route("", methods=["GET"])
def list_exceptions():
    session = Session()
    event_id = request.args.get("event_id")
    q = session.query(EventException)
    if event_id:
        q = q.filter(EventException.event_id == int(event_id))
    rows = q.all()
    out = []
    for r in rows:
        out.append({
            "id": r.id,
            "event_id": r.event_id,
            "exception_date": r.exception_date.isoformat(),
            "is_skipped": r.is_skipped,
            "override_title": r.override_title,
            "override_description": r.override_description,
            "override_start": r.override_start.isoformat() if r.override_start else None,
            "override_end": r.override_end.isoformat() if r.override_end else None,
        })
    session.close()
    return jsonify(out)
