"""
feature_flag_service.py — Service layer untuk Feature Flags.
"""

import logging
import time
import threading
from typing import Optional

from fastapi import Depends, HTTPException
from sqlalchemy.orm import Session

from app.core.database import get_db
from app.models.feature_flag import FeatureFlag, DEFAULT_FLAGS

logger = logging.getLogger(__name__)

# ── In-memory cache ───────────────────────────────────────────────────────────
_CACHE_TTL_SECONDS = 60
_cache: dict[str, bool] = {}
_cache_ts: float = 0.0
_cache_lock = threading.Lock()


def _is_cache_valid() -> bool:
    return (time.monotonic() - _cache_ts) < _CACHE_TTL_SECONDS


def _refresh_cache(db: Session) -> None:
    global _cache, _cache_ts
    flags = db.query(FeatureFlag).all()
    with _cache_lock:
        _cache = {f.key: f.is_enabled for f in flags}
        _cache_ts = time.monotonic()
    logger.debug("[FeatureFlag] Cache diperbarui: %s", _cache)


def invalidate_cache() -> None:
    global _cache_ts
    with _cache_lock:
        _cache_ts = 0.0


# ── Public helpers ────────────────────────────────────────────────────────────

def is_enabled(db: Session, key: str) -> bool:
    if not _is_cache_valid():
        _refresh_cache(db)
    with _cache_lock:
        return _cache.get(key, True)


def get_flags_for_template(db: Session) -> dict[str, bool]:
    """
    Kembalikan semua flag sebagai dict {key: is_enabled}.
    Dipakai oleh middleware untuk inject ke request.state.feature_flags,
    lalu tersedia di semua template Jinja2 via {{ get_flags(request) }}.
    """
    if not _is_cache_valid():
        _refresh_cache(db)
    with _cache_lock:
        return dict(_cache)


def get_all_flags(db: Session) -> list[dict]:
    flags = db.query(FeatureFlag).order_by(FeatureFlag.id).all()
    return [f.to_dict() for f in flags]


def set_flag(db: Session, key: str, enabled: bool, admin_id: Optional[int] = None) -> dict:
    flag = db.query(FeatureFlag).filter(FeatureFlag.key == key).first()
    if not flag:
        raise ValueError(f"Feature flag '{key}' tidak ditemukan.")
    flag.is_enabled = enabled
    flag.updated_by = admin_id
    db.commit()
    db.refresh(flag)
    invalidate_cache()
    logger.info("[FeatureFlag] '%s' diset %s oleh admin ID %s.", key, enabled, admin_id)
    return flag.to_dict()


# ── FastAPI Dependency ────────────────────────────────────────────────────────

def require_feature(key: str, maintenance_msg: Optional[str] = None):
    _msg = maintenance_msg or (
        "Fitur ini sedang dalam maintenance. "
        "Silakan coba beberapa saat lagi atau hubungi admin."
    )

    def _check(db: Session = Depends(get_db)) -> None:
        if not is_enabled(db, key):
            raise HTTPException(status_code=503, detail=_msg)

    return _check


# ── Seed data default ─────────────────────────────────────────────────────────

def seed_default_flags(db: Session) -> None:
    inserted = 0
    for flag_def in DEFAULT_FLAGS:
        existing = db.query(FeatureFlag).filter(FeatureFlag.key == flag_def["key"]).first()
        if not existing:
            db.add(FeatureFlag(
                key         = flag_def["key"],
                label       = flag_def["label"],
                description = flag_def.get("description"),
                icon        = flag_def.get("icon", "⚙️"),
                is_enabled  = True,
            ))
            inserted += 1
    if inserted:
        db.commit()
        logger.info("[FeatureFlag] %d flag default di-seed.", inserted)
    invalidate_cache()