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

/**
 * Class Podcastmaker_Smart_Tone
 * 
 * Handles default values and retrieval of Smart Tone configuration.
 */
class Podcastmaker_Smart_Tone
{
    const OPTION_NAME = 'Podcastmaker_smart_tone_config';
    const STYLES_OPTION_NAME = 'Podcastmaker_smart_tone_styles';
    const NEXT_ID_OPTION = 'Podcastmaker_smart_tone_next_id';

    /**
     * Get the current configuration (merge defaults with DB values).
     */
    public static function get_config()
    {
        $defaults = self::get_defaults();
        $saved = get_option(self::OPTION_NAME, array());

        if (!is_array($saved)) {
            $saved = array();
        }

        return array_merge($defaults, $saved);
    }

    /**
     * Get default configuration strings.
     */
    public static function get_defaults()
    {
        return array(
            'base_instruction' => "You are an AI assistant specializing in enhancing dialogue text for speech generation.\n\n" .
            "Your PRIMARY GOAL is to dynamically integrate audio tags into dialogue, making it more expressive while STRICTLY preserving the original text.\n" .
            "- DO NOT alter, add, or remove words from the original dialogue.\n" .
            "- The dialogue text MUST remain in its original language, but ALL audio tags MUST be in English inside square brackets [].\n" .
            "- Enhance emphasis without altering words by capitalization (ENGLISH ONLY), adding pauses (...), or punctuation.\n" .
            "- Use tags like [happy], [excited], [serious], [laughing], [chuckles], [whisper], [confident], [empathetic], [short pause], [long pause], [sarcastic], [appalled].\n" .
            "- Place tags immediately after the speaker label when the script is multi-speaker.\n" .
            "- Reply ONLY with the enhanced text.",
            'default_single_smart_tone_style_id' => 'podcast_neutral',
            'default_multi_smart_tone_style_id' => 'talk_show_contrast',
            'style_news' => 'Legacy compatibility placeholder. Use the registered Smart Tone style list instead.',
            'style_vibrant' => 'Legacy compatibility placeholder. Use the registered Smart Tone style list instead.',
            'style_dramatic' => 'Legacy compatibility placeholder. Use the registered Smart Tone style list instead.',
            'style_humorous' => 'Legacy compatibility placeholder. Use the registered Smart Tone style list instead.',
            'style_calm' => 'Legacy compatibility placeholder. Use the registered Smart Tone style list instead.',
            'style_business' => 'Legacy compatibility placeholder. Use the registered Smart Tone style list instead.',
        );
    }

    /**
     * Get default smart tone styles.
     *
     * @return array<int, array<string, string|bool>>
     */
    public static function get_default_styles()
    {
        return array(
            array(
                'id' => 'podcast_neutral',
                'index_id' => 1,
                'name' => 'Podcast Neutral',
                'speaker_type' => 'single',
                'description' => 'Balanced default style for solo podcast narration.',
                'directive' => 'Keep the delivery natural, balanced, and podcast-friendly. Use emotional tags only when they improve clarity or rhythm. Avoid exaggerated performance and maintain a steady, approachable tone.',
                'voice_direction_template' => "## Audio Profile\nA calm solo narrator who reads at a steady pace, neither too fast nor too slow. The voice should feel clear, trustworthy, and announcer-like, similar to a polished high-school textbook reading.\n\n## Scene\nA quiet recording studio where a general-audience explanation is delivered at a stable pace. The atmosphere is restrained, with no unnecessary theatrical effect.\n\n## Director's Notes\nKeep the delivery steady and make the end of each sentence clearly audible. Even though punctuation is not spoken, treat commas and periods as natural cues for careful phrasing and pacing. Do not overplay emotion or inflection. Read with the clean, composed clarity of a professional broadcaster, with crisp articulation and short, natural pauses. Prioritize clarity above all else.\n\n## Contextual Lead-in\nThe speaker is already reading a general-audience explanation in a calm, composed tone. The listener should be able to follow the key points at a stable, even pace.",
                'is_system' => true,
            ),
            array(
                'id' => 'business_calm',
                'index_id' => 2,
                'name' => 'Business Calm',
                'speaker_type' => 'single',
                'description' => 'Restrained and professional delivery for business topics.',
                'directive' => 'Use a restrained, professional, and confident tone. Keep the pacing measured and the emotional range narrow. Favor precision, calm emphasis, and credibility over expressiveness.',
                'voice_direction_template' => "## Audio Profile\nA calm, trustworthy solo narrator who reads business and practical content at a slightly brisker pace. The voice should feel composed, professional, and easy to follow. Technical and business terms should be articulated a little more strongly when they matter.\n\n## Scene\nA quiet business presentation setting where practical points are delivered in an organized sequence. The atmosphere is restrained, with a clear focus on concise, work-oriented explanation.\n\n## Director's Notes\nKeep the flow organized and make the structure of the explanation easy to follow. Maintain a slightly faster pace to give the reading a business-oriented feel. Make the end of each sentence clearly audible, and treat punctuation as a cue for natural phrasing and clean pauses. Emphasize technical and business terms a little when needed so the important vocabulary stands out. Avoid overacting and prioritize accuracy, clarity, and a polished professional rhythm.\n\n## Contextual Lead-in\nThe speaker is already delivering practical, business-oriented content in a calm explanatory tone. The listener should be able to follow the information in a clear, slightly brisk, and structured way.",
                'is_system' => true,
            ),
            array(
                'id' => 'warm_explainer',
                'index_id' => 3,
                'name' => 'Warm Explainer',
                'speaker_type' => 'single',
                'description' => 'Supportive and friendly explanatory tone.',
                'directive' => 'Create a warm, supportive, and easy-to-follow delivery. Make the tone friendly and human, while still keeping the explanation clear and organized. Use gentle emotional shifts where helpful.',
                'voice_direction_template' => "## Audio Profile\nA warm, friendly solo narrator who explains things in a reassuring and easy-to-follow way. The voice should feel calm, approachable, and supportive, like someone who wants the listener to understand comfortably.\n\n## Scene\nA quiet learning space where the speaker is guiding someone step by step through an unfamiliar topic. The atmosphere is gentle, patient, and welcoming.\n\n## Director's Notes\nKeep the delivery warm, gentle, and easy to follow. Make the listener feel included and supported throughout the explanation. Read with clear sentence endings and natural pauses, while treating punctuation as a cue for careful phrasing. Use a teacher-like tone, as if a kind school teacher is patiently explaining something to students. When difficult terms or technical words appear, read them a little more slowly so the listener can understand them comfortably. Make the explanation feel warm and caring, with a focus on kindness, clarity, and reassurance.\n\n## Contextual Lead-in\nThe speaker is already helping the listener understand a topic that may feel unfamiliar or slightly complex. The listener should feel guided step by step with calm reassurance.",
                'is_system' => true,
            ),
            array(
                'id' => 'news_brief',
                'index_id' => 4,
                'name' => 'News Brief',
                'speaker_type' => 'single',
                'description' => 'News-headline style delivery with a slightly brisk pace.',
                'directive' => 'Deliver the script with concise, headline-like energy and clear forward motion. Keep the rhythm brisk and informative, but do not let speed reduce intelligibility.',
                'voice_direction_template' => "## Audio Profile\nA clear, slightly brisk solo narrator who reads news-style updates with a sharp and informative delivery. The voice should feel crisp, direct, and easy to follow.\n\n## Scene\nA newsroom-like reading environment where important points are delivered quickly and in an organized sequence. The atmosphere is focused and restrained.\n\n## Director's Notes\nRead the script like a short news headline or broadcast update. Keep the pace a little faster than normal and make the end of each sentence clearly audible. Treat punctuation as a cue for short, clean pauses. Prioritize the most important facts first, and keep the tone crisp, restrained, and easy to understand. Do not overdo emotion; keep the delivery immediate and clear.\n\n## Contextual Lead-in\nThe speaker is already giving a short update and needs to get the key facts across quickly. The listener should be able to pick up the main points immediately.",
                'is_system' => true,
            ),
            array(
                'id' => 'friendly_guide',
                'index_id' => 5,
                'name' => 'Friendly Guide',
                'speaker_type' => 'single',
                'description' => 'Warm and approachable guide-style delivery.',
                'directive' => 'Create a friendly, approachable, and easy-to-follow delivery. Keep the tone close to the listener and gentle, while still maintaining clarity and a natural flow.',
                'voice_direction_template' => "## Audio Profile\nA friendly and approachable solo narrator who speaks in a warm, close, and reassuring way. The voice should feel relaxed, considerate, and easy to listen to.\n\n## Scene\nA calm guidance setting where the speaker is helping the listener move through a topic step by step. The atmosphere is soft, welcoming, and comfortable.\n\n## Director's Notes\nKeep the delivery friendly, gentle, and easy to follow. Make the listener feel close to the speaker and supported throughout the explanation. Read with clear sentence endings and natural pauses, while treating punctuation as a cue for careful phrasing. When difficult terms or technical words appear, read them a little more slowly so the listener can understand them comfortably. Keep the tone warm and approachable without becoming childish or overly casual.\n\n## Contextual Lead-in\nThe speaker is already guiding the listener through the topic in a warm, approachable way. The listener should feel at ease and able to follow along naturally.",
                'is_system' => true,
            ),
            array(
                'id' => 'energetic_promo',
                'index_id' => 6,
                'name' => 'Recommendation Boost',
                'speaker_type' => 'single',
                'description' => 'Lively and proactive recommendation delivery.',
                'directive' => 'Deliver the script with upbeat energy, forward momentum, and recommendation clarity. Keep the rhythm lively and engaged, but do not let excitement reduce intelligibility.',
                'voice_direction_template' => "## Audio Profile\nA clear, confident solo narrator who presents recommendations with a lively but controlled sense of momentum. The voice should feel positive, active, and easy to listen to.\n\n## Scene\nA recommendation-style presentation where the speaker is introducing something worth noticing and guiding the listener toward the highlights. The atmosphere is focused, upbeat, and inviting.\n\n## Director's Notes\nRead the script with a slightly more proactive and engaged feeling, as if you genuinely want the listener to pay attention to the recommendation. Keep the delivery clear and well paced, with sentence endings that are easy to hear. Treat punctuation as a cue for short, clean pauses. Emphasize the key benefits and highlights in a natural way, while avoiding pushiness. Keep the tone bright, persuasive, and balanced so it feels like a confident introduction rather than an advertisement.\n\n## Contextual Lead-in\nThe speaker is already introducing the article as something worth recommending. The listener should feel that the main highlights are being presented with positive energy and clear guidance.",
                'is_system' => true,
            ),
            array(
                'id' => 'narrative_serious',
                'index_id' => 7,
                'name' => 'Narrative Serious',
                'speaker_type' => 'single',
                'description' => 'Reflective tone for heavier narrative or commentary topics.',
                'directive' => 'Use a serious, reflective, and emotionally grounded tone. Keep the pacing deliberate and let important moments breathe. Avoid casual phrasing in delivery unless the script clearly calls for it.',
                'voice_direction_template' => "## Audio Profile\nA dramatic storyteller who carries the script with a strong emotional arc and a clear sense of narrative flow. The voice should feel serious, vivid, and memorable without becoming overly theatrical.\n\n## Scene\nA story is unfolding with an evident beginning, middle, and end. The listener should feel the progression of the narrative, along with the emotional weight of what is being told.\n\n## Director's Notes\nRead the script like a story being carried forward with rising tension and release. Keep the phrasing expressive and let the pacing help the listener follow the narrative arc. Allow the emotion to build more strongly than in a neutral explanation, but keep the performance controlled enough that the story remains clear. Make the delivery feel serious, cinematic, and emotionally grounded.\n\n## Contextual Lead-in\nThe speaker is already in the middle of a meaningful story, and the listener should feel the narrative moving forward with emotional weight and momentum.",
                'is_system' => true,
            ),
            array(
                'id' => 'scene_performance',
                'index_id' => 8,
                'name' => 'Scene Performance',
                'speaker_type' => 'single',
                'description' => 'Dramatic scene-like delivery with strong visual presence.',
                'directive' => 'Create a scene-like delivery that makes the content feel visible and emotionally present. Keep the tone dramatic and vivid, but do not lose clarity.',
                'voice_direction_template' => "## Audio Profile\nA scene-driven solo narrator who delivers the script with a strong sense of atmosphere and visual presence. The voice should feel composed but expressive, with enough color to make the scene feel vivid and memorable.\n\n## Scene\nA cinematic or drama-like moment where the atmosphere of the scene spreads out in front of the listener. The content should feel easy to picture, with a clear sense of place, motion, and emotional texture.\n\n## Director's Notes\nRead the script in a way that makes the scene feel visible and alive. Keep the phrasing expressive and make the pauses and rhythm help the listener picture the atmosphere. Use a slightly stronger dramatic touch, like observing a memorable film or TV scene, but do not let the delivery become overly theatrical. Preserve clarity and keep the presentation focused on making the scene feel distinct, atmospheric, and emotionally present.\n\n## Contextual Lead-in\nThe speaker is already building a vivid scene, and the listener should feel as if they are watching the atmosphere and details unfold in front of them.",
                'is_system' => true,
            ),
            array(
                'id' => 'solo_comedy_burst',
                'index_id' => 9,
                'name' => 'Solo Comedy Burst',
                'speaker_type' => 'single',
                'description' => 'Fast-paced solo entertainment style with sharp comedic momentum.',
                'directive' => 'Create a fast-paced, highly energetic solo comedic monologue. Keep the rhythm sharp, using dynamic shifts in tone, rapid-fire delivery, self-retorts, and clear comedic escalation to maintain a hilarious momentum.',
                'voice_direction_template' => "## Audio Profile\nA bright and energetic comedian who speaks in a strong Kansai dialect. Although the character feels friendly and approachable, the priority is to deliver the script content accurately. The vocal tone is slightly higher and full of energy, but the delivery should always focus on clearly conveying the content to the listener.\n\n## Scene\nAn upbeat announcement or a friendly explanatory scene designed to energize the listener. The performance should keep its lively momentum, while each word remains clearly understandable in a stable recording environment.\n\n## Director's Notes\nRead every word of the script accurately without omitting or changing any part of the text.\n\nUse a strong Kansai-dialect intonation and maintain a bright, positive energy throughout.\n\nKeep the tempo lively, but do not let it become so fast that the content becomes unclear.\n\nTake appropriate pauses according to punctuation, and make the boundaries of each sentence clear.\n\nFocus less on trying to get laughs and more on delivering the content solidly in a bright, lively atmosphere.\n\n## Contextual Lead-in\nThis is a bright, crisp narration in a strong Kansai dialect, intended to give energy to the listener.\nAvoid excessive exaggeration, and read the written text carefully while keeping the delivery lively and spirited.",
                'is_system' => true,
            ),
            array(
                'id' => 'talk_show_contrast',
                'index_id' => 10,
                'name' => 'Talk Show Contrast',
                'speaker_type' => 'multi',
                'description' => 'Clear role contrast between Host and Guest in a polished talk-show exchange.',
                'directive' => 'Create a lively two-speaker exchange with clear contrast between Host and Guest. The Host should guide, react, and invite. The Guest should explain, expand, and deliver the main substance.',
                'voice_direction_template' => "## Audio Profile\nHost:\nA calm and easy-to-follow presenter who guides the conversation smoothly. The Host introduces topics gently, organizes key points, and helps the listener follow the flow naturally.\n\nGuest:\nA natural and clear explanatory speaker who handles the main substance of the discussion. The Guest delivers key points in an organized order with a steady, approachable tone.\n\n## Scene\nA modern talk-show style studio conversation with natural rhythm and light interpersonal tension.\n\n## Director's Notes\nKeep the contrast between the two speakers clear. Let the Host sound more reactive and connective, while the Guest sounds more informative and composed. Preserve the flow of a polished conversation.\n\n## Contextual Lead-in\nThe two speakers are already in the middle of a thoughtful and engaging discussion.",
                'is_system' => true,
            ),
            array(
                'id' => 'business_interview',
                'index_id' => 11,
                'name' => 'Business Interview',
                'speaker_type' => 'multi',
                'description' => 'Structured and professional interview format.',
                'directive' => 'Shape the script like a professional interview. The Host should sound focused and concise, while the Guest should sound clear, credible, and well-structured. Keep the exchange polished and efficient.',
                'voice_direction_template' => "## Audio Profile\nHost:\nA calm, businesslike interviewer who listens carefully and guides the conversation with concise prompts. The Host keeps the discussion organized and helps the listener follow the structure clearly.\n\nGuest:\nA composed and credible expert speaker who explains the main content in a professional and well-structured way. The Guest should sound reliable, precise, and easy to follow.\n\n## Scene\nA formal business interview setting where practical insight and clear explanation matter more than casual chemistry. The atmosphere is restrained, professional, and organized.\n\n## Director's Notes\nKeep the Host in a listening and guiding role throughout the exchange. The Host should frame the topic, invite the explanation, and steer the flow without taking over the substance. Let the Guest handle the main explanation with clear structure and professional confidence. Keep sentence endings clear, treat punctuation as a cue for clean pauses, and maintain a polished business rhythm.\n\n## Contextual Lead-in\nThe Host has already introduced the topic, and the Guest is now explaining the practical substance in a calm, professional exchange. The listener should feel that the conversation is structured, efficient, and credible.",
                'is_system' => true,
            ),
            array(
                'id' => 'beginner_friendly_duo',
                'index_id' => 12,
                'name' => 'Beginner Friendly Duo',
                'speaker_type' => 'multi',
                'description' => 'Two-speaker beginner-friendly guidance with supportive pacing.',
                'directive' => 'Create a beginner-friendly two-speaker exchange. The Host should guide from the listener’s point of view, while the Guest explains carefully and clearly. Keep the tone supportive, patient, and easy to follow.',
                'voice_direction_template' => "## Audio Profile\nHost:\nA gentle and approachable guide who listens from the beginner's point of view and helps move the conversation forward step by step. The Host should sound supportive, patient, and easy to trust.\n\nGuest:\nA clear and friendly explainer who handles the main explanation in simple, accessible language. The Guest should sound calm, helpful, and careful not to leave the listener behind.\n\n## Scene\nA quiet educational conversation where the Host helps a beginner listener stay oriented while the Guest explains the topic clearly. The atmosphere is kind, patient, and easy to follow.\n\n## Director's Notes\nKeep the Host in a listening and guiding role throughout the exchange. The Host should ask or prompt in a way that helps the explanation unfold naturally from a beginner's perspective. Let the Guest carry the main substance with simple phrasing, clear structure, and patient pacing. Keep sentence endings distinct, use punctuation as a cue for gentle pauses, and make the whole exchange feel warm, supportive, and accessible.\n\n## Contextual Lead-in\nThe Host has already opened the topic in a beginner-friendly way, and the Guest is now explaining it step by step. The listener should feel guided, reassured, and able to follow without strain.",
                'is_system' => true,
            ),
            array(
                'id' => 'news_roundup',
                'index_id' => 13,
                'name' => 'News Roundup',
                'speaker_type' => 'multi',
                'description' => 'Fast, clear two-speaker news-style summary.',
                'directive' => 'Create a brisk two-speaker exchange that delivers key facts like a short news roundup. The Host should guide and cue the main points, while the Guest explains the substance clearly and concisely.',
                'voice_direction_template' => "## Audio Profile\nHost:\nA quick, clear presenter who keeps the conversation moving and helps surface the most important points first. The Host should sound alert, organized, and focused on guiding the listener through the update.\n\nGuest:\nA concise and informative speaker who handles the main explanation with clarity and speed. The Guest should sound factual, efficient, and easy to follow.\n\n## Scene\nA short news-style exchange where the speakers move through important facts quickly and in a tightly organized sequence. The atmosphere is focused, brisk, and restrained.\n\n## Director's Notes\nKeep the Host in a listening and guiding role throughout the exchange. The Host should introduce the angle, react briefly, and steer the flow so the listener can catch the key points quickly. Let the Guest carry the main facts in a concise, headline-aware style. Keep sentence endings sharp, use punctuation as a cue for short, clean pauses, and maintain a slightly brisk pace without sacrificing clarity.\n\n## Contextual Lead-in\nThe Host has already set up the topic as a short update, and the Guest is now delivering the main facts in a fast, organized exchange. The listener should feel that the most important information is arriving quickly and clearly.",
                'is_system' => true,
            ),
            array(
                'id' => 'friendly_cohost_chat',
                'index_id' => 14,
                'name' => 'Friendly Co-host Chat',
                'speaker_type' => 'multi',
                'description' => 'Easygoing chemistry between familiar co-hosts.',
                'directive' => 'Make the exchange feel relaxed, friendly, and natural, as if two familiar co-hosts are talking comfortably. Keep the tone light and conversational, with smooth turn-taking and occasional playful warmth.',
                'voice_direction_template' => "## Audio Profile\nHost:\nA warm and easygoing guide who keeps the conversation moving in a relaxed and welcoming way. The Host should sound like a listener-friendly partner who gently leads the flow.\n\nGuest:\nA friendly and natural speaker who explains the main content with approachable, everyday phrasing. The Guest should sound comfortable, human, and easy to listen to.\n\n## Scene\nA comfortable co-host style conversation where the speakers sound familiar with each other and easy for the listener to join. The atmosphere is soft, relaxed, and naturally conversational.\n\n## Director's Notes\nKeep the Host in a listening and guiding role throughout the exchange. The Host should gently prompt, react, and keep the conversation easy to follow without sounding formal. Let the Guest carry the main explanation in a clear but friendly way. Keep sentence endings clear, use punctuation as a cue for natural pauses, and preserve a relaxed flow with a little warmth and human closeness.\n\n## Contextual Lead-in\nThe Host has already opened the topic in a friendly way, and the Guest is now explaining it as the conversation unfolds naturally. The listener should feel welcomed into a calm, easygoing exchange.",
                'is_system' => true,
            ),
            array(
                'id' => 'recommendation_spotlight',
                'index_id' => 15,
                'name' => 'Recommendation Spotlight',
                'speaker_type' => 'multi',
                'description' => 'Recommendation-focused two-speaker presentation with positive momentum.',
                'directive' => 'Create a positive, recommendation-style exchange. The Host should guide the listener toward the highlights, while the Guest explains the value and appeal of the topic in a natural, non-pushy way.',
                'voice_direction_template' => "## Audio Profile\nHost:\nA positive and engaging guide who helps the listener notice why the topic is worth paying attention to. The Host should sound attentive, lightly proactive, and easy to follow.\n\nGuest:\nA clear and appealing explanatory speaker who handles the main substance while naturally bringing out the value of the topic. The Guest should sound positive, confident, and informative.\n\n## Scene\nA recommendation-style conversation where the speakers are introducing something worth noticing without turning it into a hard sell. The atmosphere is upbeat, clear, and inviting.\n\n## Director's Notes\nKeep the Host in a listening and guiding role throughout the exchange. The Host should steer the conversation toward the highlights, react with interest, and help the listener notice the key appeal points. Let the Guest handle the main explanation with a positive but balanced tone. Keep sentence endings clear, use punctuation as a cue for clean pauses, and maintain a pleasant forward-moving rhythm without sounding pushy or overly promotional.\n\n## Contextual Lead-in\nThe Host has already introduced the topic as something worth noticing, and the Guest is now explaining the main strengths and highlights. The listener should feel guided toward the value of the topic in a natural, positive way.",
                'is_system' => true,
            ),
            array(
                'id' => 'story_flow_dialogue',
                'index_id' => 16,
                'name' => 'Story Flow Dialogue',
                'speaker_type' => 'multi',
                'description' => 'Narrative two-speaker exchange with clear story progression.',
                'directive' => 'Create a two-speaker exchange that carries the listener through a narrative flow. The Host should guide the progression, while the Guest explains the substance with a connected sense of background, development, and landing.',
                'voice_direction_template' => "## Audio Profile\nHost:\nA calm narrative guide who helps shape the flow of the conversation and keeps the listener oriented as the story progresses. The Host should sound attentive, connective, and steady.\n\nGuest:\nA vivid explanatory speaker who carries the main substance with a connected narrative rhythm. The Guest should sound thoughtful, expressive, and clear.\n\n## Scene\nA story-driven conversation where the topic unfolds with a sense of progression rather than as isolated points. The atmosphere is focused, flowing, and slightly dramatic without becoming theatrical.\n\n## Director's Notes\nKeep the Host in a listening and guiding role throughout the exchange. The Host should help mark transitions, react in ways that support the flow, and lead the listener naturally from one stage of the story to the next. Let the Guest handle the main explanation with a connected, narrative rhythm. Keep sentence endings distinct, use punctuation as a cue for natural pauses, and shape the exchange so the listener feels the background, development, and landing of the story.\n\n## Contextual Lead-in\nThe Host has already opened the path into the topic, and the Guest is now carrying the listener through the narrative flow. The listener should feel the story moving forward in a clear and engaging progression.",
                'is_system' => true,
            ),
            array(
                'id' => 'scene_drama_exchange',
                'index_id' => 17,
                'name' => 'Scene Drama Exchange',
                'speaker_type' => 'multi',
                'description' => 'Scene-focused dramatic exchange with strong atmosphere.',
                'directive' => 'Create a two-speaker exchange that makes the scene feel vivid and present. The Host should guide the listener through the atmosphere, while the Guest carries the main descriptive substance with dramatic clarity.',
                'voice_direction_template' => "## Audio Profile\nHost:\nA composed scene guide who helps frame the atmosphere and keeps the listener oriented inside the exchange. The Host should sound attentive, steady, and slightly dramatic without taking over.\n\nGuest:\nAn expressive scene-focused speaker who carries the main descriptive content with strong visual and emotional presence. The Guest should sound vivid, clear, and memorable.\n\n## Scene\nA cinematic exchange where the listener can easily picture the atmosphere, movement, and emotional texture of the scene. The conversation should feel like a memorable film or drama moment unfolding in front of the audience.\n\n## Director's Notes\nKeep the Host in a listening and guiding role throughout the exchange. The Host should help frame the scene, react in ways that support the atmosphere, and guide the listener through the progression. Let the Guest carry the main substance with a vivid, image-rich delivery. Keep sentence endings clear, use punctuation as a cue for expressive pauses, and make the exchange feel atmospheric and dramatic without losing intelligibility.\n\n## Contextual Lead-in\nThe Host has already brought the listener into the scene, and the Guest is now making the atmosphere and details feel vivid. The listener should feel the scene spreading out clearly in front of them.",
                'is_system' => true,
            ),
            array(
                'id' => 'manzai_fast_tempo',
                'index_id' => 18,
                'name' => 'Manzai Fast Tempo',
                'speaker_type' => 'multi',
                'description' => 'Fast comedic back-and-forth with sharp timing and escalation.',
                'directive' => 'Create a fast-paced comedic back-and-forth with strong contrast in timing, attitude, and reaction. Keep the rhythm sharp and responsive, with quick exchanges and clear comedic escalation.',
                'voice_direction_template' => "## Audio Profile\nHost:\nA sharp, quick-reacting straight-man style guide who listens, responds, and drives the rhythm of the exchange forward. The Host should sound alert, timing-aware, and clearly focused on steering the flow.\n\nGuest:\nA highly energetic comic speaker who drives the main joke momentum with bold delivery and strong character. The Guest should sound playful, fast, and full of performance energy.\n\n## Scene\nA stage-ready manzai-style performance where timing, audience awareness, and rapid reactions matter more than ordinary conversation. The atmosphere is lively, performance-driven, and tightly paced.\n\n## Director's Notes\nKeep the Host in a listening and guiding role throughout the exchange, even when reacting sharply. The Host should frame, respond, and steer the rhythm so the jokes land cleanly. Let the Guest carry the main comedic performance with speed, boldness, and clear contrast. Keep sentence endings audible, use punctuation as a cue for timing and punch, and preserve clarity while maintaining a fast, energetic stage rhythm.\n\n## Contextual Lead-in\nThe Host and Guest are already in the middle of a lively comedic exchange, with the Host guiding the rhythm and the Guest pushing the joke momentum forward. The listener should feel the speed and timing of a stage performance rather than an ordinary conversation.",
                'is_system' => true,
            ),
        );
    }

    /**
     * Get current smart tone styles.
     *
     * @return array<int, array<string, string|bool>>
     */
    public static function get_styles()
    {
        $saved = get_option(self::STYLES_OPTION_NAME, array());
        $default_styles = self::get_default_styles();
        $default_style_ids = array();
        foreach ($default_styles as $default_style) {
            if (!is_array($default_style) || empty($default_style['id'])) {
                continue;
            }

            $default_style_ids[] = sanitize_key($default_style['id']);
        }

        if (!is_array($saved) || empty($saved)) {
            return $default_styles;
        }

        $normalized = array();
        $sync_needed = false;
        foreach ($saved as $style) {
            if (!is_array($style)) {
                continue;
            }

            $style_id = isset($style['id']) ? sanitize_key($style['id']) : '';
            $speaker_type = isset($style['speaker_type']) && $style['speaker_type'] === 'multi' ? 'multi' : 'single';
            $name = isset($style['name']) ? sanitize_text_field($style['name']) : '';
            $directive = isset($style['directive']) ? sanitize_textarea_field($style['directive']) : '';
            $voice_direction_template = isset($style['voice_direction_template']) ? sanitize_textarea_field($style['voice_direction_template']) : '';
            $description = isset($style['description']) ? sanitize_text_field($style['description']) : '';

            if ($style_id === '' || $name === '' || $directive === '') {
                continue;
            }

            $is_system_style = !empty($style['is_system']);
            if ($is_system_style && !in_array($style_id, $default_style_ids, true)) {
                $sync_needed = true;
                continue;
            }

            $normalized[$style_id] = array(
                'id' => $style_id,
                'index_id' => isset($style['index_id']) ? absint($style['index_id']) : 0,
                'name' => $name,
                'speaker_type' => $speaker_type,
                'description' => $description,
                'directive' => $directive,
                'voice_direction_template' => $voice_direction_template,
                'is_system' => $is_system_style,
                'last_updated' => isset($style['last_updated']) ? sanitize_text_field($style['last_updated']) : '',
            );
        }

        foreach ($default_styles as $default_style) {
            if (!is_array($default_style) || empty($default_style['id'])) {
                continue;
            }

            $default_id = sanitize_key($default_style['id']);
            if (isset($normalized[$default_id])) {
                $merged_style = array_merge($normalized[$default_id], $default_style);
                if ($merged_style !== $normalized[$default_id]) {
                    $sync_needed = true;
                }
                $normalized[$default_id] = $merged_style;
                continue;
            }

            $normalized[$default_id] = $default_style;
            $sync_needed = true;
        }

        if (empty($normalized)) {
            return $default_styles;
        }

        uasort($normalized, function ($left, $right) {
            $left_index = isset($left['index_id']) ? absint($left['index_id']) : 0;
            $right_index = isset($right['index_id']) ? absint($right['index_id']) : 0;

            if ($left_index === $right_index) {
                $left_name = isset($left['name']) ? (string) $left['name'] : '';
                $right_name = isset($right['name']) ? (string) $right['name'] : '';
                return strcmp($left_name, $right_name);
            }

            return $left_index <=> $right_index;
        });

        $final_styles = array_values($normalized);
        if ($sync_needed) {
            update_option(self::STYLES_OPTION_NAME, $final_styles);
        }

        return $final_styles;
    }

    /**
     * Get a style definition by ID.
     *
     * @param string $style_id The style ID.
     * @return array<string, mixed>|false
     */
    public static function get_style($style_id)
    {
        $style = self::find_style($style_id);
        return $style ? $style : false;
    }

    /**
     * Get styles for a specific speaker type.
     *
     * @param string|null $speaker_type The requested speaker type.
     * @return array<int, array<string, string|bool>>
     */
    public static function get_styles_for_speaker_type($speaker_type = null)
    {
        $speaker_type = $speaker_type === 'multi' ? 'multi' : 'single';
        return array_values(array_filter(self::get_styles(), function ($style) use ($speaker_type) {
            return isset($style['speaker_type']) && $style['speaker_type'] === $speaker_type;
        }));
    }

    /**
     * Find a style definition by ID.
     *
     * @param string $style_id The style ID.
     * @return array<string, string|bool>|null
     */
    public static function find_style($style_id)
    {
        $style_id = sanitize_key($style_id);
        foreach (self::get_styles() as $style) {
            if (isset($style['id']) && $style['id'] === $style_id) {
                return $style;
            }
        }

        return null;
    }

    /**
     * Get the configured default style ID for a speaker type.
     *
     * @param string $speaker_type The speaker type.
     * @return string
     */
    public static function get_default_style_id($speaker_type)
    {
        $config = self::get_config();
        $speaker_type = $speaker_type === 'multi' ? 'multi' : 'single';
        $config_key = $speaker_type === 'multi' ? 'default_multi_smart_tone_style_id' : 'default_single_smart_tone_style_id';
        $default_id = isset($config[$config_key]) ? sanitize_key($config[$config_key]) : '';

        $candidate = self::find_style($default_id);
        if ($candidate && isset($candidate['speaker_type']) && $candidate['speaker_type'] === $speaker_type) {
            return $default_id;
        }

        $styles = self::get_styles_for_speaker_type($speaker_type);
        if (!empty($styles[0]['id'])) {
            return $styles[0]['id'];
        }

        return '';
    }

    /**
     * Save configuration.
     */
    public static function save($config)
    {
        return update_option(self::OPTION_NAME, $config);
    }

    /**
     * Save or update a smart tone style.
     *
     * @param string|null $style_id The style ID.
     * @param string      $name The style name.
     * @param string      $speaker_type The speaker type.
     * @param string      $description The style description.
     * @param string      $directive The directive text.
     * @param string      $voice_direction_template The voice direction template.
     * @return string
     */
    public static function save_style($style_id, $name, $speaker_type, $description, $directive, $voice_direction_template)
    {
        $styles = self::get_styles();
        $normalized_styles = array();
        $existing_style = null;

        foreach ($styles as $style) {
            $current_id = isset($style['id']) ? sanitize_key($style['id']) : '';
            if ($current_id !== '' && $style_id && $current_id === sanitize_key($style_id)) {
                $existing_style = $style;
            }
            $normalized_styles[$current_id] = $style;
        }

        $normalized_id = $style_id ? sanitize_key($style_id) : '';
        if ($normalized_id === '') {
            $normalized_id = uniqid('smart_tone_', false);
        }

        $index_id = 0;
        if (is_array($existing_style) && !empty($existing_style['index_id'])) {
            $index_id = absint($existing_style['index_id']);
        }

        if ($index_id === 0) {
            $saved_next_id = absint(get_option(self::NEXT_ID_OPTION, 0));
            $highest_index_id = 0;
            foreach ($styles as $style) {
                $highest_index_id = max($highest_index_id, isset($style['index_id']) ? absint($style['index_id']) : 0);
            }

            $index_id = max($saved_next_id, $highest_index_id + 1, 1);
            update_option(self::NEXT_ID_OPTION, $index_id + 1);
        }

        $normalized_styles[$normalized_id] = array(
            'id' => $normalized_id,
            'index_id' => $index_id,
            'name' => sanitize_text_field($name),
            'speaker_type' => $speaker_type === 'multi' ? 'multi' : 'single',
            'description' => sanitize_text_field($description),
            'directive' => sanitize_textarea_field($directive),
            'voice_direction_template' => sanitize_textarea_field($voice_direction_template),
            'is_system' => false,
            'last_updated' => current_time('mysql'),
        );

        uasort($normalized_styles, function ($left, $right) {
            $left_index = isset($left['index_id']) ? absint($left['index_id']) : 0;
            $right_index = isset($right['index_id']) ? absint($right['index_id']) : 0;

            if ($left_index === $right_index) {
                $left_name = isset($left['name']) ? (string) $left['name'] : '';
                $right_name = isset($right['name']) ? (string) $right['name'] : '';
                return strcmp($left_name, $right_name);
            }

            return $left_index <=> $right_index;
        });

        update_option(self::STYLES_OPTION_NAME, array_values($normalized_styles));

        return $normalized_id;
    }

    /**
     * Duplicate a smart tone style.
     *
     * @param string $style_id The source style ID.
     * @return string|false
     */
    public static function duplicate_style($style_id)
    {
        $source_style = self::get_style($style_id);
        if (!$source_style) {
            return false;
        }

        return self::save_style(
            null,
            $source_style['name'] . ' (copy)',
            isset($source_style['speaker_type']) ? $source_style['speaker_type'] : 'single',
            isset($source_style['description']) ? $source_style['description'] : '',
            isset($source_style['directive']) ? $source_style['directive'] : '',
            isset($source_style['voice_direction_template']) ? $source_style['voice_direction_template'] : ''
        );
    }

    /**
     * Delete a smart tone style.
     *
     * @param string $style_id The style ID.
     * @return void
     */
    public static function delete_style($style_id)
    {
        $normalized_id = sanitize_key($style_id);
        $styles = array_values(array_filter(self::get_styles(), function ($style) use ($normalized_id) {
            return isset($style['id']) && $style['id'] !== $normalized_id;
        }));

        update_option(self::STYLES_OPTION_NAME, $styles);

        $config = self::get_config();
        $updated = false;
        if (isset($config['default_single_smart_tone_style_id']) && $config['default_single_smart_tone_style_id'] === $normalized_id) {
            $config['default_single_smart_tone_style_id'] = self::resolve_fallback_default_style_id($styles, 'single');
            $updated = true;
        }
        if (isset($config['default_multi_smart_tone_style_id']) && $config['default_multi_smart_tone_style_id'] === $normalized_id) {
            $config['default_multi_smart_tone_style_id'] = self::resolve_fallback_default_style_id($styles, 'multi');
            $updated = true;
        }
        if ($updated) {
            update_option(self::OPTION_NAME, $config);
        }
    }

    /**
     * Set the default smart tone style for a speaker type.
     *
     * @param string $speaker_type The speaker type.
     * @param string $style_id The style ID.
     * @return void
     */
    public static function set_default_style_id($speaker_type, $style_id)
    {
        $speaker_type = $speaker_type === 'multi' ? 'multi' : 'single';
        $style = self::find_style($style_id);
        if (!$style || !isset($style['speaker_type']) || $style['speaker_type'] !== $speaker_type) {
            return;
        }

        $config = self::get_config();
        if ($speaker_type === 'multi') {
            $config['default_multi_smart_tone_style_id'] = sanitize_key($style_id);
        } else {
            $config['default_single_smart_tone_style_id'] = sanitize_key($style_id);
        }

        update_option(self::OPTION_NAME, $config);
    }

    /**
     * Reset to defaults.
     */
    public static function reset()
    {
        delete_option(self::NEXT_ID_OPTION);
        delete_option(self::STYLES_OPTION_NAME);
        return delete_option(self::OPTION_NAME);
    }

    /**
     * Get UI labels for styles.
     */
    public static function get_style_labels()
    {
        $labels = array();
        foreach (self::get_styles() as $style) {
            if (!empty($style['id']) && !empty($style['name'])) {
                $labels[$style['id']] = $style['name'];
            }
        }
        return $labels;
    }

    /**
     * Get UI-ready style options.
     *
     * @param string|null $speaker_type Speaker type filter.
     * @return array<int, array<string, string|bool>>
     */
    public static function get_style_options($speaker_type = null)
    {
        $options = array();
        $styles = $speaker_type ? self::get_styles_for_speaker_type($speaker_type) : self::get_styles();
        $default_single_id = self::get_default_style_id('single');
        $default_multi_id = self::get_default_style_id('multi');

        foreach ($styles as $style) {
            $style_id = isset($style['id']) ? $style['id'] : '';
            $current_type = isset($style['speaker_type']) && $style['speaker_type'] === 'multi' ? 'multi' : 'single';
            $is_default = ($current_type === 'single' && $style_id === $default_single_id) || ($current_type === 'multi' && $style_id === $default_multi_id);
            $label = isset($style['name']) ? $style['name'] : $style_id;

            if ($is_default) {
                $label .= ' (Default)';
            }

            $options[] = array(
                'value' => $style_id,
                'label' => $label,
                'speaker_type' => $current_type,
                'is_default' => $is_default,
                'description' => isset($style['description']) ? $style['description'] : '',
                'directive' => isset($style['directive']) ? $style['directive'] : '',
                'voice_direction_template' => isset($style['voice_direction_template']) ? $style['voice_direction_template'] : '',
            );
        }

        return $options;
    }

    /**
     * Resolve a fallback default style ID after a deletion.
     *
     * @param array<int, array<string, mixed>> $styles The remaining styles.
     * @param string                           $speaker_type The target speaker type.
     * @return string
     */
    private static function resolve_fallback_default_style_id($styles, $speaker_type)
    {
        $normalized_type = $speaker_type === 'multi' ? 'multi' : 'single';
        foreach ($styles as $style) {
            if (isset($style['speaker_type'], $style['id']) && $style['speaker_type'] === $normalized_type) {
                return sanitize_key($style['id']);
            }
        }

        return '';
    }
}
