"""
Auth API routes — login, me, logout, user management (PostgreSQL)
3 roles: admin, editor, viewer
"""
import logging
from fastapi import APIRouter, HTTPException, Depends
from pydantic import BaseModel
from typing import Optional
from auth import hash_password, verify_password, create_access_token
from auth.middleware import get_current_user
from auth.models import get_conn, DASHBOARD_SCHEMA, init_dashboard_schema

logger = logging.getLogger(__name__)
router = APIRouter(prefix="/api/auth", tags=["auth"])

# Ensure schema exists
try:
    init_dashboard_schema()
except Exception:
    pass


class LoginRequest(BaseModel):
    username: str
    password: str


class CreateUserRequest(BaseModel):
    username: str
    password: str
    role: str = "viewer"


class UpdateSettingsRequest(BaseModel):
    settings: dict


class UpdateUserRequest(BaseModel):
    password: Optional[str] = None
    role: Optional[str] = None


VALID_ROLES = ("admin", "editor", "viewer")


# ═══ PUBLIC ENDPOINTS ═══

@router.post("/login")
async def login(req: LoginRequest):
    conn = get_conn()
    try:
        cur = conn.cursor()
        cur.execute(
            f"SELECT id, username, password, role FROM {DASHBOARD_SCHEMA}.admin_users WHERE username = %s",
            (req.username,)
        )
        row = cur.fetchone()
        if not row:
            raise HTTPException(status_code=401, detail="Sai tên đăng nhập hoặc mật khẩu")
        uid, uname, phash, role = row
        if not verify_password(req.password, phash):
            raise HTTPException(status_code=401, detail="Sai tên đăng nhập hoặc mật khẩu")
        # Update last_login
        cur.execute(f"UPDATE {DASHBOARD_SCHEMA}.admin_users SET last_login = NOW() WHERE id = %s", (uid,))
        cur.close()
    finally:
        conn.close()

    token = create_access_token(user_id=uid, username=uname, role=role)
    logger.info(f"✅ User '{uname}' logged in (role={role})")
    return {
        "access_token": token,
        "token_type": "bearer",
        "user": {"id": uid, "username": uname, "role": role},
    }


@router.get("/me")
async def get_me(user: dict = Depends(get_current_user)):
    return {"user": user}


@router.post("/refresh")
async def refresh_token(user: dict = Depends(get_current_user)):
    """Issue a new access token for a currently-authenticated user."""
    new_token = create_access_token(
        user_id=user["id"], username=user["username"], role=user["role"]
    )
    return {"access_token": new_token, "token_type": "bearer"}


@router.put("/me/settings")
async def update_my_settings(req: UpdateSettingsRequest, user: dict = Depends(get_current_user)):
    import json
    conn = get_conn()
    try:
        cur = conn.cursor()
        cur.execute(
            f"UPDATE {DASHBOARD_SCHEMA}.admin_users SET settings = COALESCE(settings, '{{}}'::jsonb) || %s::jsonb WHERE id = %s",
            (json.dumps(req.settings), user["id"])
        )
        cur.close()
    finally:
        conn.close()
    return {"message": "Cập nhật cài đặt thành công"}


# ═══ ADMIN-ONLY: User Management ═══

def _require_admin(user: dict = Depends(get_current_user)):
    if user.get("role") != "admin":
        raise HTTPException(status_code=403, detail="Chỉ admin mới có quyền này")
    return user


@router.get("/users")
async def list_users(admin: dict = Depends(_require_admin)):
    conn = get_conn()
    try:
        cur = conn.cursor()
        cur.execute(f"""
            SELECT id, username, role, created_at, last_login
            FROM {DASHBOARD_SCHEMA}.admin_users ORDER BY id
        """)
        rows = cur.fetchall()
        cur.close()
    finally:
        conn.close()
    return {"users": [
        {"id": r[0], "username": r[1], "role": r[2],
         "created_at": r[3].isoformat() if r[3] else None,
         "last_login": r[4].isoformat() if r[4] else None}
        for r in rows
    ]}


@router.post("/users")
async def create_user(req: CreateUserRequest, admin: dict = Depends(_require_admin)):
    if req.role not in VALID_ROLES:
        raise HTTPException(status_code=400, detail=f"Role phải là: {', '.join(VALID_ROLES)}")
    conn = get_conn()
    try:
        cur = conn.cursor()
        cur.execute(f"SELECT id FROM {DASHBOARD_SCHEMA}.admin_users WHERE username = %s", (req.username,))
        if cur.fetchone():
            raise HTTPException(status_code=400, detail=f"Username '{req.username}' đã tồn tại")
        hashed = hash_password(req.password)
        cur.execute(
            f"INSERT INTO {DASHBOARD_SCHEMA}.admin_users (username, password, role) VALUES (%s, %s, %s)",
            (req.username, hashed, req.role),
        )
        cur.close()
    finally:
        conn.close()
    logger.info(f"✅ Admin '{admin['username']}' created user '{req.username}' (role={req.role})")
    return {"message": f"Tạo user '{req.username}' thành công"}


@router.put("/users/{user_id}")
async def update_user(user_id: int, req: UpdateUserRequest, admin: dict = Depends(_require_admin)):
    conn = get_conn()
    try:
        cur = conn.cursor()
        cur.execute(f"SELECT id FROM {DASHBOARD_SCHEMA}.admin_users WHERE id = %s", (user_id,))
        if not cur.fetchone():
            raise HTTPException(status_code=404, detail="User không tồn tại")
        if req.password:
            hashed = hash_password(req.password)
            cur.execute(f"UPDATE {DASHBOARD_SCHEMA}.admin_users SET password = %s WHERE id = %s", (hashed, user_id))
        if req.role:
            if req.role not in VALID_ROLES:
                raise HTTPException(status_code=400, detail=f"Role phải là: {', '.join(VALID_ROLES)}")
            cur.execute(f"UPDATE {DASHBOARD_SCHEMA}.admin_users SET role = %s WHERE id = %s", (req.role, user_id))
        cur.close()
    finally:
        conn.close()
    return {"message": "Cập nhật thành công"}


@router.delete("/users/{user_id}")
async def delete_user(user_id: int, admin: dict = Depends(_require_admin)):
    if user_id == admin["id"]:
        raise HTTPException(status_code=400, detail="Không thể xóa chính mình")
    conn = get_conn()
    try:
        cur = conn.cursor()
        cur.execute(f"SELECT username FROM {DASHBOARD_SCHEMA}.admin_users WHERE id = %s", (user_id,))
        row = cur.fetchone()
        if not row:
            raise HTTPException(status_code=404, detail="User không tồn tại")
        cur.execute(f"DELETE FROM {DASHBOARD_SCHEMA}.admin_users WHERE id = %s", (user_id,))
        cur.close()
    finally:
        conn.close()
    logger.info(f"🗑️ Admin '{admin['username']}' deleted user '{row[0]}'")
    return {"message": f"Đã xóa user '{row[0]}'"}


# ═══ ADMIN: Dashboard Stats ═══

@router.get("/stats")
async def get_dashboard_stats(admin: dict = Depends(_require_admin)):
    """Get overview stats for admin dashboard."""
    conn = get_conn()
    try:
        cur = conn.cursor()
        # Total users
        cur.execute(f"SELECT COUNT(*) FROM {DASHBOARD_SCHEMA}.admin_users")
        total_users = cur.fetchone()[0]
        # Users by role
        cur.execute(f"SELECT role, COUNT(*) FROM {DASHBOARD_SCHEMA}.admin_users GROUP BY role")
        role_counts = {r[0]: r[1] for r in cur.fetchall()}

        # Try to get chat stats from canifa_chat schema
        chat_total = 0
        chat_today = 0
        try:
            cur.execute("SELECT COUNT(*) FROM canifa_chat.checkpoints")
            chat_total = cur.fetchone()[0]
            cur.execute("SELECT COUNT(*) FROM canifa_chat.checkpoints WHERE created_at >= CURRENT_DATE")
            chat_today = cur.fetchone()[0]
        except Exception:
            pass

        cur.close()
    finally:
        conn.close()

    return {
        "total_users": total_users,
        "role_counts": role_counts,
        "chat_total": chat_total,
        "chat_today": chat_today,
    }


# ═══ BOOTSTRAP: Register first admin ═══

@router.post("/register")
async def register_first_admin(req: LoginRequest):
    conn = get_conn()
    try:
        cur = conn.cursor()
        cur.execute(f"SELECT COUNT(*) FROM {DASHBOARD_SCHEMA}.admin_users")
        count = cur.fetchone()[0]
        if count > 0:
            raise HTTPException(status_code=403, detail="Đã có user. Liên hệ admin để tạo tài khoản.")
        hashed = hash_password(req.password)
        cur.execute(
            f"INSERT INTO {DASHBOARD_SCHEMA}.admin_users (username, password, role) VALUES (%s, %s, 'admin')",
            (req.username, hashed),
        )
        cur.close()
    finally:
        conn.close()
    logger.info(f"✅ First admin '{req.username}' registered")
    return {"message": f"Admin '{req.username}' created. Hãy đăng nhập."}
