from __future__ import annotations
from pathlib import Path
import logging
import os
from logging.handlers import TimedRotatingFileHandler
from typing import Optional
from config import Config


_DEF_LEVEL = os.getenv("APP_LOG_LEVEL", "INFO").upper()
_DEF_FMT = "%(asctime)s [%(levelname)s] %(name)s: %(message)s"


def _ensure_log_dir() -> Path:
    p = Path(Config.LOG_FOLDER)
    p.mkdir(parents=True, exist_ok=True)
    return p


def setup_logging(app: Optional[object] = None) -> logging.Logger:
    """앱 전역 로깅을 파일(일단위 회전) + 콘솔로 설정.
    - 회전 파일명: YYYY-MM-DD.log
    - 중복 핸들러 방지
    - Windows/Linux 공통 동작
    """
    log_dir = _ensure_log_dir()
    log_path = log_dir / "app.log"

    root = logging.getLogger()
    root.setLevel(_DEF_LEVEL)
    root.propagate = False

    # 기존 핸들러 제거(중복 방지)
    for h in root.handlers[:]:
        root.removeHandler(h)

    # 파일 로거
    file_handler = TimedRotatingFileHandler(
        filename=str(log_path), when="midnight", interval=1, backupCount=90, encoding="utf-8", utc=False
    )

    # 회전 파일명: 2025-09-30.log 형태로
    def _namer(default_name: str) -> str:
        # default_name: app.log.YYYY-MM-DD
        base_dir = os.path.dirname(default_name)
        date_str = default_name.rsplit(".", 1)[-1]
        return os.path.join(base_dir, f"{date_str}.log")

    file_handler.namer = _namer
    file_handler.setFormatter(logging.Formatter(_DEF_FMT))

    # 콘솔 로거
    console = logging.StreamHandler()
    console.setFormatter(logging.Formatter("[%(levelname)s] %(message)s"))

    root.addHandler(file_handler)
    root.addHandler(console)

    if app is not None:
        # Flask 앱 로거에도 동일 핸들러 바인딩
        app.logger.handlers = root.handlers
        app.logger.setLevel(root.level)
        # 루트 로거로 전파되면 메시지가 두 번 출력되므로 방지
        app.logger.propagate = False

    # 제3자 라이브러리 로그 레벨 조정 (너무 시끄러운 경우)
    # werkzeug: 기본적인 HTTP 요청 로그(GET/POST 등)를 숨김 (WARNING 이상만 표시)
    logging.getLogger("werkzeug").setLevel(logging.WARNING)
    logging.getLogger("socketio").setLevel(logging.WARNING)
    logging.getLogger("engineio").setLevel(logging.WARNING)
    
    # httpx, telegram 라이브러리의 HTTP 요청 로그 숨기기
    logging.getLogger("httpx").setLevel(logging.WARNING)
    logging.getLogger("httpcore").setLevel(logging.WARNING)
    logging.getLogger("telegram").setLevel(logging.WARNING) 

    root.info("Logger initialized | level=%s | file=%s", _DEF_LEVEL, log_path)
    return root