import funciones
from typing import Optional, Literal
from fastapi.responses import JSONResponse
from fastapi.middleware.cors import CORSMiddleware
from fastapi import FastAPI, Form, HTTPException, status

#FUTURE: Quizá en el futuro cambiarla de Form a Json con Pydantic.
app = FastAPI()

# Configuración de CORS
origins = [
    "http://localhost",
    "http://localhost:8000", # Si usas algún puerto específico para tu frontend
    "http://127.0.0.1:5500", # Puerto común de Live Server
    "https://splashmix.com", # Si despliegas tu frontend, añade su dominio aquí
    #"*" # ¡CUIDADO! '*' permite CUALQUIER origen. Úsalo solo para desarrollo o si sabes lo que haces.
        # Es más seguro especificar orígenes concretos en producción.
]

app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True, # Permite cookies, cabeceras de autorización, etc.
    allow_methods=["*"],    # Permite todos los métodos (GET, POST, PUT, DELETE, etc.)
    allow_headers=["*"],    # Permite todas las cabeceras
)

# Nuevo endpoint para Health Check
@app.get("/health",
         tags=["Health Check"],
         description="Verifica el estado de salud de la API.",
         summary="Health Check"
         )
async def health_check():
    """
    Este endpoint devuelve una respuesta 200 OK para indicar que la API está funcionando.
    """
    return JSONResponse(content={"status": "ok"}, status_code=200)

@app.post("/creaCliente/")
async def creaCliente(
    email: str = Form(...),
    firebase_user: Optional[str] = Form(None),
    site: Optional[str] = Form(None),
):
    """
    Busca un cliente existente en Stripe, priorizando el Firebase User ID.
    Si no existe, lo busca por email. Si tampoco existe, lo crea.

    Args:
        email (str): El correo electrónico del cliente.
        firebase_user (str, opcional): El ID de usuario de Firebase asociado. **Identificador principal.**
        site (str, opcional): El nombre del sitio de origen.

    Returns:
        dict: Un diccionario con el ID del cliente de Stripe (existente o nuevo)
              si la operación fue exitosa, indicando cómo fue encontrado o si fue creado.
              O un error si la operación falló.
    """
    try:
        customer_result = funciones.create_stripe_customer(
            email=email,
            firebase_user=firebase_user,
            site=site
        )

        if customer_result:
            customer, status = customer_result # Desempaca el objeto customer y el estado
            
            message_text = ""
            if status == "found_by_firebase_user":
                message_text = "Cliente existente encontrado exitosamente por Firebase User ID."
            elif status == "found_by_email":
                message_text = "Cliente existente encontrado exitosamente por email."
            elif status == "created":
                message_text = "Nuevo cliente creado exitosamente."
            else:
                message_text = "Operación de cliente exitosa." # Fallback

            response_data = {
                "message": message_text,
                "status": status, # Agregamos el estado específico también
                "customer_id": customer.id,
                "customer_email": customer.email
            }
            if customer.metadata:
                if 'firebase_user' in customer.metadata:
                    response_data['firebase_user'] = customer.metadata.firebase_user
                if 'site' in customer.metadata:
                    response_data['site'] = customer.metadata.site
            return response_data
        else:
            raise HTTPException(status_code=500, detail="No se pudo procesar la operación del cliente en Stripe. Verifica los logs del servidor.")

    except HTTPException as e:
        raise e
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"Ocurrió un error inesperado al procesar la solicitud: {str(e)}")

@app.post("/creaLinkSesion/")
async def creaLinkSesion(
    price_id: str = Form(...),
    unidades: int = Form(...), # <--- ¡Nuevo parámetro 'unidades' como int!
    mode: Literal["payment", "subscription"] = Form(...), # <--- ¡Nuevo parámetro 'mode' con validación!
    customer_email: Optional[str] = Form(None),
    customer_id: Optional[str] = Form(None),
    firebase_user: Optional[str] = Form(None),
    gaCliente: Optional[str] = Form(None)
):
    """
    Crea una Checkout Session en Stripe.
    Acepta 'unidades' (cantidad) y 'mode' ('payment' o 'subscription').
    """
    try:
        # Llama a la función de Stripe con todos los parámetros, incluyendo los nuevos
        return funciones.create_checkout_session(
            price_id,
            customer_email,
            customer_id,
            firebase_user,
            unidades, # Pasar el nuevo parámetro
            mode,      # Pasar el nuevo parámetro
            gaCliente
        )
    except Exception as e:
        print(f"Error al crear la sesión de checkout: {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Error interno al intentar crear la sesión de checkout: {e}"
        )