from sqlalchemy.orm import Session
from typing import Optional, List
from fastapi import HTTPException, status
from . import repository
from .schema import ActivitylogCreate, ActivitylogUpdate, ActivitylogResponse, ActivitylogDetailResponse
from datetime import datetime


def _get_or_raise(db: Session, activitylog_id: str) -> repository.Activitylog:
    activitylog = repository.get_by_id(db, activitylog_id)
    if not activitylog:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Activity log with id {activitylog_id} not found",
        )
    return activitylog


def create_activitylog(db: Session, data: ActivitylogCreate) -> ActivitylogResponse:
    activitylog_data = data.model_dump()
    activitylog = repository.create(db, activitylog_data)
    db.commit()
    db.refresh(activitylog)
    return ActivitylogResponse.model_validate(activitylog)


def get_activitylog(db: Session, activitylog_id: str) -> ActivitylogResponse:
    activitylog = _get_or_raise(db, activitylog_id)
    return ActivitylogResponse.model_validate(activitylog)


def list_activitylogs(
    db: Session,
    limit: int = 20,
    offset: int = 0,
    entity_type: Optional[str] = None,
    entity_id: Optional[str] = None,
    user_id: Optional[str] = None,
    action_type: Optional[str] = None,
    start_date: Optional[datetime] = None,
    end_date: Optional[datetime] = None,
) -> List[ActivitylogResponse]:
    activitylogs = repository.list_all(
        db,
        limit=limit,
        offset=offset,
        entity_type=entity_type,
        entity_id=entity_id,
        user_id=user_id,
        action_type=action_type,
        start_date=start_date,
        end_date=end_date,
    )
    return [ActivitylogResponse.model_validate(log) for log in activitylogs]


def update_activitylog(db: Session, activitylog_id: str, data: ActivitylogUpdate) -> ActivitylogResponse:
    _get_or_raise(db, activitylog_id)
    update_data = data.model_dump(exclude_unset=True)
    if not update_data:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="No fields provided for update",
        )
    activitylog = repository.update(db, activitylog_id, update_data)
    db.commit()
    db.refresh(activitylog)
    return ActivitylogResponse.model_validate(activitylog)


def delete_activitylog(db: Session, activitylog_id: str) -> dict:
    _get_or_raise(db, activitylog_id)
    success = repository.delete(db, activitylog_id)
    if not success:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="Failed to delete activity log",
        )
    db.commit()
    return {"message": "Activity log deleted successfully"}


def get_activitylog_details(db: Session, activitylog_id: str) -> ActivitylogDetailResponse:
    activitylog = repository.get_with_details(db, activitylog_id)
    if not activitylog:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Activity log with id {activitylog_id} not found",
        )
    return ActivitylogDetailResponse.model_validate(activitylog)


def get_activitylogs_count(
    db: Session,
    entity_type: Optional[str] = None,
    entity_id: Optional[str] = None,
    user_id: Optional[str] = None,
    action_type: Optional[str] = None,
    start_date: Optional[datetime] = None,
    end_date: Optional[datetime] = None,
) -> dict:
    count = repository.count_all(
        db,
        entity_type=entity_type,
        entity_id=entity_id,
        user_id=user_id,
        action_type=action_type,
        start_date=start_date,
        end_date=end_date,
    )
    return {"count": count}