<?php
if ( ! defined( 'ABSPATH' ) ) exit;

/**
 * mbstring 拡張依存を吸収する互換ラッパー。
 *
 * 経緯:
 *   mbstring は WordPress 公式で「Highly Recommended」とされているが必須ではない。
 *   そのため拡張が無い環境では mb_* 関数呼出で Fatal Error が発生する。
 *
 *   過去はコード内に `function_exists( 'mb_strlen' ) ? mb_strlen( $s ) : strlen( $s )`
 *   のような inline guard が散在していて、ガードあり/なしが混在して一貫性に欠けていた。
 *
 *   このクラスで全 mb_* 呼出を統一する。
 *
 * 設計方針:
 *   - mbstring 拡張があれば mb_* をそのまま呼ぶ (元と同じ挙動)
 *   - 無ければ substr/strlen/strtolower/stripos にフォールバック
 *     (バイト単位処理になるため、マルチバイト文字の境界で文字化けする可能性はあるが、
 *      Fatal Error を避けて動作継続することを優先する設計)
 *   - エンコーディング引数は受け取るが fallback では使わない (mbstring 無し環境では指定不可)
 */
class AIAP_Compat {

    /**
     * mb_substr ラッパー
     *
     * @param string   $str
     * @param int      $start
     * @param int|null $length null なら末尾まで
     * @param string   $encoding
     * @return string
     */
    public static function mb_substr( $str, $start, $length = null, $encoding = 'UTF-8' ) {
        if ( function_exists( 'mb_substr' ) ) {
            return $length === null
                ? mb_substr( (string) $str, (int) $start, null, $encoding )
                : mb_substr( (string) $str, (int) $start, (int) $length, $encoding );
        }
        return $length === null
            ? substr( (string) $str, (int) $start )
            : substr( (string) $str, (int) $start, (int) $length );
    }

    /**
     * mb_strlen ラッパー
     */
    public static function mb_strlen( $str, $encoding = 'UTF-8' ) {
        return function_exists( 'mb_strlen' )
            ? mb_strlen( (string) $str, $encoding )
            : strlen( (string) $str );
    }

    /**
     * mb_strtolower ラッパー
     */
    public static function mb_strtolower( $str, $encoding = 'UTF-8' ) {
        return function_exists( 'mb_strtolower' )
            ? mb_strtolower( (string) $str, $encoding )
            : strtolower( (string) $str );
    }

    /**
     * mb_stripos ラッパー
     *
     * @return int|false
     */
    public static function mb_stripos( $haystack, $needle, $offset = 0, $encoding = 'UTF-8' ) {
        return function_exists( 'mb_stripos' )
            ? mb_stripos( (string) $haystack, (string) $needle, (int) $offset, $encoding )
            : stripos( (string) $haystack, (string) $needle, (int) $offset );
    }

    /**
     * mb_strimwidth ラッパー
     *
     * fallback の width は本来「表示幅」だが byte 長で近似する
     * (mbstring 無し環境では幅を厳密に算出できないため)
     */
    public static function mb_strimwidth( $str, $start, $width, $trimmarker = '', $encoding = 'UTF-8' ) {
        if ( function_exists( 'mb_strimwidth' ) ) {
            return mb_strimwidth( (string) $str, (int) $start, (int) $width, (string) $trimmarker, $encoding );
        }
        $s  = (string) $str;
        $tm = (string) $trimmarker;
        if ( strlen( $s ) <= (int) $width ) return $s;
        $cut = (int) $width - strlen( $tm );
        if ( $cut < 0 ) $cut = 0;
        return substr( $s, (int) $start, $cut ) . $tm;
    }
}
