/**
 * Contentosapp Studio Brand Voice — Wizard interactions.
 *
 * @since 3.2.0
 */

/* global CostudioData */
(function ($) {
    'use strict';

    const data = window.CostudioData || {};
    const ajaxUrl = data.ajax_url || '';
    const nonce = data.nonce || '';

    function t(key, fallback) {
        return (data.i18n && data.i18n[key]) ? data.i18n[key] : fallback;
    }

    function textNode(tag, attrs, text) {
        return $('<' + tag + '/>', attrs || {}).text(text == null ? '' : String(text));
    }

    function format(template, values) {
        return String(template || '').replace(/\{([a-z0-9_]+)\}/gi, function (match, key) {
            return Object.prototype.hasOwnProperty.call(values || {}, key) ? values[key] : match;
        });
    }

    function uniqueList(items) {
        const seen = {};
        return (Array.isArray(items) ? items : [])
            .map(item => String(item || '').trim())
            .filter(item => {
                const key = item.toLowerCase();
                if (!item || seen[key]) return false;
                seen[key] = true;
                return true;
            });
    }

    const TONE_FIELDS = ['formality', 'technicality', 'authority', 'opinion', 'warmth'];

    const toneDescriptions = {
        formality: {
            1: t('brand_voice_tone_formality_1', 'Very casual'),
            2: t('brand_voice_tone_formality_2', 'Friendly chat'),
            3: t('brand_voice_tone_formality_3', 'Neutral'),
            4: t('brand_voice_tone_formality_4', 'Professional'),
            5: t('brand_voice_tone_formality_5', 'Formal')
        },
        technicality: {
            1: t('brand_voice_tone_technicality_1', 'For beginners'),
            2: t('brand_voice_tone_technicality_2', 'Accessible'),
            3: t('brand_voice_tone_technicality_3', 'Balanced'),
            4: t('brand_voice_tone_technicality_4', 'Technical'),
            5: t('brand_voice_tone_technicality_5', 'Expert')
        },
        authority: {
            1: t('brand_voice_tone_authority_1', 'Careful'),
            2: t('brand_voice_tone_authority_2', 'Guiding'),
            3: t('brand_voice_tone_authority_3', 'Confident'),
            4: t('brand_voice_tone_authority_4', 'Assertive'),
            5: t('brand_voice_tone_authority_5', 'Categorical')
        },
        opinion: {
            1: t('brand_voice_tone_opinion_1', 'Factual'),
            2: t('brand_voice_tone_opinion_2', 'Analytical'),
            3: t('brand_voice_tone_opinion_3', 'Balanced'),
            4: t('brand_voice_tone_opinion_4', 'Critical'),
            5: t('brand_voice_tone_opinion_5', 'Opinionated')
        },
        warmth: {
            1: t('brand_voice_tone_warmth_1', 'Distant'),
            2: t('brand_voice_tone_warmth_2', 'Reserved'),
            3: t('brand_voice_tone_warmth_3', 'Natural'),
            4: t('brand_voice_tone_warmth_4', 'Close'),
            5: t('brand_voice_tone_warmth_5', 'Welcoming')
        }
    };

    const presets = {
        professional: {
            formality: 5,
            technicality: 4,
            authority: 5,
            opinion: 2,
            warmth: 2,
            pov: 'third',
            para: 'medium'
        },
        conversational: {
            formality: 2,
            technicality: 2,
            authority: 3,
            opinion: 4,
            warmth: 5,
            pov: 'second',
            para: 'short'
        },
        academic: {
            formality: 5,
            technicality: 5,
            authority: 4,
            opinion: 1,
            warmth: 1,
            pov: 'third',
            para: 'long'
        },
        journalistic: {
            formality: 4,
            technicality: 3,
            authority: 4,
            opinion: 2,
            warmth: 3,
            pov: 'third',
            para: 'medium'
        }
    };

    const packs = {
        marketing: {
            preferred: [
                t('brand_voice_pack_marketing_preferred_1', 'funnel conversion'),
                t('brand_voice_pack_marketing_preferred_2', 'marketing team'),
                t('brand_voice_pack_marketing_preferred_3', 'scale production'),
                t('brand_voice_pack_marketing_preferred_4', 'playbook'),
                t('brand_voice_pack_marketing_preferred_5', 'consistency')
            ],
            avoid: [
                t('brand_voice_pack_marketing_avoid_1', 'revolutionary'),
                t('brand_voice_pack_marketing_avoid_2', 'transform'),
                t('brand_voice_pack_marketing_avoid_3', 'game changer')
            ],
            signatures: [t('brand_voice_pack_marketing_signature', 'Marketing that measures what matters.')],
            replacements: [{ from: t('brand_voice_pack_marketing_from', 'user'), to: t('brand_voice_pack_marketing_to', 'customer') }],
            dos: [t('brand_voice_pack_marketing_do', 'use business metrics')],
            donts: [t('brand_voice_pack_marketing_dont', 'promise guaranteed results')]
        },
        editorial: {
            preferred: [
                t('brand_voice_pack_editorial_preferred_1', 'context'),
                t('brand_voice_pack_editorial_preferred_2', 'evidence'),
                t('brand_voice_pack_editorial_preferred_3', 'clarity'),
                t('brand_voice_pack_editorial_preferred_4', 'analysis')
            ],
            avoid: [
                t('brand_voice_pack_editorial_avoid_1', 'shocking'),
                t('brand_voice_pack_editorial_avoid_2', 'must-see'),
                t('brand_voice_pack_editorial_avoid_3', 'revealed secret')
            ],
            signatures: [t('brand_voice_pack_editorial_signature', 'No exaggeration: only what holds up.')],
            replacements: [{ from: t('brand_voice_pack_editorial_from', 'opinion'), to: t('brand_voice_pack_editorial_to', 'analysis') }],
            dos: [t('brand_voice_pack_editorial_do', 'explain cause and consequence')],
            donts: [t('brand_voice_pack_editorial_dont', 'use sensationalist tone')]
        }
    };

    const BrandVoice = {
        modal: null,
        currentKey: '',
        currentStep: 1,
        hasExistingVoice: false,
        chips: {
            preferred: [],
            avoid: [],
            signatures: [],
            dos: [],
            donts: []
        },
        replacements: [],

        init: function () {
            this.modal = $('#fos-modal-brand-voice');
            if (!this.modal.length) return;

            this.bindEvents();
            this.initChipInput('preferred');
            this.initChipInput('avoid');
            this.initChipInput('signatures');
            this.initChipInput('dos');
            this.initChipInput('donts');
            this.updateAll();
        },

        bindEvents: function () {
            const self = this;

            $(document).on('click', '.fos-open-voice-btn', function (e) {
                e.preventDefault();
                self.open($(this).data('key'), $(this).data('name'));
            });

            this.modal.on('click', '.fos-modal__close', function () {
                self.close();
            });

            this.modal.on('click', function (e) {
                if (e.target === self.modal[0]) {
                    self.close();
                }
            });

            $(document).on('keydown', function (e) {
                if (e.key === 'Escape' && self.modal.is(':visible')) {
                    self.close();
                }
            });

            this.modal.on('click', '.fos-voice-step-nav', function () {
                self.goToStep(parseInt($(this).data('step'), 10));
            });

            $('#fos-voice-next-btn').on('click', function () {
                if (self.validateStep(self.currentStep)) {
                    self.goToStep(self.currentStep + 1, true);
                }
            });

            $('#fos-voice-prev-btn').on('click', function () {
                self.goToStep(self.currentStep - 1, true);
            });

            $('#fos-voice-save-btn').on('click', function () {
                self.save();
            });

            $('#fos-voice-delete-btn').on('click', function () {
                if (window.confirm(t('confirm_delete', 'Excluir esta voz da marca?'))) {
                    self.delete();
                }
            });

            $('#fos-voice-preview-btn').on('click', function () {
                self.generatePreview();
            });

            $('#fos-voice-blank-btn').on('click', function () {
                self.resetForm();
                self.goToStep(1, true);
            });

            this.modal.on('input change', '#fos-voice-name, #fos-voice-author, #fos-voice-reader, #fos-voice-pov, #fos-voice-para-len, #fos-voice-emojis, #fos-voice-h2-q, .fos-voice-sample-input', function () {
                self.updateAll();
            });

            this.modal.on('input', '.fos-voice-slider', function () {
                self.updateSlider($(this));
                self.updateAll();
            });

            this.modal.on('click', '.fos-voice-preset-btn', function () {
                const preset = $(this).data('preset');
                self.applyPreset(preset);
                self.modal.find('.fos-voice-preset-btn').removeClass('is-active active');
                $(this).addClass('is-active active');
            });

            this.modal.on('click', '.fos-voice-suggestion', function () {
                self.addChip($(this).data('chip-type'), $(this).data('chip'));
            });

            this.modal.on('click', '.fos-voice-pack-btn', function () {
                self.applyPack($(this).data('pack'));
            });

            $('#fos-voice-add-replacement').on('click', function () {
                self.addReplacement($('#fos-voice-replace-from').val(), $('#fos-voice-replace-to').val());
                $('#fos-voice-replace-from, #fos-voice-replace-to').val('');
            });

            this.modal.on('keydown', '#fos-voice-replace-from, #fos-voice-replace-to', function (e) {
                if (e.key === 'Enter') {
                    e.preventDefault();
                    $('#fos-voice-add-replacement').trigger('click');
                }
            });

            this.modal.on('click', '.fos-voice-replacement-remove', function () {
                self.removeReplacement(parseInt($(this).data('index'), 10));
            });

            this.modal.on('click', '.fos-voice-edit-step', function () {
                self.goToStep(parseInt($(this).data('step'), 10), true);
            });
        },

        open: function (key, siteName) {
            this.currentKey = key || '';
            this.hasExistingVoice = false;
            $('#fos-voice-site-key').val(this.currentKey);
            $('#fos-voice-site-name').text(siteName || '');

            this.resetForm();
            this.loadData(this.currentKey);
            this.modal.stop(true, true).css('display', 'flex').hide().fadeIn(160);
        },

        close: function () {
            this.modal.fadeOut(140);
        },

        loadData: function (key) {
            const self = this;

            $.get(ajaxUrl, {
                action: 'costudio_get_brand_voice',
                nonce: nonce,
                site_key: key
            }, function (res) {
                if (res && res.success && res.data && res.data.voice) {
                    self.hasExistingVoice = true;
                    self.populateVoice(res.data.voice);
                    $('#fos-voice-delete-btn').show();
                } else {
                    self.hasExistingVoice = false;
                    $('#fos-voice-delete-btn').hide();
                }
                self.updateAll();
            });
        },

        populateVoice: function (voice) {
            const persona = voice.persona || {};
            const tone = voice.tone || {};
            const vocabulary = voice.vocabulary || {};
            const rules = voice.rules || {};

            $('#fos-voice-name').val(voice.name || '');
            $('#fos-voice-author').val(persona.author || '');
            $('#fos-voice-reader').val(persona.reader || '');

            TONE_FIELDS.forEach(id => {
                $('#fos-voice-' + id).val(tone[id] || 3);
                this.updateSlider($('#fos-voice-' + id));
            });

            this.renderChips('preferred', vocabulary.preferred || []);
            this.renderChips('avoid', vocabulary.avoid || []);
            this.renderChips('signatures', vocabulary.signatures || []);
            this.renderChips('dos', rules.dos || []);
            this.renderChips('donts', rules.donts || []);
            this.renderReplacements(vocabulary.replacements || []);

            $('#fos-voice-pov').val(rules.pov || 'third');
            $('#fos-voice-para-len').val(rules.paragraph_len || 'medium');
            $('#fos-voice-emojis').prop('checked', !!rules.use_emojis);
            $('#fos-voice-h2-q').prop('checked', !!rules.h2_as_question);

            const samples = Array.isArray(voice.samples) ? voice.samples : [];
            this.modal.find('.fos-voice-sample-input').val('');
            samples.slice(0, 3).forEach((sample, index) => {
                $('#fos-voice-sample-' + (index + 1)).val(sample || '');
            });
        },

        collectVoice: function () {
            return {
                name: $('#fos-voice-name').val().trim(),
                persona: {
                    author: $('#fos-voice-author').val().trim(),
                    reader: $('#fos-voice-reader').val().trim()
                },
                tone: {
                    formality: $('#fos-voice-formality').val(),
                    technicality: $('#fos-voice-technicality').val(),
                    authority: $('#fos-voice-authority').val(),
                    opinion: $('#fos-voice-opinion').val(),
                    warmth: $('#fos-voice-warmth').val()
                },
                vocabulary: {
                    preferred: this.chips.preferred,
                    avoid: this.chips.avoid,
                    signatures: this.chips.signatures,
                    replacements: this.replacements
                },
                rules: {
                    pov: $('#fos-voice-pov').val(),
                    paragraph_len: $('#fos-voice-para-len').val(),
                    use_emojis: $('#fos-voice-emojis').is(':checked'),
                    h2_as_question: $('#fos-voice-h2-q').is(':checked'),
                    dos: this.chips.dos,
                    donts: this.chips.donts
                },
                samples: this.getSamples()
            };
        },

        save: function () {
            if (!this.validateStep(1)) {
                this.goToStep(1, true);
                return;
            }
            if (!this.validateStep(3)) {
                this.goToStep(3, true);
                return;
            }

            const btn = $('#fos-voice-save-btn');
            const originalText = btn.html();
            const voice = this.collectVoice();

            btn.prop('disabled', true).text(t('saving', 'Salvando...'));

            $.post(ajaxUrl, {
                action: 'costudio_save_brand_voice',
                nonce: nonce,
                site_key: this.currentKey,
                voice: JSON.stringify(voice)
            }, function (res) {
                btn.prop('disabled', false).html(originalText);
                if (res && res.success) {
                    window.alert(t('saved', 'Salvo!'));
                    window.location.reload();
                } else {
                    window.alert((res && res.data && res.data.message) ? res.data.message : t('error', 'Erro'));
                }
            }).fail(function () {
                btn.prop('disabled', false).html(originalText);
                window.alert(t('network_error', 'Network error.'));
            });
        },

        delete: function () {
            $.post(ajaxUrl, {
                action: 'costudio_delete_brand_voice',
                nonce: nonce,
                site_key: this.currentKey
            }, function () {
                window.location.reload();
            });
        },

        generatePreview: function () {
            if (!this.validateStep(1)) {
                this.goToStep(1, true);
                return;
            }
            if (!this.validateStep(3)) {
                this.goToStep(3, true);
                return;
            }

            const btn = $('#fos-voice-preview-btn');
            const box = $('#fos-voice-preview-box');
            const originalText = btn.html();

            btn.prop('disabled', true).html('<span class="dashicons dashicons-update fos-spin" aria-hidden="true"></span> ' + t('generating', 'Gerando...'));
            box.empty().append(
                $('<div/>', { class: 'fos-voice-preview-loading' })
                    .append($('<span/>', { class: 'dashicons dashicons-update fos-spin', 'aria-hidden': 'true' }))
                    .append(textNode('p', {}, t('brand_voice_preview_loading', 'AI is crafting your preview...')))
            );

            $.post(ajaxUrl, {
                action: 'costudio_preview_brand_voice',
                nonce: nonce,
                site_key: this.currentKey,
                voice: JSON.stringify(this.collectVoice())
            }, function (res) {
                btn.prop('disabled', false).html(originalText);
                if (res && res.success) {
                    box.text(res.data.preview || '');
                } else {
                    box.empty().append(
                        textNode('div', { class: 'fos-voice-preview-error' }, (res && res.data && res.data.message) ? res.data.message : t('error', 'Erro'))
                    );
                }
            }).fail(function () {
                btn.prop('disabled', false).html(originalText);
                box.empty().append(textNode('div', { class: 'fos-voice-preview-error' }, t('network_error', 'Network error.')));
            });
        },

        goToStep: function (step, force) {
            const target = Math.max(1, Math.min(4, step || 1));

            if (!force && target > this.currentStep && !this.validateStep(this.currentStep)) {
                return;
            }

            this.currentStep = target;
            this.modal.find('.fos-voice-step-panel').removeClass('is-active');
            this.modal.find('[data-step-panel="' + target + '"]').addClass('is-active');
            this.updateStepState();
            this.updateFooter();
            this.updateAll();
        },

        updateStepState: function () {
            const self = this;
            this.modal.find('.fos-voice-step-nav').each(function () {
                const step = parseInt($(this).data('step'), 10);
                $(this)
                    .toggleClass('is-active', step === self.currentStep)
                    .toggleClass('is-complete', step < self.currentStep);
            });
        },

        updateFooter: function () {
            $('#fos-voice-prev-btn').toggle(this.currentStep > 1);
            $('#fos-voice-next-btn').toggle(this.currentStep < 4);
            $('#fos-voice-save-btn').toggle(this.currentStep === 4);

            const labels = {
                1: t('brand_voice_continue_tone', 'Continue to Tone'),
                2: t('brand_voice_continue_vocab', 'Continue to Vocabulary'),
                3: t('brand_voice_continue_review', 'Continue to Review')
            };
            $('#fos-voice-next-btn').text((labels[this.currentStep] || t('brand_voice_continue', 'Continue')) + ' →');
        },

        validateStep: function (step) {
            if (step === 1) {
                const field = $('#fos-voice-name');
                if (field.val().trim()) {
                    field.removeClass('is-invalid');
                    return true;
                }

                field.addClass('is-invalid').trigger('focus');
                window.alert(t('brand_voice_name_required', 'Voice name is required.'));
                return false;
            }

            if (step === 3) {
                const conflicts = this.getVocabularyConflicts();
                if (!conflicts.length) {
                    return true;
                }

                window.alert(format(t('brand_voice_resolve_vocab_conflicts', 'Resolve vocabulary conflicts before continuing: {terms}.'), {
                    terms: conflicts.join(', ')
                }));
                return false;
            }

            return true;
        },

        resetForm: function () {
            $('#fos-voice-name, #fos-voice-author, #fos-voice-reader').val('').removeClass('is-invalid');
            TONE_FIELDS.forEach(id => {
                const slider = $('#fos-voice-' + id);
                slider.val(3);
                this.updateSlider(slider);
            });

            $('#fos-voice-pov').val('third');
            $('#fos-voice-para-len').val('medium');
            $('#fos-voice-emojis, #fos-voice-h2-q').prop('checked', false);
            this.chips = { preferred: [], avoid: [], signatures: [], dos: [], donts: [] };
            this.replacements = [];
            this.renderChips('preferred');
            this.renderChips('avoid');
            this.renderChips('signatures');
            this.renderChips('dos');
            this.renderChips('donts');
            this.renderReplacements();
            this.modal.find('.fos-voice-sample-input').val('');
            this.modal.find('.fos-voice-preset-btn').removeClass('is-active active');
            $('#fos-voice-preview-box').empty().append(
                textNode('div', { class: 'fos-voice-preview-empty' }, t('brand_voice_preview_optional', 'The preview is optional. Generate a sample to validate the tone before saving.'))
            );
            this.goToStep(1, true);
        },

        applyPreset: function (name) {
            const preset = presets[name];
            if (!preset) return;

            TONE_FIELDS.forEach(id => {
                const slider = $('#fos-voice-' + id);
                slider.val(preset[id]);
                this.updateSlider(slider);
            });

            $('#fos-voice-pov').val(preset.pov);
            $('#fos-voice-para-len').val(preset.para);
            this.updateAll();
        },

        applyPack: function (name) {
            const pack = packs[name];
            if (!pack) return;

            this.addMany('preferred', pack.preferred);
            this.addMany('avoid', pack.avoid);
            this.addMany('signatures', pack.signatures);
            this.addMany('dos', pack.dos);
            this.addMany('donts', pack.donts);
            this.addReplacementMany(pack.replacements);
        },

        initChipInput: function (type) {
            const self = this;
            const container = $('#container-' + type);
            const input = container.find('.fos-chip-input');

            input.on('keydown', function (e) {
                if (e.key === 'Enter' || e.key === ',') {
                    e.preventDefault();
                    self.addChip(type, $(this).val());
                    $(this).val('');
                }
            });

            input.on('blur', function () {
                const val = $(this).val().trim();
                if (val) {
                    self.addChip(type, val);
                    $(this).val('');
                }
            });

            container.on('click', '.fos-chip-remove', function () {
                const val = $(this).closest('.fos-chip').data('val');
                self.chips[type] = self.chips[type].filter(chip => chip !== val);
                self.renderChips(type);
            });
        },

        addChip: function (type, rawValue) {
            if (!this.chips[type]) return;
            const value = String(rawValue || '').replace(/,/g, '').replace(/^\+\s*/, '').trim();
            if (!value) return;

            this.chips[type] = uniqueList(this.chips[type].concat([value]));
            this.renderChips(type);
        },

        addMany: function (type, values) {
            if (!this.chips[type]) return;
            this.chips[type] = uniqueList(this.chips[type].concat(values || []));
            this.renderChips(type);
        },

        normalizeReplacement: function (from, to) {
            return {
                from: String(from || '').trim(),
                to: String(to || '').trim()
            };
        },

        addReplacement: function (from, to) {
            const replacement = this.normalizeReplacement(from, to);
            if (!replacement.from || !replacement.to) return;

            const key = replacement.from.toLowerCase();
            const exists = this.replacements.some(item => item.from.toLowerCase() === key);
            if (exists) return;

            this.replacements.push(replacement);
            this.renderReplacements();
        },

        addReplacementMany: function (items) {
            (Array.isArray(items) ? items : []).forEach(item => {
                this.addReplacement(item.from, item.to);
            });
        },

        removeReplacement: function (index) {
            if (Number.isNaN(index)) return;
            this.replacements.splice(index, 1);
            this.renderReplacements();
        },

        renderReplacements: function (initialData) {
            if (Array.isArray(initialData)) {
                this.replacements = [];
                initialData.forEach(item => {
                    const replacement = this.normalizeReplacement(item.from, item.to);
                    if (replacement.from && replacement.to) {
                        this.replacements.push(replacement);
                    }
                });
            }

            const list = $('#fos-voice-replacements-list');
            list.empty();

            if (!this.replacements.length) {
                list.append(textNode('div', { class: 'fos-voice-replacements-empty' }, t('brand_voice_no_replacements', 'No substitutions configured.')));
            } else {
                this.replacements.forEach((item, index) => {
                    $('<div/>', { class: 'fos-voice-replacement-item' })
                        .append(textNode('span', { class: 'fos-voice-replacement-item__from' }, item.from))
                        .append($('<span/>', { class: 'dashicons dashicons-arrow-right-alt', 'aria-hidden': 'true' }))
                        .append(textNode('span', { class: 'fos-voice-replacement-item__to' }, item.to))
                        .append($('<button/>', {
                            type: 'button',
                            class: 'fos-voice-replacement-remove',
                            'data-index': index,
                            'aria-label': t('brand_voice_remove_replacement', 'Remove substitution')
                        }).text('×'))
                        .appendTo(list);
                });
            }

            this.updateAll();
        },

        renderChips: function (type, initialData) {
            if (Array.isArray(initialData)) {
                this.chips[type] = uniqueList(initialData);
            }

            const container = $('#container-' + type);
            const input = container.find('.fos-chip-input');
            container.find('.fos-chip').remove();

            this.chips[type].forEach(val => {
                textNode('span', { class: 'fos-chip fos-chip--' + type }, val)
                    .attr('data-val', val)
                    .append($('<button/>', {
                        type: 'button',
                        class: 'fos-chip-remove',
                        'aria-label': format(t('brand_voice_remove_item', 'Remove {item}'), { item: val })
                    }).text('×'))
                    .insertBefore(input);
            });

            this.updateAll();
        },

        updateSlider: function (slider) {
            const id = slider.attr('id').replace('fos-voice-', '');
            const value = parseInt(slider.val(), 10) || 3;
            const percent = ((value - 1) / 4) * 100;

            $('#val-' + id).text(value);
            $('#desc-' + id).text((toneDescriptions[id] && toneDescriptions[id][value]) ? toneDescriptions[id][value] : '—');
            slider.closest('.fos-voice-slider-group').css('--range-value', percent);
            slider.css('background', 'linear-gradient(90deg, #d8ccff 0%, var(--fos-primary, #6C47FF) ' + percent + '%, #e5e7eb ' + percent + '%, #e5e7eb 100%)');
        },

        updateAll: function () {
            TONE_FIELDS.forEach(id => this.updateSlider($('#fos-voice-' + id)));
            this.updateSummary();
            this.updateVocabImpact();
            this.updateReview();
            this.renderRadar();
        },

        updateSummary: function () {
            const voice = this.collectVoice();
            $('#fos-voice-summary-name').text(voice.name || '—');
            $('#fos-voice-summary-pov').text(this.getPovLabel(voice.rules.pov));
            $('#fos-voice-summary-tone').text(this.getToneSignature());
            $('#fos-voice-summary-vocab').text(this.getVocabSummary());
        },

        updateVocabImpact: function () {
            const preferred = this.chips.preferred.length;
            const avoid = this.chips.avoid.length;
            const signatures = this.chips.signatures.length;
            const replacements = this.replacements.length;
            const conflicts = this.getVocabularyConflicts();

            $('#fos-voice-count-preferred').text(preferred + ' ' + (preferred === 1 ? t('brand_voice_term_singular', 'term') : t('brand_voice_term_plural', 'terms')));
            $('#fos-voice-count-avoid').text(avoid + ' ' + (avoid === 1 ? t('brand_voice_term_singular', 'term') : t('brand_voice_term_plural', 'terms')));
            $('#fos-voice-count-signatures').text(signatures);
            $('#fos-voice-count-replacements').text(replacements);
            $('#fos-voice-count-dos').text(this.chips.dos.length);
            $('#fos-voice-count-donts').text(this.chips.donts.length);
            $('#fos-voice-impact-preferred').text(preferred);
            $('#fos-voice-impact-avoid').text(avoid);
            $('#fos-voice-impact-signatures').text(signatures);
            $('#fos-voice-impact-replacements').text(replacements);

            const preferredText = preferred ? this.chips.preferred.slice(0, 4).join(', ') : '—';
            const avoidText = avoid ? this.chips.avoid.slice(0, 4).join(', ') : '—';
            const signatureText = signatures ? this.chips.signatures.slice(0, 2).join(' | ') : '—';
            const replacementText = replacements ? this.replacements.slice(0, 2).map(item => item.from + ' → ' + item.to).join(' | ') : '—';
            $('#fos-voice-prompt-snippet').text(
                '# ' + t('brand_voice_prompt_vocabulary', 'VOCABULARY') +
                ' ## ' + t('brand_voice_prompt_prioritize', 'prioritize') + ' ' + preferredText +
                ' ## ' + t('brand_voice_prompt_prohibit', 'prohibit') + ' ' + avoidText +
                ' ## ' + t('brand_voice_prompt_replace', 'replace') + ' ' + replacementText +
                ' ## ' + t('brand_voice_prompt_signature', 'signature') + ' ' + signatureText
            );

            const conflictBox = $('#fos-voice-conflict-status');
            conflictBox.toggleClass('is-ok', conflicts.length === 0).toggleClass('is-error', conflicts.length > 0);
            conflictBox.find('.dashicons')
                .toggleClass('dashicons-yes-alt', conflicts.length === 0)
                .toggleClass('dashicons-warning', conflicts.length > 0);
            conflictBox.find('p').text(conflicts.length
                ? format(t('brand_voice_conflict', 'Conflict: {terms}.'), { terms: conflicts.join(', ') })
                : t('brand_voice_no_conflicts', 'No conflicts detected.')
            );
        },

        updateReview: function () {
            const voice = this.collectVoice();
            $('#fos-voice-review-name').text(voice.name || '—');
            $('#fos-voice-review-author').text(voice.persona.author || '—');
            $('#fos-voice-review-reader').text(voice.persona.reader || '—');
            $('#fos-voice-review-pov').text(this.getPovLabel(voice.rules.pov));
            $('#fos-voice-review-paragraph').text(this.getParagraphLabel(voice.rules.paragraph_len));
            $('#fos-voice-review-vocab').text(this.getVocabSummary());
            $('#fos-voice-review-samples').text(this.getSampleSummary(voice.samples));
            $('#fos-voice-samples-count').text(voice.samples.length + '/3');
            $('#fos-voice-tone-quote').text(this.getToneQuote());
        },

        renderRadar: function () {
            const values = TONE_FIELDS.map(id => parseInt($('#fos-voice-' + id).val(), 10) || 3);
            const labels = [
                t('brand_voice_radar_formality', 'Formality'),
                t('brand_voice_radar_technical', 'Technical'),
                t('brand_voice_radar_authority', 'Authority'),
                t('brand_voice_radar_opinion', 'Opinion'),
                t('brand_voice_radar_warmth', 'Warmth')
            ];
            const center = 100;
            const maxRadius = 68;
            const angles = [-90, -18, 54, 126, 198];

            const point = function (angle, radius) {
                const rad = (Math.PI / 180) * angle;
                return {
                    x: center + Math.cos(rad) * radius,
                    y: center + Math.sin(rad) * radius
                };
            };

            const rings = [1, 2, 3, 4, 5].map(level => {
                const radius = (maxRadius / 5) * level;
                return angles.map(angle => {
                    const p = point(angle, radius);
                    return p.x.toFixed(2) + ',' + p.y.toFixed(2);
                }).join(' ');
            });

            const polygon = values.map((value, index) => {
                const p = point(angles[index], (maxRadius / 5) * value);
                return p.x.toFixed(2) + ',' + p.y.toFixed(2);
            }).join(' ');

            const spokes = angles.map(angle => {
                const p = point(angle, maxRadius);
                return '<line x1="' + center + '" y1="' + center + '" x2="' + p.x.toFixed(2) + '" y2="' + p.y.toFixed(2) + '" />';
            }).join('');

            const labelNodes = labels.map((label, index) => {
                const p = point(angles[index], maxRadius + 19);
                return '<text x="' + p.x.toFixed(2) + '" y="' + p.y.toFixed(2) + '">' + label + '</text>';
            }).join('');

            const dots = values.map((value, index) => {
                const p = point(angles[index], (maxRadius / 5) * value);
                return '<circle cx="' + p.x.toFixed(2) + '" cy="' + p.y.toFixed(2) + '" r="3.5" />';
            }).join('');

            const svg = '' +
                '<svg viewBox="0 0 200 200" role="img" aria-label="' + t('brand_voice_radar_label', 'Voice DNA') + '">' +
                    '<g class="fos-voice-radar__grid">' +
                        rings.map(points => '<polygon points="' + points + '" />').join('') +
                        spokes +
                    '</g>' +
                    '<polygon class="fos-voice-radar__area" points="' + polygon + '" />' +
                    '<polyline class="fos-voice-radar__line" points="' + polygon + ' ' + polygon.split(' ')[0] + '" />' +
                    '<g class="fos-voice-radar__dots">' + dots + '</g>' +
                    '<g class="fos-voice-radar__labels">' + labelNodes + '</g>' +
                '</svg>';

            this.modal.find('.fos-voice-radar').html(svg);
        },

        getVocabularyConflicts: function () {
            const avoidMap = {};
            this.chips.avoid.forEach(item => {
                avoidMap[item.toLowerCase()] = true;
            });
            return this.chips.preferred.filter(item => avoidMap[item.toLowerCase()]);
        },

        getSamples: function () {
            const samples = [];
            this.modal.find('.fos-voice-sample-input').each(function () {
                const value = (this.value || '').trim();
                if (value) {
                    samples.push(value);
                }
            });
            return samples.slice(0, 3);
        },

        getSampleSummary: function (samples) {
            const count = (samples || []).length;
            if (!count) return '—';
            return count + ' ' + (count === 1 ? t('brand_voice_example_singular', 'example') : t('brand_voice_example_plural', 'examples'));
        },

        getToneSignature: function () {
            const formality = parseInt($('#fos-voice-formality').val(), 10) || 3;
            const technicality = parseInt($('#fos-voice-technicality').val(), 10) || 3;
            const warmth = parseInt($('#fos-voice-warmth').val(), 10) || 3;
            const opinion = parseInt($('#fos-voice-opinion').val(), 10) || 3;

            if (formality >= 5 && technicality >= 4) return t('brand_voice_signature_academic', 'Academic');
            if (formality >= 4 && warmth <= 3) return t('brand_voice_signature_professional', 'Professional');
            if (warmth >= 4 && formality <= 3) return t('brand_voice_signature_conversational', 'Conversational+');
            if (opinion >= 4) return t('brand_voice_signature_critical', 'Critical');
            return t('brand_voice_signature_balanced', 'Balanced');
        },

        getToneQuote: function () {
            const tone = this.getToneSignature();
            if (tone === t('brand_voice_signature_academic', 'Academic')) {
                return t('brand_voice_quote_academic', '“The analysis shows a consistent pattern: clear processes reduce rework and increase operational predictability.”');
            }
            if (tone === t('brand_voice_signature_professional', 'Professional')) {
                return t('brand_voice_quote_professional', '“The company can scale production with a clear process, the right metrics, and consistent review.”');
            }
            if (tone === t('brand_voice_signature_conversational', 'Conversational+')) {
                return t('brand_voice_quote_conversational', '“You can simplify it: choose the next step, measure what matters, and adjust without complicating the process.”');
            }
            if (tone === t('brand_voice_signature_critical', 'Critical')) {
                return t('brand_voice_quote_critical', '“The problem is not producing more. It is producing without method and calling volume strategy.”');
            }
            return t('brand_voice_quote_balanced', '“The path becomes clearer when strategy, process, and measurement move together.”');
        },

        getPovLabel: function (value) {
            const map = {
                first_plural: t('brand_voice_pov_first_plural', '1st person plural (We)'),
                second: t('brand_voice_pov_second', '2nd person (You)'),
                third: t('brand_voice_pov_third', '3rd person (Impersonal)')
            };
            return map[value] || map.third;
        },

        getParagraphLabel: function (value) {
            const map = {
                short: t('brand_voice_para_short', 'Short · 2-3 sentences'),
                medium: t('brand_voice_para_medium', 'Medium · 4-5 sentences'),
                long: t('brand_voice_para_long', 'Long · 6+ sentences')
            };
            return map[value] || map.medium;
        },

        getVocabSummary: function () {
            const preferred = this.chips.preferred.length;
            const avoid = this.chips.avoid.length;
            const signatures = this.chips.signatures.length;
            const replacements = this.replacements.length;
            if (!preferred && !avoid && !signatures && !replacements) return '—';
            return preferred + ' ' + t('brand_voice_prefer_short', 'prefer') +
                ' · ' + avoid + ' ' + t('brand_voice_avoid_short', 'avoid') +
                ' · ' + replacements + ' ' + t('brand_voice_subst_short', 'subst.') +
                ' · ' + signatures + ' ' + (signatures === 1 ? t('brand_voice_signature_singular', 'signature') : t('brand_voice_signature_plural', 'signatures'));
        }
    };

    $(document).ready(function () {
        BrandVoice.init();
    });

})(jQuery);
