from flask import Blueprint, request, current_app, json
from src.database import Database
from src.routes.app.api_custom import api_custom
from src.utils import clean_uploaded_avtar, Path
import os

api_route = Blueprint("api_app", __name__, url_prefix="/api")


@api_route.route("/")
def api_index():
    return {"error": False, "message": "EV API Works!!"}


# --------------------------
# CREATE / INSERT
# --------------------------


@api_route.route("/<table>", methods=["POST"])
@api_route.route("/<table>/", methods=["POST"])
def create_record(table):

    data = request.get_json(silent=True)

    if not data:
        data = request.form.to_dict()

    if not data:
        return {"error": True, "message": "No JSON data provided"}, 400

    with Database() as db:
        resp = db.save(table, data)

    if not resp.error and request.files:
        for _, file in request.files.items():
            upload_path = Path(current_app.root_path).joinpath(
                "uploads", "avatars", table
            )
            extension = os.path.splitext(file.filename)[1].lower()
            filename = f"{resp.lastrowid}{extension}"
            upload_path = upload_path.joinpath(filename)
            file.save(upload_path)

    return resp.todict()


# --------------------------
# READ / SEARCH
# --------------------------


@api_route.route("/<table>", methods=["GET"])
@api_route.route("/<table>/", methods=["GET"])
def search_records(table):
    query_params = request.args.to_dict()
    with Database() as db:
        resp = db.search(table, **query_params)
    return resp.todict()


# --------------------------
# GET BY ID
# --------------------------


@api_route.route("/<table>/<int:id>", methods=["GET"])
@api_route.route("/<table>/<int:id>/", methods=["GET"])
def search_by_id(table, id):
    with Database() as db:
        resp = db.get_by_id(table, id, **request.args)
    return resp.todict()


# --------------------------
# UPDATE
# --------------------------
@api_route.route("/<table>", methods=["PUT"])
@api_route.route("/<table>/", methods=["PUT"])
def update_record(table):
    payload = request.get_json(silent=True)
    if not payload:
        payload = request.form.to_dict()

        print(payload)
        conditions = json.loads(payload.pop("conditions", ""))
        payload = {"data": payload, "conditions": conditions}

    print(payload)

    if not payload or "conditions" not in payload or "data" not in payload:
        return {
            "error": True,
            "message": "Payload must include 'conditions' and 'data'",
        }, 400

    with Database() as db:
        resp = db.update(table, payload["data"], payload["conditions"])

    # Manejar archivos si existen
    if not resp.error and request.files:

        # Usar lastrowid o id de condiciones para nombrar el archivo
        record_id = payload["conditions"].get("id") or resp.lastrowid

        clean_uploaded_avtar(table, record_id)
        for _, file in request.files.items():
            # Crear carpeta si no existe
            upload_path = Path(current_app.root_path).joinpath(
                "uploads", "avatars", table
            )
            upload_path.mkdir(parents=True, exist_ok=True)

            # Obtener extensión y generar nombre de archivo
            extension = os.path.splitext(file.filename)[1].lower()

            filename = f"{record_id}{extension}"
            file_path = upload_path.joinpath(filename)

            # Guardar archivo
            file.save(file_path)
            print(f"Archivo actualizado en: {file_path}")

    return resp.todict()


# --------------------------
# DELETE
# --------------------------


@api_route.route("/<table>", methods=["DELETE"])
@api_route.route("/<table>/", methods=["DELETE"])
def delete_record(table):
    payload = request.json
    if not payload or "conditions" not in payload:
        return {"error": True, "message": "Payload must include 'conditions'"}, 400

    with Database() as db:
        resp = db.delete(table, payload["conditions"])
    return resp.todict()


api_route.register_blueprint(api_custom)
