# app/modules/monitoring/routes/api/admin_logs.py
"""
Log management endpoints for admin.

Provides endpoints for:
- Viewing database logs with filters
- Reading file logs
- Log statistics
- Log settings management
- Log cleanup operations
"""

import logging

from fastapi import APIRouter, Depends, Query
from sqlalchemy.orm import Session

from app.api.deps import get_current_admin_api
from app.core.database import get_db
from app.core.logging import reload_log_level
from app.exceptions import ResourceNotFoundException
from app.modules.core.services.admin_settings_service import admin_settings_service
from app.modules.monitoring.services.admin_audit_service import admin_audit_service
from app.modules.monitoring.services.log_service import log_service
from app.modules.tenancy.exceptions import ConfirmationRequiredException
from app.modules.tenancy.schemas.admin import (
    ApplicationLogFilters,
    ApplicationLogListResponse,
    FileLogResponse,
    LogCleanupResponse,
    LogDeleteResponse,
    LogFileListResponse,
    LogSettingsResponse,
    LogSettingsUpdate,
    LogSettingsUpdateResponse,
    LogStatistics,
)
from app.modules.tenancy.schemas.auth import UserContext

admin_logs_router = APIRouter(prefix="/logs")
logger = logging.getLogger(__name__)


# ============================================================================
# DATABASE LOGS ENDPOINTS
# ============================================================================


@admin_logs_router.get("/database", response_model=ApplicationLogListResponse)
def get_database_logs(
    level: str | None = Query(None, description="Filter by log level"),
    logger_name: str | None = Query(None, description="Filter by logger name"),
    module: str | None = Query(None, description="Filter by module"),
    user_id: int | None = Query(None, description="Filter by user ID"),
    store_id: int | None = Query(None, description="Filter by store ID"),
    search: str | None = Query(None, description="Search in message"),
    skip: int = Query(0, ge=0),
    limit: int = Query(100, ge=1, le=1000),
    db: Session = Depends(get_db),
    current_admin: UserContext = Depends(get_current_admin_api),
):
    """
    Get logs from database with filtering.

    Supports filtering by level, logger, module, user, store, and date range.
    Returns paginated results.
    """
    filters = ApplicationLogFilters(
        level=level,
        logger_name=logger_name,
        module=module,
        user_id=user_id,
        store_id=store_id,
        search=search,
        skip=skip,
        limit=limit,
    )

    return log_service.get_database_logs(db, filters)


@admin_logs_router.get("/statistics", response_model=LogStatistics)
def get_log_statistics(
    days: int = Query(7, ge=1, le=90, description="Number of days to analyze"),
    db: Session = Depends(get_db),
    current_admin: UserContext = Depends(get_current_admin_api),
):
    """
    Get log statistics for the last N days.

    Returns counts by level, module, and recent critical errors.
    """
    return log_service.get_log_statistics(db, days)


@admin_logs_router.delete("/database/cleanup", response_model=LogCleanupResponse)
def cleanup_old_logs(
    retention_days: int = Query(30, ge=1, le=365),
    confirm: bool = Query(False, description="Must be true to confirm cleanup"),
    db: Session = Depends(get_db),
    current_admin: UserContext = Depends(get_current_admin_api),
):
    """
    Delete logs older than retention period.

    Requires confirmation parameter.
    """
    if not confirm:
        raise ConfirmationRequiredException(operation="cleanup_logs")

    deleted_count = log_service.cleanup_old_logs(db, retention_days)

    # Log action
    admin_audit_service.log_action(
        db=db,
        admin_user_id=current_admin.id,
        action="cleanup_logs",
        target_type="application_logs",
        target_id="bulk",
        details={"retention_days": retention_days, "deleted_count": deleted_count},
    )

    return LogCleanupResponse(
        message=f"Deleted {deleted_count} log entries older than {retention_days} days",
        deleted_count=deleted_count,
    )


@admin_logs_router.delete("/database/{log_id}", response_model=LogDeleteResponse)
def delete_log(
    log_id: int,
    db: Session = Depends(get_db),
    current_admin: UserContext = Depends(get_current_admin_api),
):
    """Delete a specific log entry."""
    message = log_service.delete_log(db, log_id)

    # Log action
    admin_audit_service.log_action(
        db=db,
        admin_user_id=current_admin.id,
        action="delete_log",
        target_type="application_log",
        target_id=str(log_id),
        details={},
    )

    return LogDeleteResponse(message=message)


# ============================================================================
# FILE LOGS ENDPOINTS
# ============================================================================


@admin_logs_router.get("/files", response_model=LogFileListResponse)
def list_log_files(
    current_admin: UserContext = Depends(get_current_admin_api),
):
    """
    List all available log files.

    Returns list of log files with size and modification date.
    """
    return LogFileListResponse(files=log_service.list_log_files())


@admin_logs_router.get("/files/{filename}", response_model=FileLogResponse)
def get_file_log(
    filename: str,
    lines: int = Query(500, ge=1, le=10000, description="Number of lines to read"),
    current_admin: UserContext = Depends(get_current_admin_api),
):
    """
    Read log file content.

    Returns the last N lines from the specified log file.
    """
    return log_service.get_file_logs(filename, lines)


@admin_logs_router.get("/files/{filename}/download")
def download_log_file(
    filename: str,
    current_admin: UserContext = Depends(get_current_admin_api),
):
    """
    Download log file.

    Returns the entire log file for download.
    """
    from pathlib import Path

    from fastapi.responses import FileResponse

    from app.core.config import settings

    # Determine log file path
    log_file_path = settings.log_file
    if log_file_path:
        log_file = Path(log_file_path).parent / filename
    else:
        log_file = Path("logs") / filename

    if not log_file.exists():
        raise ResourceNotFoundException(resource_type="LogFile", identifier=filename)

    # Log action
    from app.core.database import get_db

    db_gen = get_db()
    db = next(db_gen)
    try:
        admin_audit_service.log_action(
            db=db,
            admin_user_id=current_admin.id,
            action="download_log_file",
            target_type="log_file",
            target_id=filename,
            details={"size_bytes": log_file.stat().st_size},
        )
    finally:
        db.close()

    return FileResponse(
        log_file,
        media_type="text/plain",
        filename=filename,
        headers={"Content-Disposition": f'attachment; filename="{filename}"'},
    )


# ============================================================================
# LOG SETTINGS ENDPOINTS
# ============================================================================


@admin_logs_router.get("/settings", response_model=LogSettingsResponse)
def get_log_settings(
    db: Session = Depends(get_db),
    current_admin: UserContext = Depends(get_current_admin_api),
):
    """Get current log configuration settings."""
    log_level = admin_settings_service.get_setting_value(db, "log_level", "INFO")
    max_size_mb = admin_settings_service.get_setting_value(
        db, "log_file_max_size_mb", 10
    )
    backup_count = admin_settings_service.get_setting_value(
        db, "log_file_backup_count", 5
    )
    retention_days = admin_settings_service.get_setting_value(
        db, "db_log_retention_days", 30
    )
    file_enabled = admin_settings_service.get_setting_value(
        db, "file_logging_enabled", "true"
    )
    db_enabled = admin_settings_service.get_setting_value(
        db, "db_logging_enabled", "true"
    )

    return LogSettingsResponse(
        log_level=str(log_level),
        log_file_max_size_mb=int(max_size_mb),
        log_file_backup_count=int(backup_count),
        db_log_retention_days=int(retention_days),
        file_logging_enabled=str(file_enabled).lower() == "true",
        db_logging_enabled=str(db_enabled).lower() == "true",
    )


@admin_logs_router.put("/settings", response_model=LogSettingsUpdateResponse)
def update_log_settings(
    settings_update: LogSettingsUpdate,
    db: Session = Depends(get_db),
    current_admin: UserContext = Depends(get_current_admin_api),
):
    """
    Update log configuration settings.

    Changes are applied immediately without restart (for log level).
    File rotation settings require restart.
    """
    from app.modules.tenancy.schemas.admin import AdminSettingUpdate

    updated = []

    # Update log level
    if settings_update.log_level:
        admin_settings_service.update_setting(
            db,
            "log_level",
            AdminSettingUpdate(value=settings_update.log_level),
            current_admin.id,
        )
        updated.append("log_level")

        # Reload log level immediately
        reload_log_level()

    # Update file rotation settings
    if settings_update.log_file_max_size_mb:
        admin_settings_service.update_setting(
            db,
            "log_file_max_size_mb",
            AdminSettingUpdate(value=str(settings_update.log_file_max_size_mb)),
            current_admin.id,
        )
        updated.append("log_file_max_size_mb")

    if settings_update.log_file_backup_count is not None:
        admin_settings_service.update_setting(
            db,
            "log_file_backup_count",
            AdminSettingUpdate(value=str(settings_update.log_file_backup_count)),
            current_admin.id,
        )
        updated.append("log_file_backup_count")

    # Update retention
    if settings_update.db_log_retention_days:
        admin_settings_service.update_setting(
            db,
            "db_log_retention_days",
            AdminSettingUpdate(value=str(settings_update.db_log_retention_days)),
            current_admin.id,
        )
        updated.append("db_log_retention_days")

    # Log action
    admin_audit_service.log_action(
        db=db,
        admin_user_id=current_admin.id,
        action="update_log_settings",
        target_type="settings",
        target_id="logging",
        details={"updated_fields": updated},
    )

    return LogSettingsUpdateResponse(
        message="Log settings updated successfully",
        updated_fields=updated,
        note="Log level changes are applied immediately. File rotation settings require restart.",
    )
