from fastapi import APIRouter, Depends, Query, status
from sqlalchemy.orm import Session
from typing import Optional, List
from utils.utils import get_db
from . import handler
from .schema import (
    UserCreate, UserUpdate, UserResponse,
    UseractivityCreate, UseractivityUpdate, UseractivityResponse,
    UserLogin, UserRegister, LoginResponse, UseractivityWithStock
)

router = APIRouter(prefix="/users", tags=["User Management"])


# User routes
@router.post(
    "/",
    response_model=UserResponse,
    status_code=status.HTTP_201_CREATED,
    summary="Create User",
    description="Creates a new user account. Validates email uniqueness and password strength. Returns 409 if email already exists. Passwords must be at least 8 characters with 1 uppercase, 1 lowercase, and 1 number."
)
def create_user_route(data: UserCreate, db: Session = Depends(get_db)):
    return handler.create_user(db, data)


@router.get(
    "/",
    response_model=List[UserResponse],
    summary="List Users",
    description="Returns a paginated list of users. Supports optional filters for role, status, and search by email or name. Search is case-insensitive and matches partial strings."
)
def list_users_route(
    limit: int = Query(20, ge=1, le=100),
    offset: int = Query(0, ge=0),
    role: Optional[str] = None,
    status: Optional[str] = None,
    search: Optional[str] = None,
    db: Session = Depends(get_db)
):
    return handler.list_users(db, limit, offset, role, status, search)


@router.get(
    "/{user_id}",
    response_model=UserResponse,
    summary="Get User",
    description="Retrieves a single user by ID. Returns 404 if user does not exist."
)
def get_user_route(user_id: str, db: Session = Depends(get_db)):
    return handler.get_user(db, user_id)


@router.put(
    "/{user_id}",
    response_model=UserResponse,
    summary="Update User",
    description="Updates an existing user. All fields are optional. Validates email uniqueness if email is changed. Returns 404 if user not found, 409 if new email already exists."
)
def update_user_route(user_id: str, data: UserUpdate, db: Session = Depends(get_db)):
    return handler.update_user(db, user_id, data)


@router.delete(
    "/{user_id}",
    status_code=status.HTTP_200_OK,
    summary="Delete User",
    description="Deletes a user account. Administrator accounts cannot be deleted. Returns 400 if attempting to delete an administrator, 404 if user not found."
)
def delete_user_route(user_id: str, db: Session = Depends(get_db)):
    return handler.delete_user(db, user_id)


# Authentication routes
@router.post(
    "/register",
    response_model=UserResponse,
    status_code=status.HTTP_201_CREATED,
    summary="Register New User",
    description="Registers a new user account with email and password. Validates email uniqueness and password strength. Automatically assigns REGISTERED role and ACTIVE status. Returns 409 if email already exists."
)
def register_user_route(data: UserRegister, db: Session = Depends(get_db)):
    return handler.register_user(db, data)


@router.post(
    "/login",
    summary="Authenticate User",
    description="Authenticates a user with email and password. Validates credentials and account status. Updates last login timestamp. Returns 400 if credentials invalid or account is suspended/inactive."
)
def login_user_route(data: UserLogin, db: Session = Depends(get_db)):
    return handler.login_user(db, data)


@router.post(
    "/logout",
    summary="Log Out User",
    description="Logs out the current user. In a production system, this would invalidate the JWT token. Returns success message."
)
def logout_user_route(user_id: str, db: Session = Depends(get_db)):
    return handler.logout_user(db, user_id)


# User activity routes
@router.post(
    "/activities",
    response_model=UseractivityResponse,
    status_code=status.HTTP_201_CREATED,
    summary="Create User Activity",
    description="Logs a user activity (view, search, or favorite) for a stock. Validates that both user and stock exist. Returns 404 if user or stock not found."
)
def create_user_activity_route(data: UseractivityCreate, db: Session = Depends(get_db)):
    return handler.create_user_activity(db, data)


@router.get(
    "/activities/list",
    response_model=List[UseractivityResponse],
    summary="List User Activities",
    description="Returns a paginated list of user activities. Supports optional filters for user_id, stock_id, activity_type, and session_id. Results are ordered by timestamp descending."
)
def list_user_activities_route(
    limit: int = Query(20, ge=1, le=100),
    offset: int = Query(0, ge=0),
    user_id: Optional[str] = None,
    stock_id: Optional[str] = None,
    activity_type: Optional[str] = None,
    session_id: Optional[str] = None,
    db: Session = Depends(get_db)
):
    return handler.list_user_activities(db, limit, offset, user_id, stock_id, activity_type, session_id)


@router.get(
    "/activities/{activity_id}",
    response_model=UseractivityResponse,
    summary="Get User Activity",
    description="Retrieves a single user activity by ID. Returns 404 if activity does not exist."
)
def get_user_activity_route(activity_id: str, db: Session = Depends(get_db)):
    return handler.get_user_activity(db, activity_id)


@router.put(
    "/activities/{activity_id}",
    response_model=UseractivityResponse,
    summary="Update User Activity",
    description="Updates an existing user activity. All fields are optional. Validates user and stock existence if those fields are updated. Returns 404 if activity, user, or stock not found."
)
def update_user_activity_route(activity_id: str, data: UseractivityUpdate, db: Session = Depends(get_db)):
    return handler.update_user_activity(db, activity_id, data)


@router.delete(
    "/activities/{activity_id}",
    status_code=status.HTTP_200_OK,
    summary="Delete User Activity",
    description="Deletes a user activity record. Returns 404 if activity not found."
)
def delete_user_activity_route(activity_id: str, db: Session = Depends(get_db)):
    return handler.delete_user_activity(db, activity_id)


@router.get(
    "/{user_id}/activities",
    response_model=List[UseractivityWithStock],
    summary="Get User Activities With Stock Details",
    description="Retrieves all activities for a specific user with associated stock details (ticker, company name, current price). Results are paginated and ordered by timestamp descending. Returns 404 if user not found."
)
def get_user_activities_with_stock_route(
    user_id: str,
    limit: int = Query(20, ge=1, le=100),
    offset: int = Query(0, ge=0),
    db: Session = Depends(get_db)
):
    return handler.get_user_activities_with_stock_details(db, user_id, limit, offset)


@router.post(
    "/activities/log",
    response_model=UseractivityResponse,
    status_code=status.HTTP_201_CREATED,
    summary="Log User Activity",
    description="Convenience endpoint to log a user activity (view, search, or favorite) for a stock. Automatically sets timestamp to current time. Validates that both user and stock exist. Returns 404 if user or stock not found."
)
def log_user_activity_route(
    user_id: str,
    stock_id: str,
    activity_type: str,
    session_id: Optional[str] = None,
    db: Session = Depends(get_db)
):
    return handler.log_user_activity(db, user_id, stock_id, activity_type, session_id)