from fastapi import APIRouter, Request, Form, UploadFile, HTTPException, Depends
from fastapi.responses import HTMLResponse, RedirectResponse, JSONResponse
import os
import secrets
from ..database import templates, BASE_DIR, _conn
from .deps import rotate_session, pwd_context, current_user
from .crud import get_user_by_email, create_user, _upsert_satellites_empty

router = APIRouter()

@router.get("/login", name="login", response_class=HTMLResponse)
async def login_get(request: Request):
    return templates.TemplateResponse("login.html", {"request": request, "error": None})

@router.post("/login", name="login_post", response_class=HTMLResponse)
async def login_post(request: Request, email: str = Form(...), password: str = Form(...)):
    email_norm = email.strip().lower()
    user = get_user_by_email(email_norm)
    if not user or not pwd_context.verify(password, user["password_hash"]):
        return templates.TemplateResponse("login.html", {"request": request, "error": "Credenciales inválidas"})
    rotate_session(request)
    request.session["user_id"] = int(user["id"])
    request.session["role"] = user["role"]
    if user["role"] == "admin" or email_norm == "admin@admin.es":
        return RedirectResponse(url=request.url_for("reservas_dashboard"), status_code=303)
    elif user["role"] == "docente":
        return RedirectResponse(url=request.url_for("docente"), status_code=303)
    else:
        return RedirectResponse(url=request.url_for("dashboard"), status_code=303)

@router.get("/register", name="register", response_class=HTMLResponse)
async def register_get(request: Request):
    me = current_user(request)
    ctx_user = me or {"name": "", "email": "", "phone": ""}
    return templates.TemplateResponse("register.html", {"request": request, "error": None, "user": ctx_user})

@router.post("/register", name="register_post", response_class=HTMLResponse)
async def register_post(request: Request, name: str = Form(...), email: str = Form(...), password: str = Form(...)):
    email_norm = email.strip().lower()
    if get_user_by_email(email_norm):
        return templates.TemplateResponse(
            "register.html",
            {"request": request, "error": "Ese email ya existe", "user": {"name": name.strip(), "email": email_norm, "phone": ""}}
        )
    if len(password) < 6:
        return templates.TemplateResponse(
            "register.html",
            {"request": request, "error": "La contraseña debe tener 6+ caracteres", "user": {"name": name.strip(), "email": email_norm, "phone": ""}}
        )
    create_user(name.strip(), email_norm, password, role="alumno")
    user = get_user_by_email(email_norm)
    request.session["user_id"] = int(user["id"])
    request.session["role"] = user["role"]
    if user["role"] == "admin" or email_norm == "admin@admin.es":
        return RedirectResponse(url=request.url_for("reservas_dashboard"), status_code=303)
    else:
        return RedirectResponse(url=request.url_for("dashboard"), status_code=303)

@router.get("/academy-register", name="academy_register_get", response_class=HTMLResponse)
async def academy_register_get(request: Request):
    me = current_user(request)
    return templates.TemplateResponse(
        "academy-register.html",
        {"request": request, "user": me}
    )

@router.post("/academy-register", name="academy_register_post")
async def academy_register_post(request: Request):
    form = await request.form()
    email = (form.get("email") or "").strip().lower()
    name  = (form.get("name")  or "").strip()
    password = (form.get("password") or "")
    first_name = (form.get("firstName") or "").strip()
    last_name = (form.get("lastName") or "").strip()

    if not email:
        raise HTTPException(status_code=400, detail="El email es obligatorio.")
    if not first_name or len(first_name) < 2:
        raise HTTPException(status_code=400, detail="Indica tu nombre.")
    if not last_name or len(last_name) < 2:
        raise HTTPException(status_code=400, detail="Indica tus apellidos.")
    if not name or len(name) < 2:
        raise HTTPException(status_code=400, detail="Indica tu nombre (mínimo 2 caracteres).")
    if not password or len(password) < 6:
        raise HTTPException(status_code=400, detail="La contraseña debe tener al menos 6 caracteres.")
    
    # --- New Mandatory Validations ---
    if not form.get("dni"): raise HTTPException(status_code=400, detail="El DNI es obligatorio.")
    if not form.get("birthDate"): raise HTTPException(status_code=400, detail="La fecha de nacimiento es obligatoria.")
    if not form.get("gender"): raise HTTPException(status_code=400, detail="El sexo es obligatorio.")
    if not form.get("occupation"): raise HTTPException(status_code=400, detail="Indica si estudias o trabajas.")
    if not form.get("studyPlace"): raise HTTPException(status_code=400, detail="Indica dónde estudias.")
    if not form.get("category"): raise HTTPException(status_code=400, detail="Selecciona una categoría.")
    if not form.get("currentTeam"): raise HTTPException(status_code=400, detail="Indica tu equipo actual.")
    
    if not form.get("currentPosition"): raise HTTPException(status_code=400, detail="Indica tu posición actual.")
    if not form.get("dominantFoot"): raise HTTPException(status_code=400, detail="Indica tu pierna dominante.")
    if not form.get("preferredPosition"): raise HTTPException(status_code=400, detail="Indica tu posición preferida.")
    
    if not form.get("parentName"): raise HTTPException(status_code=400, detail="El nombre del tutor es obligatorio.")
    if not form.get("phone"): raise HTTPException(status_code=400, detail="El teléfono es obligatorio.")
    if not form.get("parentEmail"): raise HTTPException(status_code=400, detail="El email del tutor es obligatorio.")
    if not form.get("city"): raise HTTPException(status_code=400, detail="La ciudad es obligatoria.")
    if not form.get("foundUs"): raise HTTPException(status_code=400, detail="Indica cómo nos conociste.")
    
    if not form.get("trainingType"): raise HTTPException(status_code=400, detail="Indica el tipo de entrenamiento.")
    if not form.get("commitment"): raise HTTPException(status_code=400, detail="Confirma tu compromiso.")
    if not form.get("videoPermission"): raise HTTPException(status_code=400, detail="Indica el permiso de vídeo.")
    if not form.get("whatsappContent"): raise HTTPException(status_code=400, detail="Indica preferencia de WhatsApp.")
    
    if not form.get("strengths"): raise HTTPException(status_code=400, detail="Indica tus virtudes.")
    if not form.get("weaknesses"): raise HTTPException(status_code=400, detail="Indica tus defectos/mejoras.")
    
    if not form.get("nervesConfidence"): raise HTTPException(status_code=400, detail="Responde sobre nervios/confianza.")
    if not form.get("discomfort"): raise HTTPException(status_code=400, detail="Responde sobre malestar.")
    if not form.get("enjoyment"): raise HTTPException(status_code=400, detail="Responde sobre disfrute/motivación.")
    if not form.get("recovery"): raise HTTPException(status_code=400, detail="Responde sobre recuperación.")
    
    if not form.get("injuries"): raise HTTPException(status_code=400, detail="Indica historial de lesiones.")
    physical_work = form.get("physicalWork")
    if not physical_work: raise HTTPException(status_code=400, detail="Indica si has hecho trabajo físico.")
    if physical_work == "si" and not form.get("physicalWorkDetails"):
        raise HTTPException(status_code=400, detail="Si has hecho trabajo físico, detalla dónde y cuánto tiempo.")
    
    if not form.get("alcohol"): raise HTTPException(status_code=400, detail="Indica consumo de alcohol.")
    if not form.get("smoking"): raise HTTPException(status_code=400, detail="Indica consumo de tabaco.")
    # ---------------------------------
    existing = get_user_by_email(email)
    if existing:
        raise HTTPException(status_code=409, detail="Ya existe un usuario con ese email. Inicia sesión.")
    # Store photo content temporarily (before user creation)
    photo_content = None
    photo_ext = None
    player_photo = form.get("playerPhoto")
    is_upload = hasattr(player_photo, 'filename') and hasattr(player_photo, 'read')
    if is_upload and player_photo.filename:
        try:
            photo_content = await player_photo.read()
            if photo_content:
                photo_ext = os.path.splitext(player_photo.filename)[1].lower() or ".jpg"
        except Exception as e:
            print(f"ERROR: Failed to read photo: {e}")
    
    # Create user first
    create_user(name.strip(), email, password, role="alumno", first_name=first_name, last_name=last_name)
    user = get_user_by_email(email)
    user_id = int(user["id"])
    
    # Now save photo with user_ID.ext format
    avatar_path = None
    if photo_content and photo_ext:
        try:
            uploads_dir = BASE_DIR / "static" / "uploads"
            uploads_dir.mkdir(parents=True, exist_ok=True)
            filename = f"user_{user_id}{photo_ext}"
            file_path = uploads_dir / filename
            with open(file_path, "wb") as f:
                f.write(photo_content)
            avatar_path = f"/static/uploads/{filename}"
        except Exception as e:
            print(f"ERROR: Failed to save photo to disk: {e}")
    
    data: dict[str, str] = {}
    for k, v in form.items():
        if isinstance(v, UploadFile):
            continue
        if v not in (None, "", "null"):
            data[k] = str(v)
    def pick(*keys):
        for k in keys:
            val = data.get(k)
            if val not in (None, "", "null"):
                return val
        return None
    profile_vals = {
        "phone": pick("phone", "whatsapp"),
        "dni": pick("dni"),
        "birth_date": pick("birthDate", "birth_date"),
        "city": pick("city"),
        "avatar": avatar_path or pick("playerPhoto", "avatar")
    }
    sports_vals = {
        "team": pick("currentTeam", "team", "club"),
        "category": pick("category"),
        "position": pick("currentPosition", "preferredPosition", "position"),
        "dominant_foot": pick("dominantFoot"),
        "strengths": pick("strengths"),
        "weaknesses": pick("weaknesses"),
        "training_type": pick("trainingType"),
        "injury_history": pick("injuries", "injuryHistory", "injury_history")
    }
    health_vals = {
        "physical_work": pick("physicalWork"),
        "physical_work_details": pick("physicalWorkDetails"),
        "smoking": pick("smoking"),
        "alcohol": pick("alcohol"),
        "recovery": pick("recovery"),
        "chest_pain": pick("chestPain"),
        "discomfort": pick("discomfort")
    }
    consent_vals = {
        "whatsapp_content": pick("whatsappContent"),
        "video_permission": pick("videoPermission"),
        "privacy_acceptance": pick("privacyAcceptance"),
        "data_confirmation": pick("dataConfirmation"),
        "agreement": pick("agreement")
    }
    guardians_vals = {
        "occupation": pick("occupation"),
        "study_place": pick("studyPlace", "study_place"),
        "parent_name": pick("parentName", "parent_name"),
        "parent_email": pick("parentEmail", "parent_email")
    }
    marketing_vals = {
        "found_us": pick("foundUs", "found_us"),
        "enjoyment": pick("enjoyment"),
        "nerves_confidence": pick("nervesConfidence", "nerves_confidence"),
        "additional_comments": pick("additionalComments", "additional_comments")
    }
    with _conn() as conn:
        _upsert_satellites_empty(conn, user_id)
        if any(v is not None for v in profile_vals.values()):
            sets = ", ".join([f"{k}=COALESCE(?, {k})" for k in profile_vals.keys()])
            conn.execute(f"UPDATE user_profile SET {sets} WHERE user_id=?", (*profile_vals.values(), user_id))
        if any(v is not None for v in sports_vals.values()):
            sets = ", ".join([f"{k}=COALESCE(?, {k})" for k in sports_vals.keys()])
            conn.execute(f"UPDATE user_sports SET {sets} WHERE user_id=?", (*sports_vals.values(), user_id))
        if any(v is not None for v in health_vals.values()):
            sets = ", ".join([f"{k}=COALESCE(?, {k})" for k in health_vals.keys()])
            conn.execute(f"UPDATE user_health SET {sets} WHERE user_id=?", (*health_vals.values(), user_id))
        if any(v is not None for v in consent_vals.values()):
            sets = ", ".join([f"{k}=COALESCE(?, {k})" for k in consent_vals.keys()])
            conn.execute(f"UPDATE user_consent SET {sets} WHERE user_id=?", (*consent_vals.values(), user_id))
        if any(v is not None for v in guardians_vals.values()):
            sets = ", ".join([f"{k}=COALESCE(?, {k})" for k in guardians_vals.keys()])
            conn.execute(f"UPDATE user_guardians SET {sets} WHERE user_id=?", (*guardians_vals.values(), user_id))
        if any(v is not None for v in marketing_vals.values()):
            sets = ", ".join([f"{k}=COALESCE(?, {k})" for k in marketing_vals.keys()])
            conn.execute(f"UPDATE user_marketing SET {sets} WHERE user_id=?", (*marketing_vals.values(), user_id))
        conn.commit()

    return JSONResponse({"ok": True, "redirect": "/login"})
