from fastapi import APIRouter, Request, Form, Depends
from fastapi.responses import HTMLResponse, RedirectResponse
from fastapi.templating import Jinja2Templates
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select
from app.core.database import get_db
from app.models.models import User, UserRole
from app.core.security import require_roles, get_current_user
import bcrypt
import os

router = APIRouter(dependencies=[Depends(require_roles("super_admin"))])
BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
templates = Jinja2Templates(directory=os.path.join(BASE_DIR, "app/templates"))
VALID_ROLES = {role.value for role in UserRole}


def hash_password(password: str) -> str:
    return bcrypt.hashpw(password.encode(), bcrypt.gensalt()).decode()


@router.get("/users", response_class=HTMLResponse)
async def users_page(request: Request, db: AsyncSession = Depends(get_db)):
    result = await db.execute(select(User).order_by(User.id))
    users = result.scalars().all()
    return templates.TemplateResponse(request=request, name="users.html", context={"users": users})


@router.post("/users/create")
async def create_user(
    request: Request,
    username: str = Form(...),
    full_name: str = Form(...),
    password: str = Form(...),
    role: str = Form(...),
    db: AsyncSession = Depends(get_db),
):
    username = username.strip()
    full_name = full_name.strip()
    if not username or not full_name or len(password) < 8 or role not in VALID_ROLES:
        return RedirectResponse(url="/users?error=invalid", status_code=303)
    existing = await db.scalar(select(User).where(User.username == username))
    if existing:
        return RedirectResponse(url="/users?error=username_exists", status_code=303)
    db.add(User(username=username, full_name=full_name, hashed_password=hash_password(password), role=role, is_active=True))
    await db.commit()
    return RedirectResponse(url="/users?success=created", status_code=303)


@router.post("/users/{user_id}/toggle")
async def toggle_user(
    user_id: int,
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    user = await db.get(User, user_id)
    if not user or user.id == current_user.id:
        return RedirectResponse(url="/users?error=invalid_target", status_code=303)
    user.is_active = not user.is_active
    await db.commit()
    return RedirectResponse(url="/users?success=toggled", status_code=303)


@router.post("/users/{user_id}/reset-password")
async def reset_password(
    user_id: int,
    password: str = Form(...),
    db: AsyncSession = Depends(get_db),
):
    user = await db.get(User, user_id)
    if not user or len(password) < 8:
        return RedirectResponse(url="/users?error=invalid_password", status_code=303)
    user.hashed_password = hash_password(password)
    await db.commit()
    return RedirectResponse(url="/users?success=password_reset", status_code=303)
