"""
4Alarm - Multi-Tenant Alarm System
Main FastAPI server
"""
from fastapi import FastAPI, Depends, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from motor.motor_asyncio import AsyncIOMotorClient
from dotenv import load_dotenv
from datetime import datetime, timezone, timedelta
from jose import jwt, JWTError
import os
import bcrypt
import uuid

load_dotenv()

app = FastAPI(title="4Alarm API", version="1.0.0")

app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# Database
client = AsyncIOMotorClient(os.environ.get("MONGO_URL"))
db = client[os.environ.get("DB_NAME")]

JWT_SECRET = os.environ.get("JWT_SECRET")
JWT_ALGORITHM = "HS256"
JWT_EXPIRE_HOURS = 72


# ── Auth helpers ──────────────────────────────────────────────

def create_token(user_id: str, tenant_id: str, rol: str) -> str:
    payload = {
        "sub": user_id,
        "tenant_id": tenant_id,
        "rol": rol,
        "exp": datetime.now(timezone.utc) + timedelta(hours=JWT_EXPIRE_HOURS),
    }
    return jwt.encode(payload, JWT_SECRET, algorithm=JWT_ALGORITHM)


async def get_current_user(authorization: str = None):
    """Extract user from JWT Bearer token."""
    if not authorization:
        from fastapi import Request
        raise HTTPException(status_code=401, detail="Token requerido")
    token = authorization.replace("Bearer ", "") if authorization.startswith("Bearer ") else authorization
    try:
        payload = jwt.decode(token, JWT_SECRET, algorithms=[JWT_ALGORITHM])
        user_id = payload.get("sub")
        if not user_id:
            raise HTTPException(status_code=401, detail="Token invalido")
        user = await db.users.find_one({"id": user_id}, {"_id": 0, "password_hash": 0})
        if not user:
            raise HTTPException(status_code=401, detail="Usuario no encontrado")
        return user
    except JWTError:
        raise HTTPException(status_code=401, detail="Token invalido")


# ── Auth dependency via Header ──────────────────────────────
from fastapi import Header

async def auth_dep(authorization: str = Header(None)):
    if not authorization:
        raise HTTPException(status_code=401, detail="Token requerido")
    return await get_current_user(authorization)


# ── Startup: seed super-admin ──────────────────────────────
@app.on_event("startup")
async def startup():
    existing = await db.users.find_one({"email": "superadmin@4alarm.cl"})
    if not existing:
        pw = bcrypt.hashpw("Admin1234!".encode(), bcrypt.gensalt()).decode()
        await db.users.insert_one({
            "id": str(uuid.uuid4()),
            "email": "superadmin@4alarm.cl",
            "nombre": "Super Admin",
            "rol": "superadmin",
            "tenant_id": "__global__",
            "password_hash": pw,
            "created_at": datetime.now(timezone.utc).isoformat(),
        })
        print("[4Alarm] Super admin creado: superadmin@4alarm.cl / Admin1234!")

    # Seed tenant "La Colina" if not exists
    existing_tenant = await db.tenants.find_one({"slug": "la_colina"})
    if not existing_tenant:
        tenant_id = str(uuid.uuid4())
        await db.tenants.insert_one({
            "id": tenant_id,
            "nombre": "La Colina",
            "slug": "la_colina",
            "estado": "activo",
            "tuya_access_id": "wpuqrta3dm8s735makfx",
            "tuya_access_secret": "c90380e5b3844d0d9de89bffef0f484f",
            "tuya_endpoint": "https://openapi.tuyaus.com",
            "vapid_public_key": "BMIkG3ljSZBgKPbyLuao7053srJIm_IZ3kAeg-qmpYIwS_8uKEjlNhPfSqafxjSbnZVlJD0CT40lpfSbzTzAhVM",
            "vapid_private_key": "Xr-oXp2WC82NYyFakIhDYmwtllZ-o18RqQhDpWHzKuQ",
            "created_at": datetime.now(timezone.utc).isoformat(),
        })
        # Create admin for La Colina
        pw_admin = bcrypt.hashpw("LaColina2024!".encode(), bcrypt.gensalt()).decode()
        await db.users.insert_one({
            "id": str(uuid.uuid4()),
            "email": "admin@lacolina.cl",
            "nombre": "Admin La Colina",
            "rol": "admin",
            "tenant_id": tenant_id,
            "password_hash": pw_admin,
            "created_at": datetime.now(timezone.utc).isoformat(),
        })
        # Seed app config
        await db.app_config.insert_one({
            "tenant_id": tenant_id,
            "custom_icon": False,
            "long_press_ms": 1000,
            "sos_long_press_ms": 1500,
        })
        await db.chat_config.insert_one({
            "tenant_id": tenant_id,
            "activo": False,
            "duracion_minutos": 15,
        })
        print("[4Alarm] Tenant 'La Colina' creado con admin: admin@lacolina.cl / LaColina2024!")

    # Ensure indexes
    await db.users.create_index("email", unique=True)
    await db.users.create_index("tenant_id")
    await db.devices.create_index("tenant_id")
    await db.assignments.create_index([("tenant_id", 1), ("usuario_id", 1)])
    await db.events.create_index([("tenant_id", 1), ("created_at", -1)])
    await db.notifications.create_index([("usuario_id", 1), ("leida", 1)])


# ── Auth Routes ──────────────────────────────────────────────
@app.post("/api/auth/login")
async def login(data: dict):
    email = (data.get("email") or "").strip().lower()
    password = data.get("password") or ""
    if not email or not password:
        raise HTTPException(status_code=400, detail="Email y contraseña requeridos")
    user = await db.users.find_one({"email": email})
    if not user:
        raise HTTPException(status_code=401, detail="Credenciales inválidas")
    stored = user.get("password_hash") or ""
    if not bcrypt.checkpw(password.encode(), stored.encode()):
        raise HTTPException(status_code=401, detail="Credenciales inválidas")
    token = create_token(user["id"], user.get("tenant_id", ""), user.get("rol", "usuario"))
    user_safe = {k: v for k, v in user.items() if k not in ("_id", "password_hash", "password")}
    return {"access_token": token, "user": user_safe}


@app.get("/api/auth/me")
async def me(user: dict = Depends(auth_dep)):
    return user


# ── Import & mount sub-routers ──────────────────────────────
from routes.tenants import setup_tenant_routes
from routes.alarmas import setup_alarmas_routes
from routes.deploy import setup_deploy_routes

tenant_router = setup_tenant_routes(auth_dep, db)
app.include_router(tenant_router, prefix="/api")

alarmas_router = setup_alarmas_routes(auth_dep, db)
app.include_router(alarmas_router, prefix="/api")

deploy_router = setup_deploy_routes()
app.include_router(deploy_router, prefix="/api")


@app.get("/api/health")
async def health():
    return {"status": "ok", "service": "4alarm-multitenant"}
