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,
    CustomerCreate, CustomerUpdate, CustomerResponse,
    TourguideCreate, TourguideUpdate, TourguideResponse,
    ServiceproviderCreate, ServiceproviderUpdate, ServiceproviderResponse
)

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 with authentication credentials and role assignment. Validates email uniqueness and password strength requirements (minimum 8 characters with uppercase, lowercase, number, and special character). Returns 409 if email already exists."
)
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, active status, and search by name or email. Results are ordered by creation date descending."
)
def list_users_route(
    limit: int = Query(20, ge=1, le=100),
    offset: int = Query(0, ge=0),
    role: Optional[str] = None,
    is_active: Optional[bool] = None,
    search: Optional[str] = None,
    db: Session = Depends(get_db)
):
    return handler.list_users(db, limit, offset, role, is_active, search)


@router.get(
    "/{user_id}",
    response_model=UserResponse,
    summary="Get User By ID",
    description="Retrieves a single user by ID. Returns 404 if user not found."
)
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 user information. All fields are optional. Validates email uniqueness if changed and password strength if provided. Returns 404 if user not found, 409 if email conflict."
)
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. Cascades to related customer, tour guide, or service provider profiles. Returns 404 if user not found."
)
def delete_user_route(user_id: str, db: Session = Depends(get_db)):
    return handler.delete_user(db, user_id)


# Customer routes
@router.post(
    "/customers",
    response_model=CustomerResponse,
    status_code=status.HTTP_201_CREATED,
    summary="Create Customer Profile",
    description="Creates an extended customer profile linked to a user account. Validates that the user exists and does not already have a customer profile. Returns 404 if user not found, 409 if profile already exists."
)
def create_customer_route(data: CustomerCreate, db: Session = Depends(get_db)):
    return handler.create_customer(db, data)


@router.get(
    "/customers",
    response_model=List[CustomerResponse],
    summary="List Customers",
    description="Returns a paginated list of customer profiles. Supports optional filters for loyalty status and country. Results are ordered by creation date descending."
)
def list_customers_route(
    limit: int = Query(20, ge=1, le=100),
    offset: int = Query(0, ge=0),
    loyalty_status: Optional[str] = None,
    country: Optional[str] = None,
    db: Session = Depends(get_db)
):
    return handler.list_customers(db, limit, offset, loyalty_status, country)


@router.get(
    "/customers/{customer_id}",
    response_model=CustomerResponse,
    summary="Get Customer By ID",
    description="Retrieves a single customer profile by ID. Returns 404 if customer not found."
)
def get_customer_route(customer_id: str, db: Session = Depends(get_db)):
    return handler.get_customer(db, customer_id)


@router.put(
    "/customers/{customer_id}",
    response_model=CustomerResponse,
    summary="Update Customer Profile",
    description="Updates customer profile information. All fields are optional. Returns 404 if customer not found."
)
def update_customer_route(customer_id: str, data: CustomerUpdate, db: Session = Depends(get_db)):
    return handler.update_customer(db, customer_id, data)


@router.delete(
    "/customers/{customer_id}",
    status_code=status.HTTP_200_OK,
    summary="Delete Customer Profile",
    description="Deletes a customer profile. Returns 404 if customer not found."
)
def delete_customer_route(customer_id: str, db: Session = Depends(get_db)):
    return handler.delete_customer(db, customer_id)


# Tour guide routes
@router.post(
    "/tour-guides",
    response_model=TourguideResponse,
    status_code=status.HTTP_201_CREATED,
    summary="Create Tour Guide Profile",
    description="Creates an extended tour guide profile linked to a user account. Validates that the user exists and does not already have a tour guide profile. Returns 404 if user not found, 409 if profile already exists."
)
def create_tourguide_route(data: TourguideCreate, db: Session = Depends(get_db)):
    return handler.create_tourguide(db, data)


@router.get(
    "/tour-guides",
    response_model=List[TourguideResponse],
    summary="List Tour Guides",
    description="Returns a paginated list of tour guide profiles. Supports optional filters for availability status and language spoken. Results are ordered by creation date descending."
)
def list_tourguides_route(
    limit: int = Query(20, ge=1, le=100),
    offset: int = Query(0, ge=0),
    is_available: Optional[bool] = None,
    language: Optional[str] = None,
    db: Session = Depends(get_db)
):
    return handler.list_tourguides(db, limit, offset, is_available, language)


@router.get(
    "/tour-guides/{tourguide_id}",
    response_model=TourguideResponse,
    summary="Get Tour Guide By ID",
    description="Retrieves a single tour guide profile by ID. Returns 404 if tour guide not found."
)
def get_tourguide_route(tourguide_id: str, db: Session = Depends(get_db)):
    return handler.get_tourguide(db, tourguide_id)


@router.put(
    "/tour-guides/{tourguide_id}",
    response_model=TourguideResponse,
    summary="Update Tour Guide Profile",
    description="Updates tour guide profile information. All fields are optional. Returns 404 if tour guide not found."
)
def update_tourguide_route(tourguide_id: str, data: TourguideUpdate, db: Session = Depends(get_db)):
    return handler.update_tourguide(db, tourguide_id, data)


@router.delete(
    "/tour-guides/{tourguide_id}",
    status_code=status.HTTP_200_OK,
    summary="Delete Tour Guide Profile",
    description="Deletes a tour guide profile. Returns 404 if tour guide not found."
)
def delete_tourguide_route(tourguide_id: str, db: Session = Depends(get_db)):
    return handler.delete_tourguide(db, tourguide_id)


# Service provider routes
@router.post(
    "/service-providers",
    response_model=ServiceproviderResponse,
    status_code=status.HTTP_201_CREATED,
    summary="Create Service Provider Profile",
    description="Creates an extended service provider profile linked to a user account. Validates that the user exists and does not already have a service provider profile. Returns 404 if user not found, 409 if profile already exists."
)
def create_serviceprovider_route(data: ServiceproviderCreate, db: Session = Depends(get_db)):
    return handler.create_serviceprovider(db, data)


@router.get(
    "/service-providers",
    response_model=List[ServiceproviderResponse],
    summary="List Service Providers",
    description="Returns a paginated list of service provider profiles. Supports optional filters for service type, verification status, and country. Results are ordered by creation date descending."
)
def list_serviceproviders_route(
    limit: int = Query(20, ge=1, le=100),
    offset: int = Query(0, ge=0),
    service_type: Optional[str] = None,
    is_verified: Optional[bool] = None,
    country: Optional[str] = None,
    db: Session = Depends(get_db)
):
    return handler.list_serviceproviders(db, limit, offset, service_type, is_verified, country)


@router.get(
    "/service-providers/{serviceprovider_id}",
    response_model=ServiceproviderResponse,
    summary="Get Service Provider By ID",
    description="Retrieves a single service provider profile by ID. Returns 404 if service provider not found."
)
def get_serviceprovider_route(serviceprovider_id: str, db: Session = Depends(get_db)):
    return handler.get_serviceprovider(db, serviceprovider_id)


@router.put(
    "/service-providers/{serviceprovider_id}",
    response_model=ServiceproviderResponse,
    summary="Update Service Provider Profile",
    description="Updates service provider profile information. All fields are optional. Returns 404 if service provider not found."
)
def update_serviceprovider_route(serviceprovider_id: str, data: ServiceproviderUpdate, db: Session = Depends(get_db)):
    return handler.update_serviceprovider(db, serviceprovider_id, data)


@router.delete(
    "/service-providers/{serviceprovider_id}",
    status_code=status.HTTP_200_OK,
    summary="Delete Service Provider Profile",
    description="Deletes a service provider profile. Returns 404 if service provider not found."
)
def delete_serviceprovider_route(serviceprovider_id: str, db: Session = Depends(get_db)):
    return handler.delete_serviceprovider(db, serviceprovider_id)