from sqlalchemy.orm import Session
from sqlalchemy.exc import IntegrityError
from fastapi import HTTPException, status
from typing import Optional
from datetime import datetime
from . import repository
from .schema import AnalyticseventCreate, AnalyticseventUpdate
from utils.utils import EventType


def create_analyticsevent(db: Session, data: AnalyticseventCreate):
    try:
        obj = repository.create(db, data.model_dump())
        db.commit()
        db.refresh(obj)
        return obj
    except IntegrityError as exc:
        db.rollback()
        msg = str(exc.orig).lower() if exc.orig else ""
        if "foreign key" in msg:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="Referenced calculation does not exist.",
            )
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="Data integrity error.",
        )
    except HTTPException:
        db.rollback()
        raise
    except Exception:
        db.rollback()
        raise


def get_analyticsevent(db: Session, entity_id: str):
    obj = repository.get_by_id(db, entity_id)
    if not obj:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Analytics event not found.",
        )
    return obj


def list_analyticsevents(
    db: Session,
    limit: int,
    offset: int,
    session_id: Optional[str] = None,
    event_type: Optional[EventType] = None,
    calculation_id: Optional[str] = None,
    start_date: Optional[datetime] = None,
    end_date: Optional[datetime] = None,
) -> dict:
    items = repository.list_all(
        db,
        limit=limit,
        offset=offset,
        session_id=session_id,
        event_type=event_type,
        calculation_id=calculation_id,
        start_date=start_date,
        end_date=end_date,
    )
    total = repository.count_all(
        db,
        session_id=session_id,
        event_type=event_type,
        calculation_id=calculation_id,
        start_date=start_date,
        end_date=end_date,
    )
    return {"items": items, "total": total, "limit": limit, "offset": offset}


def update_analyticsevent(db: Session, entity_id: str, data: AnalyticseventUpdate):
    update_data = data.model_dump(exclude_unset=True)
    if not update_data:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="No fields to update.",
        )
    try:
        obj = repository.update(db, entity_id, update_data)
        if not obj:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="Analytics event not found.",
            )
        db.commit()
        db.refresh(obj)
        return obj
    except IntegrityError as exc:
        db.rollback()
        msg = str(exc.orig).lower() if exc.orig else ""
        if "foreign key" in msg:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="Referenced calculation does not exist.",
            )
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="Data integrity error.",
        )
    except HTTPException:
        db.rollback()
        raise
    except Exception:
        db.rollback()
        raise


def delete_analyticsevent(db: Session, entity_id: str):
    try:
        success = repository.delete(db, entity_id)
        if not success:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="Analytics event not found.",
            )
        db.commit()
        return {"detail": "Analytics event deleted successfully."}
    except HTTPException:
        db.rollback()
        raise
    except Exception:
        db.rollback()
        raise