import os
import uuid

from flask import Blueprint, render_template, redirect, url_for, flash, current_app, request
from flask_login import login_required, current_user
from werkzeug.utils import secure_filename

from app.extensions import db
from app.models import Document, IntakeEvent
from app.profiles.helpers import get_active_patient

documents_bp = Blueprint(
    "documents", __name__, url_prefix="/documentos", template_folder="../templates/documents"
)


@documents_bp.before_request
def require_active_profile():
    if not current_user.is_authenticated:
        return None  # let @login_required handle the redirect to login
    if current_user.is_admin():
        return redirect(url_for("admin.index"))
    if get_active_patient() is None:
        flash("Elige o crea un perfil para continuar.", "info")
        return redirect(url_for("profiles.list_profiles"))
    return None


EXT_TO_MIME = {
    "pdf": "application/pdf",
    "png": "image/png",
    "jpg": "image/jpeg",
    "jpeg": "image/jpeg",
}


def _allowed_file(filename: str) -> bool:
    ext = filename.rsplit(".", 1)[-1].lower() if "." in filename else ""
    return ext in current_app.config["ALLOWED_EXTENSIONS"]


@documents_bp.route("/subir", methods=["GET", "POST"])
@login_required
def upload():
    patient = get_active_patient()

    if request.method == "POST":
        uploaded_files = request.files.getlist("files")
        uploaded_files = [f for f in uploaded_files if f and f.filename]

        if not uploaded_files:
            flash("Selecciona al menos un archivo (PDF, JPG o PNG).", "warning")
            return redirect(url_for("documents.upload"))

        patient_folder = os.path.join(current_app.config["UPLOAD_FOLDER"], str(patient.id))
        os.makedirs(patient_folder, exist_ok=True)

        saved = 0
        for file in uploaded_files:
            if not _allowed_file(file.filename):
                flash(f"Tipo de archivo no permitido: {file.filename}", "danger")
                continue

            ext = file.filename.rsplit(".", 1)[-1].lower()
            safe_name = secure_filename(file.filename)
            stored_name = f"{uuid.uuid4().hex}_{safe_name}"
            storage_path = os.path.join(patient_folder, stored_name)
            file.save(storage_path)

            document = Document(
                patient_id=patient.id,
                original_filename=safe_name,
                storage_path=storage_path,
                mime_type=EXT_TO_MIME.get(ext, "application/octet-stream"),
                status=Document.STATUS_PENDING,
                source_channel="web",
            )
            db.session.add(document)
            db.session.flush()

            db.session.add(IntakeEvent(
                channel="web",
                status=IntakeEvent.STATUS_MATCHED,
                sender_identifier=current_user.email,
                subject=safe_name,
                user_id=current_user.id,
                patient_id=patient.id,
                document_id=document.id,
            ))
            saved += 1

        db.session.commit()
        if saved:
            flash(
                f"{saved} documento(s) recibido(s) para {patient.full_name}. "
                "Se procesarán en los próximos minutos.",
                "success",
            )
        return redirect(url_for("documents.list_documents"))

    return render_template("documents/upload.html", patient=patient)


@documents_bp.route("/")
@login_required
def list_documents():
    patient = get_active_patient()
    return render_template("documents/list.html", documents=patient.documents, patient=patient)
