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

/**
 * AI プロバイダ / 画像プロバイダ / 画像設定タブのレンダリング
 *
 * 元 admin/class-aiap-admin-view.php から分離。
 * 共通基盤 (meta_label, resolve_dynamic_key) は親クラス AIAP_Admin_View にあるため直接参照する。
 */
class AIAP_Admin_View_Provider {

    // ================================================================
    // AIプロバイダ — サブタブ方式 (BotWriter style)
    // ================================================================
    public static function render_provider( $s ) {
        $sub = sanitize_key( wp_unslash( $_GET['sub'] ?? ( $s['provider'] ?? 'claude' ) ) );
        if ( ! isset( AIAP_Admin::$prov_icons[ $sub ] ) ) $sub = 'claude';
        // 各プロバイダのモデル一覧（キャッシュがあればそれを、なければハードコードのデフォルト）
        $models = array();
        $discontinued = array();
        foreach ( array_keys( AIAP_Admin::$prov_icons ) as $pkey ) {
            $list = AIAP_AI_Providers::get_models_for( $pkey );
            $models[ $pkey ] = $list;
            $mfield = $pkey . '_model';
            $cur = $s[ $mfield ] ?? '';
            if ( $cur !== '' && ! empty( $list ) && ! isset( $list[ $cur ] ) ) {
                $discontinued[ $pkey ] = $cur;
            }
        }
        $key_map   = AIAP_Admin::$text_provider_key_field;
        $model_map = AIAP_Admin::$text_provider_model_field;
        // よく使われる3プロバイダを上に、残りを下にコンパクト表示
        $popular = array( 'openai', 'claude', 'gemini' );
        $others  = array_values( array_diff( array_keys( AIAP_Admin::$prov_icons ), $popular ) );
        $active_provider = isset( $s['provider'] ) && isset( AIAP_Admin::$prov_icons[ $s['provider'] ] ) ? $s['provider'] : 'claude';
        ?>
        <form method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>" class="aiap-provider-form">
        <input type="hidden" name="action" value="aiap_save_provider">
        <input type="hidden" id="aiap-provider-tab" name="provider_tab" value="<?php echo esc_attr( $active_provider ); ?>">
        <input type="hidden" name="provider" id="aiap-active-provider-input" value="<?php echo esc_attr( $active_provider ); ?>">
        <?php wp_nonce_field( AIAP_Admin::NONCE ); ?>

        <header class="aiap-provider-hero">
            <span class="aiap-provider-hero-eyebrow"><?php echo esc_html( __( 'AI Provider', 'ai-auto-poster' ) ); ?></span>
            <h2 class="aiap-provider-hero-title"><?php echo esc_html( __( 'Which AI will write your articles?', 'ai-auto-poster' ) ); ?></h2>
            <p class="aiap-provider-hero-sub"><?php echo esc_html( __( 'Pick one, and it will be used for auto-posting. You can change it later.', 'ai-auto-poster' ) ); ?></p>
        </header>

        <div class="aiap-provider-section-label"><?php echo esc_html( __( 'Most common', 'ai-auto-poster' ) ); ?></div>
        <div class="aiap-provider-popular" id="aiap-providers-popular" role="radiogroup" aria-label="<?php echo esc_attr( __( 'Popular AI providers', 'ai-auto-poster' ) ); ?>">
            <?php
            $not_set_label   = __( 'Not set', 'ai-auto-poster' );
            $configured_label = __( 'Configured', 'ai-auto-poster' );
            foreach ( $popular as $pkey ) :
                $pi          = AIAP_Admin::$prov_icons[ $pkey ];
                $name        = AIAP_Admin_View::meta_label( $pi );
                $sub_text    = self::provider_subtitle( $pkey );
                $is_active   = ( $active_provider === $pkey );
                $is_configured = ! empty( $s[ $key_map[ $pkey ] ] );
                ?>
                <button type="button"
                    class="aiap-provider-tile<?php echo $is_active ? ' is-selected' : ''; ?>"
                    data-aiap-provider="<?php echo esc_attr( $pkey ); ?>"
                    data-aiap-name="<?php echo esc_attr( $name ); ?>"
                    data-aiap-sub="<?php echo esc_attr( $sub_text ); ?>"
                    data-aiap-icon-class="<?php echo esc_attr( $pi['ico'] ); ?>"
                    data-aiap-letter="<?php echo esc_attr( $pi['letter'] ); ?>"
                    role="radio"
                    aria-checked="<?php echo $is_active ? 'true' : 'false'; ?>">
                    <span class="aiap-provider-tile-icon ico ico-lg <?php echo esc_attr( $pi['ico'] ); ?>" aria-hidden="true"><?php echo esc_html( $pi['letter'] ); ?></span>
                    <span class="aiap-provider-tile-meta">
                        <span class="aiap-provider-tile-name"><?php echo esc_html( $name ); ?></span>
                        <?php if ( $sub_text !== '' ) : ?>
                            <span class="aiap-provider-tile-sub"><?php echo esc_html( $sub_text ); ?></span>
                        <?php endif; ?>
                    </span>
                    <span class="aiap-provider-tile-status<?php echo $is_configured ? ' is-configured' : ' is-empty'; ?>">
                        <?php echo esc_html( $is_configured ? $configured_label : $not_set_label ); ?>
                    </span>
                    <span class="aiap-provider-tile-check" aria-hidden="true">
                        <svg viewBox="0 0 24 24" width="13" height="13" focusable="false"><path d="M5 12l5 5L20 7" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/></svg>
                    </span>
                </button>
            <?php endforeach; ?>
        </div>

        <div class="aiap-provider-section-label"><?php echo esc_html( __( 'Other providers', 'ai-auto-poster' ) ); ?></div>
        <div class="aiap-provider-other" role="radiogroup" aria-label="<?php echo esc_attr( __( 'Other AI providers', 'ai-auto-poster' ) ); ?>">
            <?php foreach ( $others as $pkey ) :
                $pi          = AIAP_Admin::$prov_icons[ $pkey ];
                $name        = AIAP_Admin_View::meta_label( $pi );
                $sub_text    = self::provider_subtitle( $pkey );
                $is_active   = ( $active_provider === $pkey );
                $is_configured = ! empty( $s[ $key_map[ $pkey ] ] );
                ?>
                <button type="button"
                    class="aiap-provider-tile-compact<?php echo $is_active ? ' is-selected' : ''; ?>"
                    data-aiap-provider="<?php echo esc_attr( $pkey ); ?>"
                    data-aiap-name="<?php echo esc_attr( $name ); ?>"
                    data-aiap-sub="<?php echo esc_attr( $sub_text ); ?>"
                    data-aiap-icon-class="<?php echo esc_attr( $pi['ico'] ); ?>"
                    data-aiap-letter="<?php echo esc_attr( $pi['letter'] ); ?>"
                    role="radio"
                    aria-checked="<?php echo $is_active ? 'true' : 'false'; ?>">
                    <span class="aiap-provider-tile-icon ico <?php echo esc_attr( $pi['ico'] ); ?>" aria-hidden="true"><?php echo esc_html( $pi['letter'] ); ?></span>
                    <span class="aiap-provider-tile-name"><?php echo esc_html( $name ); ?></span>
                    <span class="aiap-provider-tile-status<?php echo $is_configured ? ' is-configured' : ' is-empty'; ?>" aria-label="<?php echo esc_attr( $is_configured ? $configured_label : $not_set_label ); ?>"></span>
                    <span class="aiap-provider-tile-check" aria-hidden="true">
                        <svg viewBox="0 0 24 24" width="11" height="11" focusable="false"><path d="M5 12l5 5L20 7" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/></svg>
                    </span>
                </button>
            <?php endforeach; ?>
        </div>

        <?php // 各プロバイダの設定パネル (active のみ表示)。フォーム項目はすべて DOM に存在するので保存ハンドラは無変更で動く。 ?>
        <?php foreach ( AIAP_Admin::$prov_icons as $card_key => $pi ) :
            $is_active = ( $active_provider === $card_key );
            $key_field = $key_map[ $card_key ];
            $has_key   = ! empty( $s[ $key_field ] );
            $masked    = $has_key ? str_repeat( '*', 20 ) : '';
            $name      = AIAP_Admin_View::meta_label( $pi );
            $sub_text  = self::provider_subtitle( $card_key );
            ?>
            <div class="aiap-provider-panel aiap-card aiap-provider-card aiap-text-provider-card" id="aiap-provider-card-<?php echo esc_attr( $card_key ); ?>" data-aiap-panel-for="<?php echo esc_attr( $card_key ); ?>" <?php echo $is_active ? '' : 'hidden'; ?>>
                <header class="aiap-provider-panel-header">
                    <span class="aiap-provider-panel-icon ico ico-lg <?php echo esc_attr( $pi['ico'] ); ?>" aria-hidden="true"><?php echo esc_html( $pi['letter'] ); ?></span>
                    <span class="aiap-provider-panel-text">
                        <span class="aiap-provider-panel-title"><?php echo esc_html( $name ); ?></span>
                        <?php if ( $sub_text !== '' ) : ?>
                            <span class="aiap-provider-panel-sub"><?php echo esc_html( $sub_text ); ?></span>
                        <?php endif; ?>
                    </span>
                    <span class="aiap-provider-panel-active"><?php echo esc_html( __( 'In use', 'ai-auto-poster' ) ); ?></span>
                </header>
                <div class="aiap-provider-panel-body">
                    <div class="aiap-field">
                        <label class="aiap-field-label" for="aiap-apikey-<?php echo esc_attr( $card_key ); ?>"><?php echo esc_html( __( 'API Key', 'ai-auto-poster' ) ); ?></label>
                        <div class="aiap-field-row">
                            <input type="password" id="aiap-apikey-<?php echo esc_attr( $card_key ); ?>" class="aiap-input-text" name="<?php echo esc_attr( $key_field ); ?>" value="<?php echo esc_attr( $masked ); ?>" autocomplete="new-password">
                            <button type="button" class="aiap-btn aiap-btn-primary aiap-btn-test" data-test-kind="text" data-provider="<?php echo esc_attr( $card_key ); ?>">
                                <span class="dashicons dashicons-search"></span> <?php echo esc_html( __( 'Test', 'ai-auto-poster' ) ); ?>
                            </button>
                        </div>
                        <div class="aiap-field-actions">
                            <a href="<?php echo esc_url( AIAP_Admin::$prov_urls[ $card_key ] ); ?>" target="_blank" rel="noopener" class="aiap-field-link">
                                <?php echo esc_html( __( 'Get an API key', 'ai-auto-poster' ) ); ?>
                                <svg viewBox="0 0 24 24" width="11" height="11" fill="none" aria-hidden="true"><path d="M7 17L17 7M17 7H9M17 7v8" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>
                            </a>
                        </div>
                    </div>

                    <div class="aiap-field">
                        <label class="aiap-field-label" for="aiap-model-<?php echo esc_attr( $card_key ); ?>"><?php echo esc_html( __( 'Model', 'ai-auto-poster' ) ); ?></label>
                        <div class="aiap-field-row">
                            <select id="aiap-model-<?php echo esc_attr( $card_key ); ?>" name="<?php echo esc_attr( $model_map[ $card_key ] ); ?>" class="aiap-select aiap-model-select" data-provider="<?php echo esc_attr( $card_key ); ?>">
                                <?php
                                $model_options = $models[ $card_key ] ?? array();
                                $custom_label  = __( '(custom)', 'ai-auto-poster' );
                                if ( ! empty( $s[ $model_map[ $card_key ] ] ) && ! isset( $model_options[ $s[ $model_map[ $card_key ] ] ] ) ) {
                                    $model_options = array( $s[ $model_map[ $card_key ] ] => $s[ $model_map[ $card_key ] ] . ' ' . $custom_label ) + $model_options;
                                }
                                foreach ( $model_options as $v => $l ) : ?>
                                    <option value="<?php echo esc_attr( $v ); ?>" <?php selected( $s[ $model_map[ $card_key ] ], $v ); ?>><?php echo esc_html( $l ); ?></option>
                                <?php endforeach; ?>
                            </select>
                            <button type="button" class="aiap-btn aiap-btn-icon aiap-btn-refresh-models" data-provider="<?php echo esc_attr( $card_key ); ?>" title="<?php echo esc_attr( __( 'Refresh model list', 'ai-auto-poster' ) ); ?>" aria-label="<?php echo esc_attr( __( 'Refresh model list', 'ai-auto-poster' ) ); ?>">
                                <span class="dashicons dashicons-update" aria-hidden="true"></span>
                            </button>
                        </div>
                        <?php if ( isset( $discontinued[ $card_key ] ) ) : ?>
                            <p class="aiap-model-notice"><span class="dashicons dashicons-warning" aria-hidden="true"></span> <?php
                                /* translators: %s = model identifier (e.g. "gpt-4-turbo") that has been discontinued */
                                echo esc_html( sprintf( __( 'Selected model "%s" is no longer available. It will be switched on save.', 'ai-auto-poster' ), $discontinued[ $card_key ] ) );
                            ?></p>
                        <?php endif; ?>
                        <p class="aiap-model-feedback" data-provider="<?php echo esc_attr( $card_key ); ?>" hidden></p>
                    </div>

                    <div class="aiap-field">
                        <label class="aiap-field-label" for="aiap-custom-model-<?php echo esc_attr( $card_key ); ?>">
                            <?php echo esc_html( __( 'Custom model', 'ai-auto-poster' ) ); ?>
                            <span class="aiap-field-label-hint"><?php echo esc_html( __( 'optional', 'ai-auto-poster' ) ); ?></span>
                        </label>
                        <input type="text" id="aiap-custom-model-<?php echo esc_attr( $card_key ); ?>" class="aiap-input-text" name="<?php echo esc_attr( $card_key ); ?>_custom_model" data-aiap-custom-model placeholder="<?php echo esc_attr( __( 'Enter a model ID not in the list', 'ai-auto-poster' ) ); ?>">
                    </div>
                </div>
            </div>
        <?php endforeach; ?>

        <p class="submit aiap-provider-submit"><button type="submit" class="button button-primary aiap-btn-primary"><span class="dashicons dashicons-saved"></span> <?php echo esc_html( __( 'Save', 'ai-auto-poster' ) ); ?></button></p>
        </form>
        <?php
    }

    /**
     * プロバイダのサブタイトル (タイル/パネルに表示)。
     */
    private static function provider_subtitle( $key ) {
        switch ( $key ) {
            case 'openai':     return __( 'ChatGPT API', 'ai-auto-poster' );
            case 'claude':     return __( 'Anthropic', 'ai-auto-poster' );
            case 'gemini':     return __( 'Google AI Studio', 'ai-auto-poster' );
            case 'mistral':    return __( 'Mistral AI', 'ai-auto-poster' );
            case 'groq':       return __( 'Groq Cloud', 'ai-auto-poster' );
            case 'deepseek':   return __( 'DeepSeek', 'ai-auto-poster' );
            case 'openrouter': return __( 'OpenRouter', 'ai-auto-poster' );
        }
        return '';
    }

    // ================================================================
    // 画像AIプロバイダ — サブタブ方式 (BotWriter style)
    // ================================================================
    public static function render_image_provider( $s, $im ) {
        $sub = sanitize_key( wp_unslash( $_GET['sub'] ?? ( $im['image_source'] ?? 'dalle3' ) ) );
        if ( ! isset( AIAP_Admin::$img_icons[ $sub ] ) ) $sub = 'dalle3';
        $img_keys = array(
            'dalle3'    => array( 'key'=>'image_openai_api_key', 'model'=>null, 'url'=>'https://platform.openai.com/api-keys' ),
            'imagen'    => array( 'key'=>'image_gemini_api_key', 'model'=>null, 'url'=>'https://aistudio.google.com/app/apikey' ),
            'stability' => array( 'key'=>'stability_api_key', 'model'=>'stability_model', 'url'=>'https://platform.stability.ai/', 'models'=>AIAP_Model_Registry::image_model_ids( 'stability' ) ),
            'flux'      => array( 'key'=>'flux_api_key',      'model'=>'flux_model',      'url'=>'https://fal.ai/dashboard/keys', 'models'=>AIAP_Model_Registry::image_model_ids( 'flux' ) ),
            'unsplash'  => array( 'key'=>'unsplash_access_key','model'=>null, 'url'=>'https://unsplash.com/developers' ),
            'pixabay'   => array( 'key'=>'pixabay_api_key',    'model'=>null, 'url'=>'https://pixabay.com/api/docs/' ),
            'pexels'    => array( 'key'=>'pexels_api_key',     'model'=>null, 'url'=>'https://www.pexels.com/api/' ),
        );
        $notes = array( 'openverse'=>'openverse_desc' );

        $dynamic_providers = array( 'dalle3', 'imagen' );
        $img_models = array();
        $img_discontinued = array();
        foreach ( $dynamic_providers as $pkey ) {
            $list = AIAP_AI_Providers::get_models_for( $pkey );
            $img_models[ $pkey ] = $list;
            $mfield = $pkey . '_model';
            $cur = $im[ $mfield ] ?? '';
            if ( $cur !== '' && ! empty( $list ) && ! isset( $list[ $cur ] ) ) {
                $img_discontinued[ $pkey ] = $cur;
            }
        }

        // よく使われる4 (AI生成2 + 写真素材2)、その他
        $popular = array( 'dalle3', 'imagen', 'unsplash', 'pexels' );
        $others  = array_values( array_diff( array_keys( AIAP_Admin::$img_icons ), $popular ) );
        $active = isset( $im['image_source'] ) && isset( AIAP_Admin::$img_icons[ $im['image_source'] ] ) ? $im['image_source'] : 'dalle3';
        $not_set_label    = __( 'Not set', 'ai-auto-poster' );
        $configured_label = __( 'Configured', 'ai-auto-poster' );
        ?>
        <form method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>" class="aiap-provider-form">
        <input type="hidden" name="action" value="aiap_save_image_provider">
        <input type="hidden" id="aiap-image-tab" name="image_tab" value="<?php echo esc_attr( $active ); ?>">
        <input type="hidden" name="image_source" id="aiap-active-image-source-input" value="<?php echo esc_attr( $active ); ?>">
        <?php wp_nonce_field( AIAP_Admin::NONCE ); ?>

        <header class="aiap-provider-hero">
            <span class="aiap-provider-hero-eyebrow"><?php echo esc_html( __( 'Featured Image', 'ai-auto-poster' ) ); ?></span>
            <h2 class="aiap-provider-hero-title"><?php echo esc_html( __( 'Where do your images come from?', 'ai-auto-poster' ) ); ?></h2>
            <p class="aiap-provider-hero-sub"><?php echo esc_html( __( 'Choose an AI image generator or a stock photo source. You can change it anytime.', 'ai-auto-poster' ) ); ?></p>
        </header>

        <div class="aiap-provider-section-label"><?php echo esc_html( __( 'Most common', 'ai-auto-poster' ) ); ?></div>
        <div class="aiap-provider-popular" id="aiap-image-providers-popular" role="radiogroup" aria-label="<?php echo esc_attr( __( 'Popular image sources', 'ai-auto-poster' ) ); ?>">
            <?php foreach ( $popular as $pkey ) :
                if ( ! isset( AIAP_Admin::$img_icons[ $pkey ] ) ) continue;
                $ii = AIAP_Admin::$img_icons[ $pkey ];
                $name = AIAP_Admin_View::meta_label( $ii );
                $sub_text = self::image_provider_subtitle( $pkey );
                $is_active = ( $active === $pkey );
                $is_configured = isset( $img_keys[ $pkey ] ) && ! empty( $im[ $img_keys[ $pkey ]['key'] ] );
                ?>
                <button type="button"
                    class="aiap-provider-tile<?php echo $is_active ? ' is-selected' : ''; ?>"
                    data-aiap-image-source="<?php echo esc_attr( $pkey ); ?>"
                    role="radio"
                    aria-checked="<?php echo $is_active ? 'true' : 'false'; ?>">
                    <span class="aiap-provider-tile-icon ico ico-lg <?php echo esc_attr( $ii['ico'] ); ?>" aria-hidden="true"><?php echo esc_html( $ii['letter'] ); ?></span>
                    <span class="aiap-provider-tile-meta">
                        <span class="aiap-provider-tile-name"><?php echo esc_html( $name ); ?></span>
                        <?php if ( $sub_text !== '' ) : ?>
                            <span class="aiap-provider-tile-sub"><?php echo esc_html( $sub_text ); ?></span>
                        <?php endif; ?>
                    </span>
                    <span class="aiap-provider-tile-status<?php echo $is_configured ? ' is-configured' : ' is-empty'; ?>">
                        <?php echo esc_html( $is_configured ? $configured_label : $not_set_label ); ?>
                    </span>
                    <span class="aiap-provider-tile-check" aria-hidden="true">
                        <svg viewBox="0 0 24 24" width="13" height="13" focusable="false"><path d="M5 12l5 5L20 7" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/></svg>
                    </span>
                </button>
            <?php endforeach; ?>
        </div>

        <div class="aiap-provider-section-label"><?php echo esc_html( __( 'Other sources', 'ai-auto-poster' ) ); ?></div>
        <div class="aiap-provider-other" role="radiogroup" aria-label="<?php echo esc_attr( __( 'Other image sources', 'ai-auto-poster' ) ); ?>">
            <?php foreach ( $others as $pkey ) :
                $ii = AIAP_Admin::$img_icons[ $pkey ];
                $name = AIAP_Admin_View::meta_label( $ii );
                $is_active = ( $active === $pkey );
                $is_configured = isset( $img_keys[ $pkey ] ) && ! empty( $im[ $img_keys[ $pkey ]['key'] ] );
                ?>
                <button type="button"
                    class="aiap-provider-tile-compact<?php echo $is_active ? ' is-selected' : ''; ?>"
                    data-aiap-image-source="<?php echo esc_attr( $pkey ); ?>"
                    role="radio"
                    aria-checked="<?php echo $is_active ? 'true' : 'false'; ?>">
                    <span class="aiap-provider-tile-icon ico <?php echo esc_attr( $ii['ico'] ); ?>" aria-hidden="true"><?php echo esc_html( $ii['letter'] ); ?></span>
                    <span class="aiap-provider-tile-name"><?php echo esc_html( $name ); ?></span>
                    <span class="aiap-provider-tile-status<?php echo $is_configured ? ' is-configured' : ' is-empty'; ?>" aria-label="<?php echo esc_attr( $is_configured ? $configured_label : $not_set_label ); ?>"></span>
                    <span class="aiap-provider-tile-check" aria-hidden="true">
                        <svg viewBox="0 0 24 24" width="11" height="11" focusable="false"><path d="M5 12l5 5L20 7" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/></svg>
                    </span>
                </button>
            <?php endforeach; ?>
        </div>

        <?php foreach ( AIAP_Admin::$img_icons as $card_key => $ii ) :
            $is_active = ( $active === $card_key );
            $name = AIAP_Admin_View::meta_label( $ii );
            $sub_text = self::image_provider_subtitle( $card_key );
            $ik = $img_keys[ $card_key ] ?? null;
            $img_has_key = $ik && ! empty( $im[ $ik['key'] ] );
            $img_masked = $img_has_key ? str_repeat( '*', 20 ) : '';

            // スタイル選択
            $style_key = $card_key . '_style';
            $saved_style = $im[ $style_key ] ?? '';
            $current_model = '';
            if ( in_array( $card_key, $dynamic_providers, true ) ) {
                $current_model = $im[ $card_key . '_model' ] ?? '';
            }
            $style_opts = AIAP_Image_Styles::get_provider_styles( $card_key, $current_model );
            $style_has_opts = ! empty( $style_opts );
            $style_unsupported = ( $saved_style !== '' && $style_has_opts && ! isset( $style_opts[ $saved_style ] ) ) ? $saved_style : '';
            $cur_style = ( $style_has_opts && isset( $style_opts[ $saved_style ] ) ) ? $saved_style : ( $style_has_opts ? array_key_first( $style_opts ) : '' );
            ?>
            <div class="aiap-provider-panel aiap-card aiap-provider-card aiap-image-provider-card" id="aiap-image-card-<?php echo esc_attr( $card_key ); ?>" data-aiap-image-panel-for="<?php echo esc_attr( $card_key ); ?>" <?php echo $is_active ? '' : 'hidden'; ?>>
                <header class="aiap-provider-panel-header">
                    <span class="aiap-provider-panel-icon ico ico-lg <?php echo esc_attr( $ii['ico'] ); ?>" aria-hidden="true"><?php echo esc_html( $ii['letter'] ); ?></span>
                    <span class="aiap-provider-panel-text">
                        <span class="aiap-provider-panel-title"><?php echo esc_html( $name ); ?></span>
                        <?php if ( $sub_text !== '' ) : ?>
                            <span class="aiap-provider-panel-sub"><?php echo esc_html( $sub_text ); ?></span>
                        <?php endif; ?>
                    </span>
                    <span class="aiap-provider-panel-active"><?php echo esc_html( __( 'In use', 'ai-auto-poster' ) ); ?></span>
                </header>
                <div class="aiap-provider-panel-body">
                    <?php if ( isset( $notes[ $card_key ] ) ) : ?>
                        <p class="aiap-field-note"><?php echo esc_html( AIAP_Admin_View::resolve_dynamic_key( $notes[ $card_key ] ) ); ?></p>
                    <?php endif; ?>

                    <?php if ( $ik ) : ?>
                        <div class="aiap-field">
                            <label class="aiap-field-label" for="aiap-img-apikey-<?php echo esc_attr( $card_key ); ?>"><?php echo esc_html( __( 'API Key', 'ai-auto-poster' ) ); ?></label>
                            <div class="aiap-field-row">
                                <input type="password" id="aiap-img-apikey-<?php echo esc_attr( $card_key ); ?>" class="aiap-input-text" name="<?php echo esc_attr( $ik['key'] ); ?>" value="<?php echo esc_attr( $img_masked ); ?>" autocomplete="new-password">
                                <button type="button" class="aiap-btn aiap-btn-primary aiap-btn-test" data-test-kind="image" data-provider="<?php echo esc_attr( $card_key ); ?>">
                                    <span class="dashicons dashicons-search"></span> <?php echo esc_html( __( 'Test', 'ai-auto-poster' ) ); ?>
                                </button>
                            </div>
                            <div class="aiap-field-actions">
                                <a href="<?php echo esc_url( $ik['url'] ); ?>" target="_blank" rel="noopener" class="aiap-field-link">
                                    <?php echo esc_html( __( 'Get an API key', 'ai-auto-poster' ) ); ?>
                                    <svg viewBox="0 0 24 24" width="11" height="11" fill="none" aria-hidden="true"><path d="M7 17L17 7M17 7H9M17 7v8" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>
                                </a>
                            </div>
                        </div>
                        <?php if ( ! empty( $ik['models'] ) && ! empty( $ik['model'] ) ) : ?>
                            <div class="aiap-field">
                                <label class="aiap-field-label" for="aiap-img-model-<?php echo esc_attr( $card_key ); ?>"><?php echo esc_html( __( 'Model', 'ai-auto-poster' ) ); ?></label>
                                <select id="aiap-img-model-<?php echo esc_attr( $card_key ); ?>" name="<?php echo esc_attr( $ik['model'] ); ?>" class="aiap-select">
                                    <?php foreach ( $ik['models'] as $m ) : ?>
                                        <option value="<?php echo esc_attr( $m ); ?>" <?php selected( $im[ $ik['model'] ] ?? '', $m ); ?>><?php echo esc_html( $m ); ?></option>
                                    <?php endforeach; ?>
                                </select>
                            </div>
                        <?php endif; ?>
                    <?php endif; ?>

                    <?php if ( in_array( $card_key, $dynamic_providers, true ) ) :
                        $mfield = $card_key . '_model';
                        $model_options = $img_models[ $card_key ] ?? array();
                        $cur_model = $im[ $mfield ] ?? '';
                        $custom_label = __( '(custom)', 'ai-auto-poster' );
                        if ( $cur_model !== '' && ! isset( $model_options[ $cur_model ] ) ) {
                            $model_options = array( $cur_model => $cur_model . ' ' . $custom_label ) + $model_options;
                        }
                        ?>
                        <div class="aiap-field">
                            <label class="aiap-field-label" for="aiap-img-dyn-model-<?php echo esc_attr( $card_key ); ?>"><?php echo esc_html( __( 'Model', 'ai-auto-poster' ) ); ?></label>
                            <div class="aiap-field-row">
                                <select id="aiap-img-dyn-model-<?php echo esc_attr( $card_key ); ?>" name="<?php echo esc_attr( $mfield ); ?>" class="aiap-select aiap-model-select" data-provider="<?php echo esc_attr( $card_key ); ?>">
                                    <?php foreach ( $model_options as $v => $l ) : ?>
                                        <option value="<?php echo esc_attr( $v ); ?>" <?php selected( $cur_model, $v ); ?>><?php echo esc_html( $l ); ?></option>
                                    <?php endforeach; ?>
                                </select>
                                <button type="button" class="aiap-btn aiap-btn-icon aiap-btn-refresh-models" data-provider="<?php echo esc_attr( $card_key ); ?>" title="<?php echo esc_attr( __( 'Refresh model list', 'ai-auto-poster' ) ); ?>" aria-label="<?php echo esc_attr( __( 'Refresh model list', 'ai-auto-poster' ) ); ?>">
                                    <span class="dashicons dashicons-update" aria-hidden="true"></span>
                                </button>
                            </div>
                            <?php if ( isset( $img_discontinued[ $card_key ] ) ) : ?>
                                <p class="aiap-model-notice"><span class="dashicons dashicons-warning" aria-hidden="true"></span> <?php
                                    /* translators: %s = image model identifier that has been discontinued */
                                    echo esc_html( sprintf( __( 'Selected model "%s" is no longer available. It will be switched on save.', 'ai-auto-poster' ), $img_discontinued[ $card_key ] ) );
                                ?></p>
                            <?php endif; ?>
                            <p class="aiap-model-feedback" data-provider="<?php echo esc_attr( $card_key ); ?>" hidden></p>
                        </div>
                    <?php endif; ?>

                    <div class="aiap-style-wrapper" data-style-wrapper data-provider="<?php echo esc_attr( $card_key ); ?>" <?php echo $style_has_opts ? '' : 'hidden'; ?>>
                        <div class="aiap-field">
                            <label class="aiap-field-label" for="aiap-img-style-<?php echo esc_attr( $card_key ); ?>"><?php echo esc_html( __( 'Style', 'ai-auto-poster' ) ); ?></label>
                            <select id="aiap-img-style-<?php echo esc_attr( $card_key ); ?>" name="<?php echo esc_attr( $style_key ); ?>" class="aiap-select aiap-style-select" data-provider="<?php echo esc_attr( $card_key ); ?>">
                                <?php if ( $style_has_opts ) : foreach ( $style_opts as $sk => $sv ) :
                                    $label = ! empty( $sv['label_key'] ) ? AIAP_Admin_View::resolve_dynamic_key( $sv['label_key'] ) : ( $sv['label_ja'] ?? $sk );
                                    ?>
                                    <option value="<?php echo esc_attr( $sk ); ?>" <?php selected( $cur_style, $sk ); ?>><?php echo esc_html( ( ! empty( $sv['icon'] ) ? $sv['icon'] . ' ' : '' ) . $label ); ?></option>
                                <?php endforeach; endif; ?>
                            </select>
                            <?php if ( $style_unsupported ) : ?>
                                <p class="aiap-model-notice" data-style-notice><span class="dashicons dashicons-warning" aria-hidden="true"></span>
                                    <?php
                                    /* translators: %s = style name not supported by the current model */
                                    echo esc_html( sprintf( __( 'Selected style "%s" is not supported by the current model. It will be reset to default on save.', 'ai-auto-poster' ), $style_unsupported ) );
                                    ?>
                                </p>
                            <?php else : ?>
                                <p class="aiap-model-notice" data-style-notice hidden><span class="dashicons dashicons-warning" aria-hidden="true"></span><span data-style-notice-text></span></p>
                            <?php endif; ?>
                            <span class="aiap-field-hint"><?php echo esc_html( __( 'Set the style for AI image generation.', 'ai-auto-poster' ) ); ?></span>
                        </div>
                    </div>
                </div>
            </div>
        <?php endforeach; ?>

        <p class="submit aiap-provider-submit"><button type="submit" class="button button-primary aiap-btn-primary"><span class="dashicons dashicons-saved"></span> <?php echo esc_html( __( 'Save', 'ai-auto-poster' ) ); ?></button></p>
        </form>
        <?php
    }

    /**
     * 画像プロバイダのサブタイトル
     */
    private static function image_provider_subtitle( $key ) {
        switch ( $key ) {
            case 'dalle3':    return __( 'OpenAI DALL-E', 'ai-auto-poster' );
            case 'imagen':    return __( 'Google Imagen', 'ai-auto-poster' );
            case 'stability': return __( 'Stable Diffusion', 'ai-auto-poster' );
            case 'flux':      return __( 'Black Forest Labs', 'ai-auto-poster' );
            case 'unsplash':  return __( 'Free stock photos', 'ai-auto-poster' );
            case 'pixabay':   return __( 'Free stock photos & videos', 'ai-auto-poster' );
            case 'pexels':    return __( 'Free stock photos', 'ai-auto-poster' );
            case 'openverse': return __( 'CC-licensed media', 'ai-auto-poster' );
        }
        return '';
    }

    // ================================================================
    // 画像設定 (BotWriter style — 2 column layout)
    // ================================================================
    public static function render_image_settings( $im ) {
        $cur_format  = $im['image_format']    ?? '16:9';
        $cur_quality = $im['image_quality']   ?? 'low';
        $cur_max     = (int) ( $im['image_max_width'] ?? 1200 );
        $cur_comp    = (int) ( $im['image_compress']  ?? 85 );

        $presets = self::get_image_presets();
        $current_preset = 'custom';
        foreach ( $presets as $key => $p ) {
            if ( $p['format'] === $cur_format
                && $p['quality'] === $cur_quality
                && $p['max_width'] === $cur_max
                && $p['compress'] === $cur_comp ) {
                $current_preset = $key;
                break;
            }
        }
        $current_label = ( 'custom' === $current_preset )
            ? __( 'Custom', 'ai-auto-poster' )
            : $presets[ $current_preset ]['title'];
        ?>
        <form method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>" class="aiap-imgset-form">
        <input type="hidden" name="action" value="aiap_save_image_settings">
        <?php wp_nonce_field( AIAP_Admin::NONCE ); ?>
        <input type="hidden" name="image_preset" id="aiap-image-preset" value="<?php echo esc_attr( $current_preset ); ?>">

        <div class="aiap-imgset">

            <header class="aiap-imgset-hero">
                <span class="aiap-imgset-eyebrow"><?php echo esc_html__( 'Image Settings', 'ai-auto-poster' ); ?></span>
                <h2 class="aiap-imgset-title"><?php echo esc_html__( 'What is this image for?', 'ai-auto-poster' ); ?></h2>
                <p class="aiap-imgset-lede"><?php echo esc_html__( 'Pick a use case and we will set the size, quality, and file weight for you.', 'ai-auto-poster' ); ?></p>
            </header>

            <div class="aiap-imgset-presets" role="radiogroup" aria-label="<?php echo esc_attr__( 'Image preset', 'ai-auto-poster' ); ?>">
                <?php foreach ( $presets as $key => $p ) : ?>
                    <button type="button"
                        class="aiap-imgset-card aiap-imgset-card--<?php echo esc_attr( $key ); ?> <?php echo $current_preset === $key ? 'is-selected' : ''; ?>"
                        data-aiap-preset="<?php echo esc_attr( $key ); ?>"
                        data-aiap-format="<?php echo esc_attr( $p['format'] ); ?>"
                        data-aiap-quality="<?php echo esc_attr( $p['quality'] ); ?>"
                        data-aiap-max-width="<?php echo esc_attr( $p['max_width'] ); ?>"
                        data-aiap-compress="<?php echo esc_attr( $p['compress'] ); ?>"
                        role="radio"
                        aria-checked="<?php echo $current_preset === $key ? 'true' : 'false'; ?>">
                        <span class="aiap-imgset-card__visual" aria-hidden="true">
                            <?php echo self::get_preset_icon_svg( $key ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- hardcoded SVG ?>
                        </span>
                        <span class="aiap-imgset-card__body">
                            <span class="aiap-imgset-card__title">
                                <span class="aiap-imgset-card__name"><?php echo esc_html( $p['title'] ); ?></span>
                                <span class="aiap-imgset-card__check" aria-hidden="true">
                                    <svg viewBox="0 0 24 24" width="14" height="14" fill="none"><path d="M5 12l5 5L20 7" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/></svg>
                                    <?php echo esc_html__( 'Selected', 'ai-auto-poster' ); ?>
                                </span>
                            </span>
                            <span class="aiap-imgset-card__sub"><?php echo esc_html( $p['description'] ); ?></span>
                            <span class="aiap-imgset-card__chips">
                                <?php foreach ( $p['chips'] as $chip ) : ?>
                                    <span class="aiap-imgset-card__chip"><?php echo esc_html( $chip ); ?></span>
                                <?php endforeach; ?>
                            </span>
                        </span>
                    </button>
                <?php endforeach; ?>
            </div>

            <div class="aiap-imgset-current">
                <span class="aiap-imgset-current__dot" aria-hidden="true"></span>
                <span class="aiap-imgset-current__text">
                    <strong id="aiap-current-preset-label" data-custom-label="<?php echo esc_attr__( 'Custom', 'ai-auto-poster' ); ?>"><?php echo esc_html( $current_label ); ?></strong>
                    <?php echo esc_html__( 'will be used to generate images', 'ai-auto-poster' ); ?>
                </span>
            </div>

            <div class="aiap-imgset-advanced <?php echo $current_preset === 'custom' ? 'is-open' : ''; ?>" id="aiap-imgset-advanced">
                <button type="button" class="aiap-imgset-advanced__toggle" id="aiap-imgset-advanced-toggle" aria-expanded="<?php echo $current_preset === 'custom' ? 'true' : 'false'; ?>" aria-controls="aiap-imgset-advanced-panel">
                    <span class="aiap-imgset-advanced__label">
                        <span class="aiap-imgset-advanced__label-main"><?php echo esc_html__( 'Advanced settings', 'ai-auto-poster' ); ?></span>
                        <span class="aiap-imgset-advanced__caption"><?php echo esc_html__( 'For users who want to set size and quality manually', 'ai-auto-poster' ); ?></span>
                    </span>
                    <svg class="aiap-imgset-advanced__chev" width="18" height="18" viewBox="0 0 24 24" fill="none" aria-hidden="true">
                        <path d="M6 9l6 6 6-6" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"/>
                    </svg>
                </button>

                <div class="aiap-imgset-advanced__panel" id="aiap-imgset-advanced-panel">
                    <div class="aiap-imgset-field">
                        <label for="aiap-image-format"><?php echo esc_html__( 'Image shape', 'ai-auto-poster' ); ?></label>
                        <select name="image_format" id="aiap-image-format" class="aiap-full-select">
                            <?php foreach ( AIAP_Admin::$image_format_keys as $k ) : ?>
                                <option value="<?php echo esc_attr( $k ); ?>" <?php selected( $cur_format, $k ); ?>>
                                    <?php echo esc_html( AIAP_Admin_View::resolve_dynamic_key( 'imgfmt_' . str_replace( ':', '_', $k ) ) ); ?>
                                </option>
                            <?php endforeach; ?>
                        </select>
                    </div>

                    <div class="aiap-imgset-field">
                        <label for="aiap-image-quality"><?php echo esc_html__( 'Image quality', 'ai-auto-poster' ); ?></label>
                        <select name="image_quality" id="aiap-image-quality" class="aiap-full-select">
                            <?php foreach ( AIAP_Admin::$image_quality_keys as $k ) : ?>
                                <option value="<?php echo esc_attr( $k ); ?>" <?php selected( $cur_quality, $k ); ?>>
                                    <?php echo esc_html( AIAP_Admin_View::resolve_dynamic_key( 'imgqual_' . $k ) ); ?>
                                </option>
                            <?php endforeach; ?>
                        </select>
                    </div>

                    <div class="aiap-imgset-field">
                        <label for="aiap-image-max-width"><?php echo esc_html__( 'Image size', 'ai-auto-poster' ); ?></label>
                        <div class="aiap-imgset-field__row">
                            <input type="number" name="image_max_width" id="aiap-image-max-width"
                                value="<?php echo esc_attr( $cur_max ); ?>" min="100" max="4096">
                            <span class="aiap-imgset-field__unit">px</span>
                        </div>
                        <span class="aiap-imgset-field__hint"><?php echo esc_html__( 'Recommended: Blog 1200px / SNS 1080px / Lite 800px', 'ai-auto-poster' ); ?></span>
                    </div>

                    <div class="aiap-imgset-field">
                        <label for="aiap-image-compress"><?php echo esc_html__( 'File weight (compression quality)', 'ai-auto-poster' ); ?></label>
                        <div class="aiap-imgset-field__row">
                            <input type="number" name="image_compress" id="aiap-image-compress"
                                value="<?php echo esc_attr( $cur_comp ); ?>" min="1" max="100">
                            <span class="aiap-imgset-field__unit">%</span>
                        </div>
                        <span class="aiap-imgset-field__hint"><?php echo esc_html__( 'Higher = better looking, lower = lighter file. Standard is 85%.', 'ai-auto-poster' ); ?></span>
                    </div>

                    <p class="aiap-imgset-field__note"><?php
                        /* Phase 12: 旧版は単に「in the SEO section」と書くだけで、ユーザーは
                           どのタブのどこにあるか分からなかった。基本設定タブの SEO アコーディオンへの
                           直接リンクに変更し、クリック 1 回で該当箇所まで飛べるようにする。
                           open=seo クエリパラメータと #aiap-seo-section ハッシュを併用し、
                           render_settings 側でアコーディオンを自動展開する。 */
                        $seo_url = add_query_arg(
                            array(
                                'page' => AIAP_Admin::MENU_SLUG,
                                'tab'  => 'settings',
                                'open' => 'seo',
                            ),
                            admin_url( 'admin.php' )
                        ) . '#aiap-seo-section';
                        printf(
                            /* translators: %s = HTML link to "WebP conversion and compression" setting in SEO section */
                            esc_html__( 'Size and compression apply only when %s is enabled.', 'ai-auto-poster' ),
                            '<a href="' . esc_url( $seo_url ) . '">' . esc_html__( '"WebP conversion and compression" in the SEO section', 'ai-auto-poster' ) . '</a>'
                        );
                    ?></p>
                </div>
            </div>

            <p class="submit aiap-imgset-submit">
                <button type="submit" class="button button-primary aiap-btn-primary">
                    <span class="dashicons dashicons-saved"></span>
                    <?php echo esc_html__( 'Save Image Settings', 'ai-auto-poster' ); ?>
                </button>
            </p>

        </div>
        </form>
        <?php
    }

    /**
     * 画像設定プリセット定義。
     */
    private static function get_image_presets() {
        return array(
            'blog' => array(
                'title'       => __( 'Blog post', 'ai-auto-poster' ),
                'description' => __( 'For headers and inline article images. Balanced quality.', 'ai-auto-poster' ),
                'chips'       => array(
                    __( 'Landscape', 'ai-auto-poster' ),
                    __( 'Balanced', 'ai-auto-poster' ),
                    __( 'Standard size', 'ai-auto-poster' ),
                ),
                'format'      => '16:9',
                'quality'     => 'medium',
                'max_width'   => 1200,
                'compress'    => 85,
            ),
            'sns' => array(
                'title'       => __( 'Social media', 'ai-auto-poster' ),
                'description' => __( 'Square format that shares well on Instagram and X.', 'ai-auto-poster' ),
                'chips'       => array(
                    __( 'Square', 'ai-auto-poster' ),
                    __( 'Balanced', 'ai-auto-poster' ),
                    __( 'Compatible', 'ai-auto-poster' ),
                ),
                'format'      => '1:1',
                'quality'     => 'medium',
                'max_width'   => 1080,
                'compress'    => 80,
            ),
            'lite' => array(
                'title'       => __( 'Lightweight', 'ai-auto-poster' ),
                'description' => __( 'Site loads faster. Quality is slightly lower.', 'ai-auto-poster' ),
                'chips'       => array(
                    __( 'Smaller', 'ai-auto-poster' ),
                    __( 'Speed first', 'ai-auto-poster' ),
                    __( 'Saves data', 'ai-auto-poster' ),
                ),
                'format'      => '16:9',
                'quality'     => 'low',
                'max_width'   => 800,
                'compress'    => 70,
            ),
        );
    }

    /**
     * 装飾用 SVG (ハードコード、ユーザー入力を含まない)
     */
    private static function get_preset_icon_svg( $preset ) {
        switch ( $preset ) {
            case 'blog':
                return '<svg viewBox="0 0 64 64" width="56" height="56" fill="none" focusable="false"><rect x="6" y="14" width="52" height="36" rx="3" fill="#fff" stroke="#c2410c" stroke-width="2"/><line x1="12" y1="24" x2="40" y2="24" stroke="#c2410c" stroke-width="2.5" stroke-linecap="round"/><line x1="12" y1="32" x2="52" y2="32" stroke="#c2410c" stroke-width="2" stroke-linecap="round" opacity=".5"/><line x1="12" y1="38" x2="48" y2="38" stroke="#c2410c" stroke-width="2" stroke-linecap="round" opacity=".5"/><line x1="12" y1="44" x2="44" y2="44" stroke="#c2410c" stroke-width="2" stroke-linecap="round" opacity=".5"/></svg>';
            case 'sns':
                return '<svg viewBox="0 0 64 64" width="56" height="56" fill="none" focusable="false"><rect x="14" y="14" width="36" height="36" rx="3" fill="#fff" stroke="#047857" stroke-width="2"/><circle cx="42" cy="22" r="2.5" fill="#047857"/><path d="M14 42 L24 32 L34 40 L42 34 L50 42" stroke="#047857" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round"/><path d="M14 50 L50 50" stroke="#047857" stroke-width="2" stroke-linecap="round"/></svg>';
            case 'lite':
                return '<svg viewBox="0 0 64 64" width="56" height="56" fill="none" focusable="false"><path d="M28 8 L18 36 L30 36 L24 56 L46 28 L34 28 L40 8 Z" fill="#fff" stroke="#3730a3" stroke-width="2" stroke-linejoin="round"/></svg>';
        }
        return '';
    }

    // ================================================================
    // プロンプト管理 (unchanged)
}
