from fastapi import APIRouter, Depends, HTTPException
from pydantic import BaseModel
from sqlalchemy import text

from .auth import hash_password, verify_password, require_token
from .db import get_db

# Staff sign-in: email + password → the staff member's bearer token (the SPA stores it as before,
# so nothing downstream changes — this just puts a friendly credential in front of the token).
router = APIRouter(prefix="/auth", tags=["auth"])


class LoginIn(BaseModel):
    email: str
    password: str


@router.post("/login")
async def login(body: LoginIn, db=Depends(get_db)):
    row = (await db.execute(text(
        "SELECT id, name, role, token, password_hash FROM staff WHERE lower(email)=lower(:e) AND active"),
        {"e": body.email.strip()})).mappings().first()
    if not row or not verify_password(body.password, row["password_hash"]):
        raise HTTPException(401, "wrong email or password")
    await db.execute(text("UPDATE staff SET last_seen=now() WHERE id=:i"), {"i": row["id"]})
    await db.commit()
    return {"ok": True, "token": row["token"], "name": row["name"], "role": row["role"]}


class ChangePwIn(BaseModel):
    current_password: str | None = None
    new_password: str


@router.post("/change-password")
async def change_password(body: ChangePwIn, ident=Depends(require_token), db=Depends(get_db)):
    sid = ident.get("staff_id")
    if not sid:
        raise HTTPException(400, "the owner signs in with the master token; only staff have passwords")
    if len(body.new_password) < 6:
        raise HTTPException(400, "password too short (min 6 characters)")
    cur = (await db.execute(text("SELECT password_hash FROM staff WHERE id=:i"), {"i": sid})).scalar()
    # if a password is already set, the old one must check out; first-time set needs no current pw
    if cur and not verify_password(body.current_password or "", cur):
        raise HTTPException(401, "current password is incorrect")
    await db.execute(text("UPDATE staff SET password_hash=:h WHERE id=:i"),
                     {"h": hash_password(body.new_password), "i": sid})
    await db.commit()
    return {"ok": True}
