from __future__ import annotations

import json
import logging
from logging.handlers import RotatingFileHandler
from pathlib import Path

from app.config import LOG_DIR
from app.db import execute, get_int, utcnow
from .errors import classify_exception, technical_details


def configure_file_logging() -> None:
    LOG_DIR.mkdir(parents=True, exist_ok=True)
    root = logging.getLogger('instagram_bot')
    if root.handlers:
        return
    handler = RotatingFileHandler(LOG_DIR / 'app.log', maxBytes=2_000_000, backupCount=5, encoding='utf-8')
    handler.setFormatter(logging.Formatter('%(asctime)s %(levelname)s %(name)s: %(message)s'))
    root.setLevel(logging.INFO)
    root.addHandler(handler)


def activity(category: str, action: str, message: str, details: dict | None = None, level: str = 'info') -> None:
    execute(
        'INSERT INTO activity_logs(level, category, action, message, details_json, created_at) VALUES (?, ?, ?, ?, ?, ?)',
        (level, category, action, message, json.dumps(details or {}, ensure_ascii=False), utcnow()),
    )
    logging.getLogger('instagram_bot').log(getattr(logging, level.upper(), logging.INFO), '%s/%s %s', category, action, message)


def error(exc: Exception, module: str, action: str, **context) -> str:
    error_type = context.pop('error_type', None) or classify_exception(exc)
    execute(
        '''INSERT INTO error_logs(error_type, module, action, message, technical_details,
           user_id, automation_id, comment_id, message_id, created_at)
           VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)''',
        (
            error_type,
            module,
            action,
            str(exc)[:1000],
            technical_details(exc)[:20000],
            context.get('user_id'),
            context.get('automation_id'),
            context.get('comment_id'),
            context.get('message_id'),
            utcnow(),
        ),
    )
    logging.getLogger('instagram_bot').exception('%s/%s: %s', module, action, exc)
    return error_type


def debug(run_id: int | None, stage: str, result: str, message: str = '') -> None:
    execute(
        'INSERT INTO debug_logs(run_id, stage, result, message, created_at) VALUES (?, ?, ?, ?, ?)',
        (run_id, stage, result, message[:4000], utcnow()),
    )


def cleanup_old_logs() -> None:
    days = max(1, get_int('log_retention_days', 30))
    for table in ('activity_logs', 'debug_logs', 'error_logs', 'system_logs'):
        execute(f"DELETE FROM {table} WHERE datetime(created_at) < datetime('now', ?)", (f'-{days} days',))
