"""
plot_feature_importance:
Show top-N feature importances for tree-based or linear models.
"""
import matplotlib.pyplot as plt
import numpy as np
from typing import Sequence, Optional, Tuple

def _extract_importances(model) -> Tuple[np.ndarray, Sequence[str]]:
    if hasattr(model, "feature_importances_"):
        importances = np.array(model.feature_importances_)
    elif hasattr(model, "coef_"):
        coef = np.array(model.coef_)
        if coef.ndim == 2:
            importances = np.sum(np.abs(coef), axis=0)
        else:
            importances = np.abs(coef)
    else:
        raise ValueError("Model does not expose feature_importances_ or coef_")
    names = [f"f{i}" for i in range(len(importances))]
    return importances, names

def plot_feature_importance(model, feature_names: Optional[Sequence[str]] = None,
                            top_n: int = 10, title: Optional[str] = None,
                            show: bool = True, save_path: Optional[str] = None):
    importances, default_names = _extract_importances(model)
    names = list(feature_names) if feature_names is not None else default_names
    idx = np.argsort(importances)[::-1][:top_n]
    selected_names = [names[i] for i in idx][::-1]
    selected_vals = importances[idx][::-1]

    plt.figure(figsize=(8, max(4, 0.4 * len(selected_names))))
    plt.barh(selected_names, selected_vals)
    plt.xlabel("Importance (absolute)")
    plt.title(title or "Feature Importances")
    plt.tight_layout()
    if save_path:
        plt.savefig(save_path)
    if show:
        plt.show()
    plt.close()
