"""Internal worklog service — CRUD with integrity hashing."""

# Import hashlib
import hashlib

# Import logging
import logging

# Import datetime from datetime
from datetime import datetime

# Import Optional from typing
from typing import Optional

# Import UUID from uuid
from uuid import UUID

# Import Session from sqlalchemy.orm
from sqlalchemy.orm import Session

# Import EntityNotFoundError from app.domain.errors
from app.domain.errors import EntityNotFoundError

# Import Worklog from app.models.worklog
from app.models.worklog import Worklog

# Assign logger = logging.getLogger(__name__)
logger = logging.getLogger(__name__)


# Define function create_worklog
def create_worklog(
    # Entry: db
    db: Session,
    *,
    # Entry: entity_type
    entity_type: str,
    # Entry: entity_id
    entity_id: UUID,
    # Entry: user_id
    user_id: UUID,
    # Entry: activity_type
    activity_type: str,
    # Entry: started_at
    started_at: datetime,
    # Entry: duration_seconds
    duration_seconds: int,
    # Entry: ended_at
    ended_at: Optional[datetime] = None,
    # Entry: description
    description: Optional[str] = None,
) -> Worklog:
    """Create a worklog with an auto-computed integrity hash."""
    # Assign wl = Worklog(
    wl = Worklog(
        # Keyword argument: entity_type
        entity_type=entity_type,
        # Keyword argument: entity_id
        entity_id=entity_id,
        # Keyword argument: user_id
        user_id=user_id,
        # Keyword argument: activity_type
        activity_type=activity_type,
        # Keyword argument: started_at
        started_at=started_at,
        # Keyword argument: ended_at
        ended_at=ended_at,
        # Keyword argument: duration_seconds
        duration_seconds=duration_seconds,
        # Keyword argument: description
        description=description,
    )
    # Assign wl.integrity_hash = _compute_hash(wl)
    wl.integrity_hash = _compute_hash(wl)
    # Stage new record(s) for database insertion
    db.add(wl)
    # Does not commit; caller (router) uses UnitOfWork.
    return wl


# Define function get_worklog_or_raise
def get_worklog_or_raise(db: Session, worklog_id: UUID) -> Worklog:
    """Get a worklog by ID or raise EntityNotFoundError."""
    # Assign wl = db.query(Worklog).filter(Worklog.id == worklog_id).first()
    wl = db.query(Worklog).filter(Worklog.id == worklog_id).first()
    # Check: not wl
    if not wl:
        # Raise EntityNotFoundError
        raise EntityNotFoundError("Worklog", str(worklog_id))
    # Return wl
    return wl


# Define function list_worklogs
def list_worklogs(
    # Entry: db
    db: Session,
    *,
    # Entry: entity_type
    entity_type: Optional[str] = None,
    # Entry: entity_id
    entity_id: Optional[UUID] = None,
    # Entry: user_id
    user_id: Optional[UUID] = None,
) -> list[Worklog]:
    """List worklogs with optional filters."""
    # Assign query = db.query(Worklog)
    query = db.query(Worklog)
    # Check: entity_type
    if entity_type:
        # Assign query = query.filter(Worklog.entity_type == entity_type)
        query = query.filter(Worklog.entity_type == entity_type)
    # Check: entity_id
    if entity_id:
        # Assign query = query.filter(Worklog.entity_id == entity_id)
        query = query.filter(Worklog.entity_id == entity_id)
    # Check: user_id
    if user_id:
        # Assign query = query.filter(Worklog.user_id == user_id)
        query = query.filter(Worklog.user_id == user_id)
    # Return query.order_by(Worklog.started_at.desc()).all()
    return query.order_by(Worklog.started_at.desc()).all()


# Define function verify_worklog_integrity
def verify_worklog_integrity(wl: Worklog) -> bool:
    """Return True if the worklog has not been tampered with."""
    # Return wl.integrity_hash == _compute_hash(wl)
    return wl.integrity_hash == _compute_hash(wl)


# Define function _compute_hash
def _compute_hash(wl: Worklog) -> str:
    """SHA-256 of the immutable fields for audit integrity."""
    # Assign data = (
    data = (
        f"{wl.entity_type}:{wl.entity_id}:{wl.user_id}:"
        f"{wl.activity_type}:{wl.started_at}:{wl.duration_seconds}"
    )
    # Return hashlib.sha256(data.encode()).hexdigest()
    return hashlib.sha256(data.encode()).hexdigest()
