<template>
    <Head :title="campaign.title || 'New Campaign'" />
    <CampaignEditorLayout>
        <!-- Step bar -->
        <div class="cw-stepbar">
            <button class="cw-back-btn" @click="router.visit(route('campaigns.index'))">
                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" width="16" height="16">
                    <path fill-rule="evenodd" d="M17 10a.75.75 0 01-.75.75H5.612l4.158 3.96a.75.75 0 11-1.04 1.08l-5.5-5.25a.75.75 0 010-1.08l5.5-5.25a.75.75 0 111.04 1.08L5.612 9.25H16.25A.75.75 0 0117 10z" clip-rule="evenodd"/>
                </svg>
                Campaigns
            </button>

            <div class="cw-steps">
                <button
                    v-for="(step, idx) in STEPS"
                    :key="step.key"
                    class="cw-step"
                    :class="{
                        'is-active': currentStep === step.key,
                        'is-done': doneSteps.has(step.key),
                    }"
                    @click="jumpToStep(step.key)"
                >
                    <span class="cw-step-num">
                        <svg v-if="doneSteps.has(step.key)" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" width="12" height="12">
                            <path fill-rule="evenodd" d="M16.704 4.153a.75.75 0 01.143 1.052l-8 10.5a.75.75 0 01-1.127.075l-4.5-4.5a.75.75 0 011.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 011.05-.143z" clip-rule="evenodd"/>
                        </svg>
                        <span v-else>{{ idx + 1 }}</span>
                    </span>
                    <span class="cw-step-label">{{ step.label }}</span>
                </button>
            </div>

            <div class="cw-stepbar-right">
                <span class="cw-campaign-title">{{ campaign.title }}</span>
                <span v-if="savedAt" class="cw-saved-indicator">
                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" width="13" height="13">
                        <path fill-rule="evenodd" d="M16.704 4.153a.75.75 0 01.143 1.052l-8 10.5a.75.75 0 01-1.127.075l-4.5-4.5a.75.75 0 011.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 011.05-.143z" clip-rule="evenodd"/>
                    </svg>
                    Saved
                </span>
                <span v-if="saving" class="cw-saving-indicator">Saving…</span>
            </div>
        </div>

        <!-- ──────────────────────────────────────────────────────── -->
        <!-- STEP 1: COMPOSE                                          -->
        <!-- ──────────────────────────────────────────────────────── -->
        <div v-show="currentStep === 'compose'" class="cw-step-panel">
            <!-- Toolbar -->
            <div class="cw-editor-toolbar">
                <div class="cw-toolbar-left">
                    <span class="cw-toolbar-label">
                        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.5" width="15" height="15">
                            <path d="M3 5h14M3 10h14M3 15h8"/>
                        </svg>
                        Email Body
                    </span>
                </div>
                <div class="cw-toolbar-right">
                    <button class="cw-tool-btn" title="Preview" @click="showPreview = true">
                        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" width="16" height="16">
                            <path d="M10 12.5a2.5 2.5 0 100-5 2.5 2.5 0 000 5z"/>
                            <path fill-rule="evenodd" d="M.664 10.59a1.651 1.651 0 010-1.186A10.004 10.004 0 0110 3c4.257 0 7.893 2.66 9.336 6.41.147.381.146.804 0 1.186A10.004 10.004 0 0110 17c-4.257 0-7.893-2.66-9.336-6.41zM14 10a4 4 0 11-8 0 4 4 0 018 0z" clip-rule="evenodd"/>
                        </svg>
                        Preview
                    </button>
                    <button class="cw-tool-btn" @click="saveCompose" :disabled="saving">
                        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" width="16" height="16">
                            <path d="M10.75 2.75a.75.75 0 00-1.5 0v8.614L6.295 8.235a.75.75 0 10-1.09 1.03l4.25 4.5a.75.75 0 001.09 0l4.25-4.5a.75.75 0 00-1.09-1.03l-2.955 3.129V2.75z"/>
                            <path d="M3.5 12.75a.75.75 0 00-1.5 0v2.5A2.75 2.75 0 004.75 18h10.5A2.75 2.75 0 0018 15.25v-2.5a.75.75 0 00-1.5 0v2.5c0 .69-.56 1.25-1.25 1.25H4.75c-.69 0-1.25-.56-1.25-1.25v-2.5z"/>
                        </svg>
                        Save
                    </button>
                    <button class="btn btn-primary btn-sm" @click="goToStep('subject')">
                        Continue
                        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" width="14" height="14">
                            <path fill-rule="evenodd" d="M3 10a.75.75 0 01.75-.75h10.638L10.23 5.29a.75.75 0 111.04-1.08l5.5 5.25a.75.75 0 010 1.08l-5.5 5.25a.75.75 0 11-1.04-1.08l4.158-3.96H3.75A.75.75 0 013 10z" clip-rule="evenodd"/>
                        </svg>
                    </button>
                </div>
            </div>

            <!-- Editor body: LEFT PANEL + CANVAS -->
            <!-- Email Editor Modular Component -->
            <EmailEditor v-model="blocks" :campaign-id="campaign.id" :global-settings="globalSettings" />
        </div>

        <!-- ──────────────────────────────────────────────────────── -->
        <!-- STEP 2: SUBJECT & SETTINGS                              -->
        <!-- ──────────────────────────────────────────────────────── -->
        <div v-show="currentStep === 'subject'" class="cw-step-panel cw-step-panel--scroll">
            <div class="cw-content-area">

                <!-- ── Email Subject Card ── -->
                <div class="ss-card">
                    <!-- Subject input -->
                    <div class="ss-field-group">
                        <div class="ss-field-label">Email Subject</div>
                        <div class="ss-input-wrap">
                            <input
                                v-model="subjectForm.email_subject"
                                type="text"
                                class="ss-input"
                                placeholder="e.g. Big news! Our summer sale is here"
                            />
                            <button class="ss-merge-btn" type="button" title="Insert merge tag">···</button>
                        </div>
                        <p v-if="subjectForm.ab_test" class="ss-ab-warning">
                            This subject will not be used to send emails. Please set A/B testing subjects
                        </p>
                    </div>

                    <!-- A/B checkbox -->
                    <label class="ss-checkbox-row">
                        <input type="checkbox" v-model="subjectForm.ab_test" class="ss-checkbox" />
                        <span class="ss-checkbox-label">Enable A/B testing for email subjects</span>
                    </label>

                    <!-- A/B subjects table -->
                    <template v-if="subjectForm.ab_test">
                        <p class="ss-ab-hint">Your provided priority will be converted to percent and it's relative</p>
                        <div class="ss-ab-table-wrap">
                            <table class="ss-ab-table">
                                <thead>
                                    <tr>
                                        <th>Subject</th>
                                        <th>Priority (%)</th>
                                        <th>Actions</th>
                                    </tr>
                                </thead>
                                <tbody>
                                    <tr v-for="(row, idx) in subjectForm.ab_subjects" :key="row.id">
                                        <td>
                                            <div class="ss-input-wrap">
                                                <input v-model="row.subject" type="text" class="ss-input" placeholder="Subject Test 1" />
                                                <button class="ss-merge-btn" type="button">···</button>
                                            </div>
                                        </td>
                                        <td>
                                            <div class="ss-stepper">
                                                <button class="ss-stepper-btn" type="button" @click="adjustPriority(idx, -1)">−</button>
                                                <input type="number" class="ss-stepper-input" v-model.number="row.priority" min="1" max="100" />
                                                <button class="ss-stepper-btn" type="button" @click="adjustPriority(idx, 1)">+</button>
                                            </div>
                                        </td>
                                        <td>
                                            <button class="ss-delete-btn" type="button" @click="removeAbSubject(idx)" title="Remove">
                                                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" width="14" height="14">
                                                    <path fill-rule="evenodd" d="M8.75 1A2.75 2.75 0 006 3.75v.443c-.795.077-1.584.176-2.365.298a.75.75 0 10.23 1.482l.149-.022.841 10.518A2.75 2.75 0 007.596 19h4.807a2.75 2.75 0 002.742-2.53l.841-10.52.149.023a.75.75 0 00.23-1.482A41.03 41.03 0 0014 4.193V3.75A2.75 2.75 0 0011.25 1h-2.5zM10 4c.84 0 1.673.025 2.5.075V3.75c0-.69-.56-1.25-1.25-1.25h-2.5c-.69 0-1.25.56-1.25 1.25v.325C8.327 4.025 9.16 4 10 4zM8.58 7.72a.75.75 0 00-1.5.06l.3 7.5a.75.75 0 101.5-.06l-.3-7.5zm4.34.06a.75.75 0 10-1.5-.06l-.3 7.5a.75.75 0 101.5.06l.3-7.5z" clip-rule="evenodd"/>
                                                </svg>
                                            </button>
                                        </td>
                                    </tr>
                                </tbody>
                            </table>
                            <div class="ss-ab-footer">
                                <button class="ss-add-more-btn" type="button" @click="addAbSubject">Add More</button>
                            </div>
                        </div>
                    </template>

                    <!-- Pre-Header -->
                    <div class="ss-field-group ss-mt">
                        <div class="ss-field-label">Email Pre-Header</div>
                        <input v-model="subjectForm.email_pre_header" type="text" class="ss-plain-input" placeholder="Preview text shown in inbox..." />
                    </div>
                </div>

                <!-- ── Sender Identity Card ── -->
                <div class="ss-card" style="overflow:visible">
                    <div class="ss-card-hdr">
                        <div class="ss-card-hdr-title">
                            <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.8" stroke="currentColor" width="16" height="16"><path stroke-linecap="round" stroke-linejoin="round" d="M15.75 6a3.75 3.75 0 11-7.5 0 3.75 3.75 0 017.5 0zM4.501 20.118a7.5 7.5 0 0114.998 0A17.933 17.933 0 0112 21.75c-2.676 0-5.216-.584-7.499-1.632z"/></svg>
                            Sender Identity
                        </div>
                        <p class="ss-card-hdr-desc">Emails are sent using the From details of your selected SMTP profile.</p>
                    </div>

                    <!-- SMTP Router Selector -->
                    <div v-if="smtpConfigs.length > 0" class="ss-field-group" style="margin-bottom:16px">
                        <div class="ss-field-label">SMTP Routing Profile</div>
                        <CwSelect v-model="subjectForm.smtp_config_id" :options="smtpOptions" @change="saveSubject" />
                    </div>

                    <!-- Selected Sender details -->
                    <div v-if="selectedSmtpConfig" class="ss-profile-list">
                        <div class="ss-profile-option is-selected">
                            <div class="ss-profile-avatar">{{ initials(selectedSmtpConfig.from_name || selectedSmtpConfig.from_email) }}</div>
                            <div class="ss-profile-info">
                                <div class="ss-profile-name">{{ selectedSmtpConfig.from_name || selectedSmtpConfig.from_email }}</div>
                                <div class="ss-profile-email">{{ selectedSmtpConfig.from_email }}</div>
                            </div>
                            <span class="ss-verified-badge">
                                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" width="12" height="12"><path fill-rule="evenodd" d="M16.704 4.153a.75.75 0 01.143 1.052l-8 10.5a.75.75 0 01-1.127.075l-4.5-4.5a.75.75 0 011.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 011.05-.143z" clip-rule="evenodd"/></svg>
                                {{ selectedSmtpConfig.name }}
                            </span>
                        </div>
                    </div>
                    <div v-else class="ss-no-profiles">
                        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="20" height="20"><path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126zM12 15.75h.007v.008H12v-.008z"/></svg>
                        <span>No SMTP profile selected or configured. Set up an <a :href="route('smtp.index')" class="ss-link">SMTP profile</a> first.</span>
                    </div>

                    <!-- Reply-to override (optional) -->
                    <div class="ss-reply-override">
                        <div class="ss-field-label" style="margin-bottom:6px">Reply-to email <span style="font-weight:400;color:#9ca3af">(optional)</span></div>
                        <input v-model="subjectForm.reply_to_email" type="email" class="ss-plain-input" placeholder="Leave blank to receive replies at the sender address" />
                    </div>
                </div>

                <!-- ── UTM Card ── -->
                <div class="ss-card">
                    <label class="ss-checkbox-row">
                        <input type="checkbox" v-model="subjectForm.utm_status" class="ss-checkbox" />
                        <span class="ss-checkbox-label">Add UTM Parameters For URLs</span>
                    </label>

                    <template v-if="subjectForm.utm_status">
                        <div class="ss-utm-grid">
                            <div class="ss-field-group">
                                <div class="ss-field-label">Campaign Source <span class="ss-required">(required)</span></div>
                                <input v-model="subjectForm.utm_source" type="text" class="ss-plain-input" placeholder="The referrer: (e.g. google, newsletter)" />
                            </div>
                            <div class="ss-field-group">
                                <div class="ss-field-label">Campaign Medium <span class="ss-required">(required)</span></div>
                                <input v-model="subjectForm.utm_medium" type="text" class="ss-plain-input" placeholder="Marketing medium: (e.g. cpc, banner, email)" />
                            </div>
                            <div class="ss-field-group">
                                <div class="ss-field-label">Campaign Name <span class="ss-required">(required)</span></div>
                                <input v-model="subjectForm.utm_campaign" type="text" class="ss-plain-input" placeholder="Product, promo code, or slogan (e.g. spring_sale)" />
                            </div>
                            <div class="ss-field-group">
                                <div class="ss-field-label">Campaign Term</div>
                                <input v-model="subjectForm.utm_term" type="text" class="ss-plain-input" placeholder="Identify the paid keywords" />
                            </div>
                            <div class="ss-field-group">
                                <div class="ss-field-label">Campaign Content</div>
                                <input v-model="subjectForm.utm_content" type="text" class="ss-plain-input" placeholder="Use to differentiate ads" />
                            </div>
                        </div>
                    </template>

                    <button class="ss-test-btn" type="button" @click="sendTestEmail">Send a test email</button>
                </div>

                <div class="cw-step-actions">
                    <button class="btn btn-ghost" @click="goToStep('compose')">Back</button>
                    <button class="btn btn-primary" @click="goToStep('recipients')">Continue</button>
                </div>
            </div>
        </div>

        <!-- ──────────────────────────────────────────────────────── -->
        <!-- STEP 3: RECIPIENTS                                       -->
        <!-- ──────────────────────────────────────────────────────── -->
        <div v-show="currentStep === 'recipients'" class="cw-step-panel cw-step-panel--scroll">
            <div class="cw-content-area">

                <!-- Segment type tabs -->
                <div class="cw-recipients-tabs">
                    <div class="cw-recipients-tab" :class="{ 'is-active': recipientsMode === 'list_tag' }" @click="recipientsMode = 'list_tag'">By List &amp; Tag</div>
                    <div class="cw-recipients-tab" :class="{ 'is-active': recipientsMode === 'advanced_filter' }" @click="recipientsMode = 'advanced_filter'">By Advanced Filter</div>
                </div>

                <!-- By Advanced Filter -->
                <div v-if="recipientsMode === 'advanced_filter'" class="cw-incl-card">
                    <div class="cw-incl-card-hdr">
                        <h4>Advanced Filter</h4>
                        <p>Build conditions against contact properties, email engagement, and tags/lists/status. Groups are combined with OR; conditions inside a group are combined with AND.</p>
                    </div>
                    <AdvancedFilterBuilder
                        ref="filterBuilderRef"
                        v-model="filterTree"
                        :menu="filterFieldMenu"
                        :lists="lists"
                        :tags="tags"
                        :campaigns="campaigns"
                        :automations="automations"
                        @apply="fetchRecipientCount"
                    />
                </div>

                <!-- Included Contacts -->
                <div v-if="recipientsMode === 'list_tag'" class="cw-incl-card">
                    <div class="cw-incl-card-hdr">
                        <h4>Included Contacts</h4>
                        <p>Select Lists and Tags that you want to send emails for this campaign. You can create multiple rows to send to all of them.</p>
                    </div>
                    <table class="cw-incl-table">
                        <thead>
                            <tr>
                                <th>Select A List</th>
                                <th>Select Tag</th>
                                <th>Actions</th>
                            </tr>
                        </thead>
                        <tbody>
                            <tr v-for="(row, idx) in recipientsForm.included" :key="'inc-'+idx" class="cw-incl-row">
                                <td>
                                    <CwSelect
                                        v-model="row.list_id"
                                        :options="listOptions"
                                        @change="row.tag_id = ''"
                                    />
                                </td>
                                <td>
                                    <CwSelect
                                        v-model="row.tag_id"
                                        :options="tagOptionsForList(row.list_id)"
                                    />
                                </td>
                                <td>
                                    <div class="cw-incl-actions">
                                        <button class="cw-incl-act" @click="addIncluded" title="Add row">+</button>
                                        <button class="cw-incl-act" @click="removeIncluded(idx)" :disabled="recipientsForm.included.length === 1" title="Remove row">−</button>
                                    </div>
                                </td>
                            </tr>
                        </tbody>
                    </table>
                    <div class="cw-incl-hint">
                        <span>Select List or all subscribers first and then select tag</span>
                    </div>
                </div>

                <!-- Excluded Contacts -->
                <div v-if="recipientsMode === 'list_tag'" class="cw-incl-card">
                    <div class="cw-incl-card-hdr">
                        <h4>Excluded Contacts</h4>
                        <p>Select Lists and Tags that you want to exclude from this campaign. Excluded contacts will be subtracted from your included selection.</p>
                    </div>
                    <table class="cw-incl-table">
                        <thead>
                            <tr>
                                <th>Select A List</th>
                                <th>Select Tag</th>
                                <th>Actions</th>
                            </tr>
                        </thead>
                        <tbody>
                            <tr v-for="(row, idx) in recipientsForm.excluded" :key="'exc-'+idx" class="cw-incl-row">
                                <td>
                                    <CwSelect
                                        v-model="row.list_id"
                                        :options="exclusionListOptions"
                                        @change="row.tag_id = ''"
                                    />
                                </td>
                                <td>
                                    <CwSelect
                                        v-model="row.tag_id"
                                        :options="tagOptionsForList(row.list_id, true)"
                                        :disabled="!row.list_id"
                                    />
                                </td>
                                <td>
                                    <div class="cw-incl-actions">
                                        <button class="cw-incl-act" @click="addExcluded" title="Add row">+</button>
                                        <button class="cw-incl-act" @click="removeExcluded(idx)" title="Remove row">−</button>
                                    </div>
                                </td>
                            </tr>
                            <tr v-if="recipientsForm.excluded.length === 0">
                                <td colspan="3" class="cw-excl-empty-cell">
                                    <button class="cw-excl-add-btn" @click="addExcluded">
                                        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" width="13" height="13">
                                            <path d="M10.75 4.75a.75.75 0 00-1.5 0v4.5h-4.5a.75.75 0 000 1.5h4.5v4.5a.75.75 0 001.5 0v-4.5h4.5a.75.75 0 000-1.5h-4.5v-4.5z"/>
                                        </svg>
                                        Add exclusion rule
                                    </button>
                                </td>
                            </tr>
                        </tbody>
                    </table>
                </div>

                <!-- Contact count badge -->
                <div style="text-align:center;padding:8px 0 20px">
                    <span class="recipient-count-badge" :class="{ 'is-loading': countingRecipients }">
                        <svg v-if="countingRecipients" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="14" height="14" class="cw-spin">
                            <path d="M12 2v4M12 18v4M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M2 12h4M18 12h4M4.93 19.07l2.83-2.83M16.24 7.76l2.83-2.83"/>
                        </svg>
                        <svg v-else xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" style="width:14px;height:14px"><path stroke-linecap="round" stroke-linejoin="round" d="M15 19.128a9.38 9.38 0 002.625.372 9.337 9.337 0 004.121-.952 4.125 4.125 0 00-7.533-2.493M15 19.128v-.003c0-1.113-.285-2.16-.786-3.07M15 19.128v.106A12.318 12.318 0 018.624 21c-2.331 0-4.512-.645-6.374-1.766l-.001-.109a6.375 6.375 0 0111.964-3.07M12 6.375a3.375 3.375 0 11-6.75 0 3.375 3.375 0 016.75 0zm8.25 2.25a2.625 2.625 0 11-5.25 0 2.625 2.625 0 015.25 0z"/></svg>
                        <span class="recipient-count-badge-num">{{ totalRecipients }}</span>
                        contacts found based on your selection
                    </span>
                </div>

                <!-- Navigation -->
                <div class="cw-step-nav">
                    <button class="cw-nav-back" @click="goToStep('subject')">Back</button>
                    <button class="cw-nav-continue" @click="goToStep('review')">
                        Continue To Next Step [Review and Send]
                        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" width="14" height="14">
                            <path stroke-linecap="round" stroke-linejoin="round" d="M13.5 4.5L21 12m0 0l-7.5 7.5M21 12H3"/>
                        </svg>
                    </button>
                </div>
            </div>
        </div>

        <!-- ──────────────────────────────────────────────────────── -->
        <!-- STEP 4: REVIEW & SEND                                    -->
        <!-- ──────────────────────────────────────────────────────── -->
        <div v-show="currentStep === 'review'" class="cw-step-panel cw-step-panel--scroll">
            <div class="cw-content-area">
                <!-- Top Back link -->
                <div style="max-width: 800px; margin: 0 auto 16px; display: flex; justify-content: flex-start;">
                    <button class="cw-nav-back" @click="goToStep('recipients')" style="display: inline-flex; align-items: center; gap: 4px;">
                        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2.5" stroke="currentColor" style="width:12px; height:12px;"><path stroke-linecap="round" stroke-linejoin="round" d="M15.75 19.5L8.25 12l7.5-7.5" /></svg>
                        Back
                    </button>
                </div>
                <div class="cw-content-card">

                    <!-- Recipients row -->
                    <div class="cw-review-section">
                        <div>
                            <div class="cw-review-lbl">Recipients</div>
                            <div class="cw-review-val">
                                Total: <strong>{{ totalRecipients }} Recipient{{ totalRecipients !== 1 ? 's' : '' }}</strong>
                            </div>
                        </div>
                        <button class="cw-review-edit" @click="goToStep('recipients')">Edit Recipients</button>
                    </div>

                    <!-- Subject row -->
                    <div class="cw-review-section">
                        <div>
                            <div class="cw-review-lbl">Subject</div>
                            <div class="cw-review-val">{{ subjectForm.email_subject || '(not set)' }}</div>
                            <div v-if="subjectForm.email_pre_header" class="cw-review-subval">Preview Text: {{ subjectForm.email_pre_header }}</div>
                        </div>
                        <button class="cw-review-edit" @click="goToStep('subject')">Edit Subject</button>
                    </div>

                    <!-- Email Body row -->
                    <div class="cw-review-section">
                        <div style="width:100%">
                            <div class="cw-review-lbl" style="margin-bottom:12px">Email Body</div>
                            <div class="cw-email-preview-card" @click="showPreview = true" title="Click to view full preview">
                                <!-- Browser/Mail client header mockup -->
                                <div style="display: flex; align-items: center; justify-content: space-between; padding: 10px 16px; background: #f3f4f6; border-bottom: 1px solid #e5e7eb; user-select: none;">
                                    <div style="display: flex; gap: 6px; align-items: center;">
                                        <span style="width: 8px; height: 8px; border-radius: 50%; background: #ef4444; display: inline-block;"></span>
                                        <span style="width: 8px; height: 8px; border-radius: 50%; background: #f59e0b; display: inline-block;"></span>
                                        <span style="width: 8px; height: 8px; border-radius: 50%; background: #10b981; display: inline-block;"></span>
                                    </div>
                                    <div style="font-size: 11px; font-weight: 600; color: #6b7280; text-transform: uppercase; letter-spacing: 0.05em;">Email Client Preview</div>
                                    <div style="width: 36px;"></div> <!-- spacer to balance the dots -->
                                </div>
                                
                                <!-- Mail content container with max-height and scrolling -->
                                <div style="max-height: 280px; overflow-y: auto; position: relative;">
                                    <div v-if="blocks.length === 0" style="font-size: 14px; color: #9ca3af; text-align: center; padding: 48px 24px; background: #ffffff;">
                                        Start Writing Here
                                    </div>
                                    <div v-else v-html="previewHtml"></div>
                                </div>

                                <!-- Fade overlay to suggest scrolling/expand -->
                                <div v-if="blocks.length > 0" style="position: absolute; bottom: 0; left: 0; right: 0; height: 60px; background: linear-gradient(to top, rgba(255,255,255,0.95) 0%, rgba(255,255,255,0) 100%); pointer-events: none; display: flex; align-items: flex-end; justify-content: center; padding-bottom: 8px;">
                                    <span class="cw-email-preview-expand-badge">
                                        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2.5" stroke="currentColor" style="width:12px; height:12px;"><path stroke-linecap="round" stroke-linejoin="round" d="M3.75 3.75v4.5m0-4.5h4.5m-4.5 0L9 9M3.75 20.25v-4.5m0 4.5h4.5m-4.5 0L9 15M20.25 3.75v4.5m0-4.5h-4.5m4.5 0L15 9m5.25 11.25v-4.5m0 4.5h-4.5m4.5 0L15 15" /></svg>
                                        Click to Expand Preview
                                    </span>
                                </div>
                            </div>
                            <div style="padding:8px 2px ; display:flex; gap:12px;">
                                <button class="cw-test-btn" @click="openTestEmailModal" style="margin-top:0">
                                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.8" stroke="currentColor" style="width:14px;height:14px">
                                        <path stroke-linecap="round" stroke-linejoin="round" d="M6 12L3.269 3.126A59.768 59.768 0 0121.485 12 59.77 59.77 0 013.27 20.876L5.999 12zm0 0h7.5"/>
                                    </svg>
                                    Send a test email
                                </button>
                                <button class="cw-test-btn" @click="showPreview = true" style="margin-top:0">
                                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.8" stroke="currentColor" style="width:14px;height:14px">
                                        <path stroke-linecap="round" stroke-linejoin="round" d="M2.036 12.322a1.012 1.012 0 010-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.43 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178z"/>
                                        <path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/>
                                    </svg>
                                    Preview Email
                                </button>
                            </div>
                        </div>
                        <button class="cw-review-edit" style="flex-shrink:0;align-self:flex-start" @click="goToStep('compose')">Edit Email Body</button>
                    </div>

                    <!-- Broadcast/Schedule section -->
                    <div class="cw-schedule-section">
                        <div class="cw-schedule-title">Broadcast/Schedule This Email Campaign Now</div>
                        <div class="cw-schedule-desc">If you think everything is alright. You can broadcast/Schedule the emails now.</div>
                        <div class="cw-schedule-divider"></div>

                        <div class="cw-schedule-body">
                            <!-- Left: mode selector -->
                            <div class="cw-schedule-left">
                                <div class="cw-schedule-q">When you send the emails?</div>
                                <label class="cw-radio-item">
                                    <input type="radio" v-model="sendMode" value="now" />
                                    <span :class="sendMode === 'now' ? 'cw-radio-active' : ''">Send the emails right now</span>
                                </label>
                                <label class="cw-radio-item">
                                    <input type="radio" v-model="sendMode" value="schedule" />
                                    <span :class="sendMode === 'schedule' ? 'cw-radio-active' : ''">Schedule the emails</span>
                                </label>
                                <label class="cw-radio-item">
                                    <input type="radio" v-model="sendMode" value="range" />
                                    <span :class="sendMode === 'range' ? 'cw-radio-active' : ''">Schedule emails within a specified date-time range</span>
                                </label>
                            </div>

                            <!-- Right: time picker panel -->
                            <div class="cw-schedule-right" v-if="sendMode !== 'now'">
                                <!-- Schedule single time -->
                                <template v-if="sendMode === 'schedule'">
                                    <div class="cw-schedule-field-label">Please set date and time</div>
                                    <CwDateTimePicker v-model="scheduledAt" placeholder="Choose date & time" align="right" />
                                    <div class="cw-server-time">
                                        Current time in your account timezone ({{ tenantTimezone }}): <code>{{ serverTime }}</code>
                                    </div>
                                </template>
                                <!-- Range -->
                                <template v-if="sendMode === 'range'">
                                    <div class="cw-schedule-field-label">Select Date &amp; Time Range that you want to send the emails</div>
                                    <div class="cw-dt-range-row">
                                        <CwDateTimePicker v-model="rangeStart" placeholder="Start date & time" align="left" />
                                        <span class="cw-dt-sep">–</span>
                                        <CwDateTimePicker v-model="rangeEnd" placeholder="End date & time" align="right" />
                                    </div>
                                    <div class="cw-schedule-hint">Emails will be spread evenly across the selected time range</div>
                                    <div class="cw-server-time">
                                        Current time in your account timezone ({{ tenantTimezone }}): <code>{{ serverTime }}</code>
                                    </div>
                                </template>
                            </div>
                        </div>

                        <!-- Success/Error feedback -->
                        <div v-if="broadcastSuccess" class="cw-broadcast-success">
                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" width="16" height="16"><path fill-rule="evenodd" d="M16.704 4.153a.75.75 0 01.143 1.052l-8 10.5a.75.75 0 01-1.127.075l-4.5-4.5a.75.75 0 011.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 011.05-.143z" clip-rule="evenodd"/></svg>
                            {{ broadcastMessage }}
                        </div>
                        <div v-if="broadcastError" class="cw-broadcast-error">{{ broadcastError }}</div>

                        <!-- Action buttons -->
                        <div class="cw-schedule-actions">
                            <button class="cw-draft-btn" @click="saveAll" :disabled="saving || broadcasting">
                                <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" width="15" height="15"><path stroke-linecap="round" stroke-linejoin="round" d="M6 12L3.269 3.126A59.768 59.768 0 0121.485 12 59.77 59.77 0 013.27 20.876L5.999 12zm0 0h7.5"/></svg>
                                <span v-if="saving">Saving…</span>
                                <span v-else>Save as Draft</span>
                            </button>
                            <button class="cw-send-btn" @click="doBroadcast" :disabled="saving || broadcasting || broadcastSuccess">
                                <svg v-if="broadcasting" xmlns="http://www.w3.org/2000/svg" class="cw-spin" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="15" height="15"><path d="M12 2v4M12 18v4M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M2 12h4M18 12h4M4.93 19.07l2.83-2.83M16.24 7.76l2.83-2.83"/></svg>
                                <svg v-else xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" width="15" height="15"><path stroke-linecap="round" stroke-linejoin="round" d="M6 12L3.269 3.126A59.768 59.768 0 0121.485 12 59.77 59.77 0 013.27 20.876L5.999 12zm0 0h7.5"/></svg>
                                <span v-if="broadcasting">Processing…</span>
                                <span v-else-if="sendMode === 'now'">Send Emails Now</span>
                                <span v-else>Schedule this campaign</span>
                            </button>
                        </div>
                    </div>
                </div>

                <!-- Back link -->
                <div style="max-width:760px;margin:16px auto 0;padding-bottom:32px">
                    <button class="cw-nav-back" @click="goToStep('recipients')">Back</button>
                </div>
            </div>
        </div>

        <!-- Preview modal -->
        <div v-if="showPreview" class="modal-overlay is-open" @click.self="showPreview = false">
            <div class="modal modal--lg">
                <div class="modal-header">
                    <h3 class="modal-title">Email Preview</h3>
                    <button class="modal-close" @click="showPreview = false">
                        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" width="18" height="18">
                            <path d="M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z"/>
                        </svg>
                    </button>
                </div>
                <div class="modal-body cw-preview-body">
                    <div class="cw-preview-email">
                        <div v-if="blocks.length === 0" style="color:#9ca3af;text-align:center;padding:40px 0">No blocks added yet.</div>
                        <div v-else v-html="previewHtml"></div>
                    </div>
                </div>
            </div>
        </div>


        <!-- ── Test Email Modal ── -->
        <div v-if="showTestEmailModal" class="modal-overlay is-open" @click.self="closeTestModal">
            <div class="modal" style="max-width:420px;width:100%">
                <div class="modal-header">
                    <span class="modal-title">Send a Test Email</span>
                    <button class="modal-close" @click="closeTestModal">✕</button>
                </div>
                <div class="modal-body" style="padding:20px">
                    <p style="font-size:13px;color:#6b7280;margin:0 0 14px">
                        Send this campaign as a test to any email address to preview how it looks in an inbox.
                    </p>
                    <label style="font-size:12px;font-weight:600;color:#374151;display:block;margin-bottom:6px">Recipient email address</label>
                    <input
                        v-model="testEmailAddress"
                        type="email"
                        placeholder="you@example.com"
                        class="cw-field-input"
                        style="height:38px;font-size:13px;width:100%;box-sizing:border-box"
                        @keydown.enter="doSendTestEmail"
                        ref="testEmailInputRef"
                    />
                    <p v-if="testEmailError" style="font-size:12px;color:#dc2626;margin:6px 0 0">{{ testEmailError }}</p>
                    <p v-if="testEmailSuccess" style="font-size:12px;color:#16a34a;margin:6px 0 0">{{ testEmailSuccess }}</p>
                </div>
                <div class="modal-footer" style="display:flex;justify-content:flex-end;gap:8px;padding:12px 16px;border-top:1px solid #e5e7eb">
                    <button class="btn btn--ghost" @click="closeTestModal">Cancel</button>
                    <button class="btn btn--primary" @click="doSendTestEmail" :disabled="testEmailSending">
                        <svg v-if="testEmailSending" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="13" height="13" class="cw-spin">
                            <path d="M12 2v4M12 18v4M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M2 12h4M18 12h4M4.93 19.07l2.83-2.83M16.24 7.76l2.83-2.83"/>
                        </svg>
                        {{ testEmailSending ? 'Sending…' : 'Send Test' }}
                    </button>
                </div>
            </div>
        </div>

    </CampaignEditorLayout>
</template>

<script setup>
import { ref, reactive, computed, watch, onMounted, onUnmounted, nextTick } from 'vue';
import { router, Head, usePage } from '@inertiajs/vue3';
import { zonedTimeToUtcIso, formatInTimeZone, nowInTimeZone } from '@/utils/timezone';
import draggable from 'vuedraggable';
import EmailEditor from '@/Components/EmailEditor/EmailEditor.vue';
import CampaignEditorLayout from '@/Layouts/CampaignEditorLayout.vue';
import CwColorPicker from '@/Components/CwColorPicker.vue';
import CwDateTimePicker from '@/Components/CwDateTimePicker.vue';
import CwSelect from '@/Components/CwSelect.vue';
import AdvancedFilterBuilder from '@/Components/AdvancedFilterBuilder.vue';

const props = defineProps({
    campaign:        Object,
    lists:           Array,
    tags:            Array,
    defaultSender:   Object,
    smtpConfigs:     { type: Array, default: () => [] },
    campaigns:       { type: Array, default: () => [] },
    automations:     { type: Array, default: () => [] },
    filterFieldMenu: { type: Array, default: () => [] }, 
    globalSettings: { type: Object, default: () => ({}) },
});


function defaultStyles(type) {
    const base = {
        paddingTop: 16, paddingRight: 24, paddingBottom: 16, paddingLeft: 24,
        marginTop: 0, marginRight: 0, marginBottom: 0, marginLeft: 0,
        fontSize: 14, lineHeight: 1.6, color: '#374151', textAlign: 'left',
        blockAlign: 'left', width: 100,
        bgColor: '', bgImageUrl: '',
        borderRadius: 0,
        borderWidth: 0, borderColor: '#e5e7eb', borderAllSides: true,
    };
    const overrides = {
        heading: { paddingTop: 20, paddingRight: 24, paddingBottom: 12, paddingLeft: 24, fontSize: 24, lineHeight: 1.3, color: '#111827', textAlign: 'left', fontWeight: 700 },
        button:  { paddingTop: 16, paddingRight: 24, paddingBottom: 16, paddingLeft: 24, fontSize: 15, textAlign: 'center', blockAlign: 'center', backgroundColor: '#4285F4', textColor: '#ffffff', borderRadius: 6 },
        divider: { paddingTop: 8, paddingRight: 0, paddingBottom: 8, paddingLeft: 0, borderColor: '#e5e7eb', borderWidth: 0, borderStyle: 'solid', dividerThickness: 1 },
        spacer:  { paddingTop: 0, paddingRight: 0, paddingBottom: 0, paddingLeft: 0, height: 24 },
        image:   { paddingTop: 8, paddingRight: 0, paddingBottom: 8, paddingLeft: 0, textAlign: 'center', width: 100 },
        social:  { paddingTop: 16, paddingRight: 24, paddingBottom: 16, paddingLeft: 24, textAlign: 'center' },
        footer:  { paddingTop: 16, paddingRight: 24, paddingBottom: 16, paddingLeft: 24, fontSize: 11, color: '#81868E', textAlign: 'center', blockAlign: 'center', lineHeight: 1.6, bgColor: '#f9fafb' },
        logo:    { paddingTop: 16, paddingRight: 24, paddingBottom: 16, paddingLeft: 24, blockAlign: 'center', textAlign: 'center', width: 50, fontFamily: 'sans-serif', fontWeight: 'bold', fontSize: 24, color: '#333333' },
    };
    return { ...base, ...(overrides[type] ?? {}) };
}

// ── State ──────────────────────────────────────────────────────────────────
const currentStep    = ref('compose');
const STEPS = [
    { key: 'compose',    label: 'Compose' },
    { key: 'subject',    label: 'Subject & Settings' },
    { key: 'recipients', label: 'Recipients' },
    { key: 'review',     label: 'Review & Send' },
];
const doneSteps       = ref(new Set());
const saving          = ref(false);

// ── Select Options ─────────────────────────────────────────────────────────
const listOptions = computed(() => {
    return [
        { value: '', label: 'All Lists' },
        ...props.lists.map(l => ({
            value: l.id,
            label: `${l.title} (${l.contacts_count ?? 0})`
        }))
    ];
});

const exclusionListOptions = computed(() => {
    return [
        { value: '', label: 'Choose a List' },
        ...props.lists.map(l => ({
            value: l.id,
            label: `${l.title} (${l.contacts_count ?? 0})`
        }))
    ];
});

function tagOptionsForList(listId, isExclusion = false) {
    const defaultLabel = isExclusion 
        ? (listId ? 'All contacts' : 'Select List First')
        : 'All contacts on Selected List segment';
    return [
        { value: '', label: defaultLabel },
        ...tagsForList(listId).map(t => ({
            value: t.id,
            label: `${t.title} (${t.contacts_count ?? 0})`
        }))
    ];
}

// ── Sender identity helpers ──────────────────────────────────────────────────
function initials(name) {
    return (name || '?').split(/\s+/).slice(0, 2).map(w => w[0]?.toUpperCase() ?? '').join('');
}
const savedAt         = ref(null);
const showPreview     = ref(false);
const previewDevice   = ref('desktop');

const COLUMN_PALETTE_PRESETS = [
    { label: '1', columnCount: 1, colWidths: [100] },
    { label: '2', columnCount: 2, colWidths: [50, 50] },
    { label: '3', columnCount: 3, colWidths: [33.3, 33.3, 33.3] },
    { label: '4', columnCount: 4, colWidths: [25, 25, 25, 25] },
    { label: '1:2', columnCount: 2, colWidths: [33.3, 66.7] },
    { label: '2:1', columnCount: 2, colWidths: [66.7, 33.3] },
    { label: '1:3', columnCount: 2, colWidths: [25, 75] },
    { label: '3:1', columnCount: 2, colWidths: [75, 25] }
];

function makeColumnPresetBlock(preset) {
    const columns = Array.from({ length: preset.columnCount }, () => ({
        id: crypto.randomUUID(),
        blocks: []
    }));
    return {
        id: crypto.randomUUID(),
        type: 'column',
        columnCount: preset.columnCount,
        colWidths: preset.colWidths,
        styles: defaultStyles('column'),
        columns: columns
    };
}

function setColumnPreset(block, preset) {
    block.columnCount = preset.columnCount;
    block.colWidths = preset.colWidths;
    const targetCount = preset.columnCount;
    while (block.columns.length < targetCount) {
        block.columns.push({ id: crypto.randomUUID(), blocks: [] });
    }
    while (block.columns.length > targetCount) {
        block.columns.pop();
    }
    saveHistory();
}

// ── Preview HTML renderer ─────────────────────────────────────────────────────
function renderPreviewBlock(block) {
    const s   = block.styles || {};
    // Match blockContentStyle() defaults exactly: padding 16/24, not 8/16
    const pt  = s.paddingTop    ?? 16;
    const pr  = s.paddingRight  ?? 24;
    const pb  = s.paddingBottom ?? 16;
    const pl  = s.paddingLeft   ?? 24;
    let wrap = `padding:${pt}px ${pr}px ${pb}px ${pl}px;`;
    if (s.width && s.width !== 'auto' && block.type !== 'button' && block.type !== 'logo') {
        const wVal = parseInt(s.width);
        if (wVal < 100) {
            wrap += `width:${wVal}%;`;
            const align = s.blockAlign || s.textAlign || 'left';
            if (align === 'center') {
                wrap += 'margin-left:auto;margin-right:auto;';
            } else if (align === 'right') {
                wrap += 'margin-left:auto;margin-right:0;';
            } else {
                wrap += 'margin-left:0;margin-right:auto;';
            }
        } else {
            wrap += 'width:100%;';
        }
    }
    if (s.bgColor)      wrap += `background:${s.bgColor};`;
    if (s.bgImageUrl)   wrap += `background-image:url(${s.bgImageUrl});background-size:cover;`;
    if (s.borderRadius) wrap += `border-radius:${s.borderRadius}px;`;
    if (s.borderWidth) wrap += `border:${s.borderWidth}px solid ${s.borderColor || '#e5e7eb'};`;

    switch (block.type) {
        case 'text': {
            const color   = s.color      || '#374151';
            const size    = s.fontSize   || 14;
            const align   = s.textAlign  || 'left';
            const lh      = s.lineHeight || 1.6;
            const listType = block.listType || 'none';
            const lines = (block.content || '').split('\n').map(l => l.trim()).filter(Boolean);
            if (listType === 'bullet') {
                const items = lines.map(line => `<li style="margin-bottom:4px;">${line}</li>`).join('');
                return `<div style="${wrap}"><ul style="list-style-type:disc !important;margin:0;padding-left:24px;color:${color};font-size:${size}px;text-align:${align};line-height:${lh};">${items}</ul></div>`;
            } else if (listType === 'numbered') {
                const items = lines.map(line => `<li style="margin-bottom:4px;">${line}</li>`).join('');
                return `<div style="${wrap}"><ol style="list-style-type:decimal !important;margin:0;padding-left:24px;color:${color};font-size:${size}px;text-align:${align};line-height:${lh};">${items}</ol></div>`;
            } else {
                const content = (block.content || '').replace(/\n/g, '<br>');
                return `<div style="${wrap}"><p style="margin:0;color:${color};font-size:${size}px;text-align:${align};line-height:${lh}">${content}</p></div>`;
            }
        }
        case 'heading': {
            const color  = s.color     || '#111827';
            const size   = s.fontSize  || 24;
            const align  = s.textAlign || 'left';
            const weight = s.fontWeight || 700;
            return `<div style="${wrap}"><h2 style="margin:0;color:${color};font-size:${size}px;text-align:${align};font-weight:${weight};">${block.content || ''}</h2></div>`;
        }
        case 'image': {
            const src   = block.src  || '';
            const alt   = block.alt  || '';
            const align = s.blockAlign || s.textAlign || 'left';
            const width = s.width ?? 100;
            if (!src) {
                return `<div style="${wrap}text-align:${align}"><div style="background:#f3f4f6;border:2px dashed #d1d5db;border-radius:6px;min-height:80px;display:flex;align-items:center;justify-content:center;color:#9ca3af;font-size:12px;"><svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='1.5' width='24' height='24'><rect x='3' y='3' width='18' height='18' rx='2'/><circle cx='8.5' cy='8.5' r='1.5'/><path d='M21 15l-5-5L5 21'/></svg></div></div>`;
            }
            const widthVal = width === 'auto' ? 'auto' : `${width}%`;
            return `<div style="${wrap}text-align:${align}"><img src="${src}" alt="${alt}" style="max-width:100%;width:${widthVal};display:inline-block;vertical-align:top;" /></div>`;
        }
        case 'button': {
            const text   = block.text || 'Click here';
            const href   = block.href || '#';
            const bgBtn  = s.backgroundColor || '#4285f4';
            const color  = s.textColor       || '#ffffff';
            const radius = (s.borderRadius   ?? 6) + 'px';
            const size   = (s.fontSize       ?? 14) + 'px';
            const align  = s.blockAlign      || s.textAlign || 'left';
            return `<div style="${wrap}text-align:${align}"><a href="${href}" style="display:inline-block;background:${bgBtn};color:${color};border-radius:${radius};font-size:${size};font-weight:600;padding:10px 24px;text-decoration:none;">${text}</a></div>`;
        }
        case 'divider': {
            const color  = s.borderColor || '#e5e7eb';
            const bw     = (s.dividerThickness || 1) + 'px';
            const bstyle = s.borderStyle  || 'solid';
            const width  = s.width ?? 100;
            const align  = s.blockAlign || s.textAlign || 'left';
            const margin = align === 'center' ? '0 auto' : (align === 'right' ? '0 0 0 auto' : '0 auto 0 0');
            return `<div style="${wrap}"><hr style="border:none;border-top:${bw} ${bstyle} ${color};width:${width}%;margin:${margin};" /></div>`;
        }
        case 'spacer': {
            const height = (s.height || 24) + 'px';
            return `<div style="height:${height};"></div>`;
        }
        case 'column': {
            const count   = block.columnCount || 2;
            const columns = block.columns     || [];
            const colWidths = block.colWidths || [];
            let tds = '';
            columns.forEach((col, idx) => {
                const inner = renderPreviewBlocks(col.blocks || []);
                const gap   = idx === 0 ? '' : 'padding-left:12px;';
                const pct   = colWidths[idx] !== undefined ? colWidths[idx] : (100 / Math.max(1, count)).toFixed(2);
                tds += `<td style="width:${pct}%;vertical-align:top;${gap}">${inner}</td>`;
            });
            return `<div style="${wrap}"><table width="100%" cellpadding="0" cellspacing="0" border="0" style="border-collapse:collapse;table-layout:fixed;"><tr>${tds}</tr></table></div>`;
        }
        case 'logo': {
            const src   = block.src  || '';
            const alt   = block.alt  || '';
            const align = s.blockAlign || s.textAlign || 'center';
            const width = s.width ?? 25;
            const link  = block.link  || '';
            const logoType = block.logoType || 'image';
            const brandText = block.brandText || 'BrandName';

            const justify = align === 'left' ? 'flex-start' : (align === 'right' ? 'flex-end' : 'center');
            const dir = logoType === 'image-text-stacked' ? 'column' : 'row';

            let innerHtml = '';
            if (logoType !== 'text') {
                if (src) {
                    innerHtml += `<img src="${src}" alt="${alt}" style="max-width:100%;width:${width}%;display:inline-block;vertical-align:middle;" />`;
                } else {
                    innerHtml += `<div style="background:#f3f4f6;border:2px dashed #d1d5db;border-radius:6px;min-height:60px;display:inline-flex;align-items:center;justify-content:center;color:#9ca3af;font-size:12px;padding:10px;"><svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round' width='24' height='24' class='lucide lucide-image-up'><path d='M10.3 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v10l-3.1-3.1a2 2 0 0 0-2.81 0L10.3 21ZM17 21v-6M14 18l3-3 3 3'/></svg></div>`;
                }
            }
            if (logoType !== 'image') {
                const ff = s.fontFamily || 'sans-serif';
                const fw = s.fontWeight || 'bold';
                const fs = (s.fontSize || 24) + 'px';
                const color = s.color || '#333333';
                innerHtml += `<span style="font-family:${ff};font-weight:${fw};font-size:${fs};color:${color};line-height:1;display:inline-block;vertical-align:middle;">${brandText}</span>`;
            }

            const wrapStyle = `display:inline-flex;align-items:center;justify-content:${justify};flex-direction:${dir};gap:12px;text-decoration:none;vertical-align:middle;`;
            const content = link ? `<a href="${link}" target="_blank" style="${wrapStyle}">${innerHtml}</a>` : `<div style="${wrapStyle}">${innerHtml}</div>`;
            return `<div style="${wrap}text-align:${align}">${content}</div>`;
        }
        case 'footer': {
            const color   = s.color      || '#9ca3af';
            const size    = s.fontSize   || 11;
            const align   = s.textAlign  || 'center';
            const lh      = s.lineHeight || 1.8;
            const content = block.content || "You're receiving this email because you subscribed to our newsletter.";
            const copyright = block.copyright || "© 2026 Your Company · All rights reserved";
            return `<div style="${wrap}text-align:${align};line-height:${lh};font-size:${size}px;color:${color};">
                <p style="margin:0 0 4px 0;">${content}</p>
                <p style="margin:0 0 4px 0;"><a href="#" style="color:#4285f4;text-decoration:none;">Unsubscribe</a> · <a href="#" style="color:#4285f4;text-decoration:none;">Privacy Policy</a></p>
                <p style="margin:0;">	ext:${copyright}</p>
            </div>`;
        }
        case 'social': {
            const align = s.textAlign || 'center';
            const justify = align === 'center' ? 'center' : (align === 'right' ? 'flex-end' : 'flex-start');
            const spaceBetween = block.spaceBetween || 8;
            const iconSize = block.iconSize || 28;
            const iconShape = block.iconShape || 'rounded';
            const iconTheme = block.iconTheme || 'colored';

            const sizeVal = typeof iconSize === 'number' ? `${iconSize}px` : (isFinite(parseInt(iconSize)) ? `${parseInt(iconSize)}px` : '28px');
            const radii = { circle: '50%', rounded: '6px', square: '0' };
            const radiusVal = radii[iconShape] || '6px';

            const links = block.links || [];
            let iconsHtml = '';

            links.forEach(link => {
                const p = getSocialPlatform(link.platform);
                if (!p) return;
                const isWhite = iconTheme === 'white';
                const bg = iconTheme === 'black' ? '#000000' : (isWhite ? '#ffffff' : (p.color || '#6b7280'));
                
                let svg = p.iconSvg.replace(/fill="#fff"/g, `fill="${isWhite ? (p.color || '#000000') : '#ffffff'}"`);
                
                const wrapStyle = `display:inline-flex;align-items:center;justify-content:center;width:${sizeVal};height:${sizeVal};border-radius:${radiusVal};background:${bg};text-decoration:none;margin-right:${spaceBetween}px;`;
                iconsHtml += `<a href="${link.url || '#'}" target="_blank" style="${wrapStyle}"><span style="display:flex;align-items:center;justify-content:center;width:100%;height:100%">${svg}</span></a>`;
            });

            return `<div style="${wrap}text-align:${align};">${iconsHtml}</div>`;
        }
        case 'video': {
            const url = block.url || '';
            if (!url) {
                return `<div style="${wrap}"><div style="background:#f3f4f6;border:2px dashed #d1d5db;border-radius:6px;min-height:120px;display:flex;align-items:center;justify-content:center;color:#9ca3af;font-size:12px;"><svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='1.5' width='24' height='24'><rect x='3' y='3' width='18' height='18' rx='2'/><path fill='currentColor' stroke='none' d='M9.5 8l7 4-7 4V8z'/></svg></div></div>`;
            }
            const isThirdParty = /youtube\.com|youtu\.be|vimeo\.com|dailymotion\.com|wistia\.com/.test(url);
            if (isThirdParty) {
                let embedUrl = url;
                const ytMatch = url.match(/(?:youtube\.com\/watch\?v=|youtu\.be\/)([^&\s?]+)/);
                const vimeoMatch = url.match(/vimeo\.com\/(\d+)/);
                if (ytMatch) {
                    embedUrl = `https://www.youtube.com/embed/${ytMatch[1]}`;
                } else if (vimeoMatch) {
                    embedUrl = `https://player.vimeo.com/video/${vimeoMatch[1]}`;
                }
                return `<div style="${wrap}"><iframe src="${embedUrl}" frameborder="0" allowfullscreen style="width:100%;aspect-ratio:16/9;display:block;border:0;"></iframe></div>`;
            } else {
                return `<div style="${wrap}"><video src="${url}" controls style="width:100%;display:block;border-radius:4px;"></video></div>`;
            }
        }
        case 'html':
            return `<div style="${wrap}">${block.html || ''}</div>`;
        default:
            return '';
    }
}

function renderPreviewBlocks(blockList) {
    return (blockList || []).map(renderPreviewBlock).join('');
}

const currentYear = new Date().getFullYear();
const hasFooterBlock = computed(() => {
    return blocks.value.some(b => {
        if (b.type === 'footer') return true;
        if (b.type === 'column' && b.columns) {
            return b.columns.some(col => col.blocks?.some(nb => nb.type === 'footer'));
        }
        return false;
    });
});
const previewHtml = computed(() => {
    const body = renderPreviewBlocks(blocks.value);
    let footerSection = '';
    if (!hasFooterBlock.value) {
        footerSection = `<div style="border-top:1px solid #e5e7eb;padding:16px 24px;text-align:center;font-size:11px;color:#9ca3af;line-height:1.8;background:#f9fafb;">
            <p style="margin:0">You're receiving this email because you subscribed to our newsletter.</p>
            <p style="margin:0"><a href="#" style="color:#4285f4;text-decoration:none;">Unsubscribe</a> · <a href="#" style="color:#4285f4;text-decoration:none;">Privacy Policy</a></p>
            <p style="margin:0">© ${currentYear} Your Company · All rights reserved</p>
        </div>`;
    }
    return `<div style="background:#f3f4f6;padding:24px 16px;">
        <div style="max-width:600px;margin:0 auto;background:#ffffff;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;">
            ${body}
            ${footerSection}
        </div>
    </div>`;
});

const availablePaletteItems = computed(() => {
    if (hasFooterBlock.value) {
        return PALETTE_ITEMS.filter(item => item.type !== 'footer');
    }
    return PALETTE_ITEMS;
});

function enforceFooterPosition() {
    if (!blocks || !blocks.value) return;
    let footers = [];
    // Look in top-level blocks
    for (let i = 0; i < blocks.value.length; i++) {
        if (blocks.value[i].type === 'footer') {
            footers.push({ block: blocks.value[i] });
        } else if (blocks.value[i].type === 'column' && blocks.value[i].columns) {
            blocks.value[i].columns.forEach(col => {
                if (col.blocks) {
                    for (let k = 0; k < col.blocks.length; k++) {
                        if (col.blocks[k].type === 'footer') {
                            footers.push({ block: col.blocks[k] });
                        }
                    }
                }
            });
        }
    }
    
    let targetFooterBlock = null;
    if (footers.length > 0) {
        targetFooterBlock = footers[0].block;
        const settings = props.globalSettings;
        const brandName = settings?.business?.name || 'Your Brand';
        const defaultNotice1 = "You're receiving this email because you subscribed to our newsletter.";
        const defaultNotice2 = "You're receiving this email because you opted in at our website.";
        if (!targetFooterBlock.content || targetFooterBlock.content === defaultNotice1 || targetFooterBlock.content === defaultNotice2) {
            targetFooterBlock.content = settings?.email?.footer_notice || defaultNotice2;
        }

        const defaultCopyright1 = `© ${new Date().getFullYear()} Your Company · All rights reserved`;
        const defaultCopyright2 = `© ${new Date().getFullYear()} CRMfic · All rights reserved`;
        const defaultCopyright3 = `© ${new Date().getFullYear()} CRMfic - All rights reserved`;
        
        if (!targetFooterBlock.copyright || 
            targetFooterBlock.copyright === defaultCopyright1 || 
            targetFooterBlock.copyright === defaultCopyright2 || 
            targetFooterBlock.copyright === defaultCopyright3 ||
            targetFooterBlock.copyright.includes('CRMfic') || 
            targetFooterBlock.copyright.includes('Your Company')) {
            targetFooterBlock.copyright = settings?.email?.footer_copyright || `© ${new Date().getFullYear()} ${brandName} · All rights reserved`;
        }
    } else {
        targetFooterBlock = reactive({
            id: crypto.randomUUID(),
            type: 'footer',
            styles: defaultStyles('footer'),
            content: props.globalSettings?.email?.footer_notice || "You're receiving this email because you subscribed to our newsletter.",
            copyright: props.globalSettings?.email?.footer_copyright || `© ${new Date().getFullYear()} Your Company · All rights reserved`,
            showUnsubscribe: true,
            showPrivacy: true,
        });
    }
    
    const isCorrect = footers.length === 1 && 
                      blocks.value.length > 0 && 
                      blocks.value[blocks.value.length - 1].type === 'footer' &&
                      blocks.value[blocks.value.length - 1].id === targetFooterBlock.id;
                      
    if (isCorrect) {
        return;
    }
    
    // Remove all footers from the tree
    blocks.value.forEach(b => {
        if (b.type === 'column' && b.columns) {
            b.columns.forEach(col => {
                if (col.blocks) {
                    col.blocks = col.blocks.filter(nb => nb.type !== 'footer');
                }
            });
        }
    });
    blocks.value = blocks.value.filter(b => b.type !== 'footer');
    
    // Push target footer to the end
    blocks.value.push(targetFooterBlock);
}

const sendMode         = ref('now');
const scheduledAt      = ref('');
const rangeStart       = ref('');
const rangeEnd         = ref('');
const broadcasting     = ref(false);
const broadcastSuccess = ref(false);
const broadcastMessage = ref('');
const broadcastError   = ref('');
// Scheduling is interpreted in the tenant's configured timezone (Settings >
// General Settings), not the browser's local timezone.
const tenantTimezone = computed(() => usePage().props.tenantTimezone || 'UTC');
const serverTime = ref(nowInTimeZone(tenantTimezone.value));
const leftPanelTab     = ref('blocks');
const sectionCategory  = ref('All');
const SECTION_CATEGORIES = ['All', 'General', 'E-commerce', 'SaaS', 'Events', 'Services', 'Media'];
const filteredSections = computed(() =>
    sectionCategory.value === 'All'
        ? SECTION_TEMPLATES
        : SECTION_TEMPLATES.filter(s => s.category === sectionCategory.value)
);


// Blocks - loaded from campaign.settings.blocks
const blocks = ref(props.campaign.settings?.blocks ?? []);
enforceFooterPosition();

watch(blocks, () => {
    enforceFooterPosition();
}, { deep: true });

// Subject & settings form
const subjectForm = reactive({
    email_subject:    props.campaign.email_subject  ?? '',
    email_pre_header: props.campaign.email_pre_header ?? '',
    email_subject_b:  props.campaign.settings?.email_subject_b ?? '',
    ab_test:          props.campaign.settings?.ab_test ?? false,
    ab_subjects:      (props.campaign.settings?.ab_subjects ?? [{ id: 1, subject: '', priority: 50 }]).map((r, i) => ({ id: r.id ?? i + 1, subject: r.subject ?? '', priority: r.priority ?? 50 })),
    reply_to_email:   props.campaign.settings?.reply_to_email ?? props.globalSettings?.email?.reply_to_email ?? '',
    smtp_config_id:   props.campaign.settings?.smtp_config_id ?? (props.smtpConfigs.find(s => s.is_default)?.id ?? null),
    utm_status:       props.campaign.utm_status  ?? false,
    utm_source:       props.campaign.utm_source  ?? '',
    utm_medium:       props.campaign.utm_medium  ?? '',
    utm_campaign:     props.campaign.utm_campaign ?? '',
    utm_term:         props.campaign.utm_term    ?? '',
    utm_content:      props.campaign.utm_content ?? '',
});

const smtpOptions = computed(() => {
    return props.smtpConfigs.map(cfg => ({
        value: cfg.id,
        label: `${cfg.name} (${cfg.from_email})` + (cfg.is_default ? ' [Default]' : '')
    }));
});

const selectedSmtpConfig = computed(() => {
    return props.smtpConfigs.find(cfg => cfg.id === subjectForm.smtp_config_id) || props.smtpConfigs.find(cfg => cfg.is_default) || null;
});

let _abIdCounter = subjectForm.ab_subjects.length + 2;

function addAbSubject() {
    subjectForm.ab_subjects.push({ id: _abIdCounter++, subject: '', priority: 50 });
}
function removeAbSubject(index) {
    subjectForm.ab_subjects.splice(index, 1);
}
function adjustPriority(index, delta) {
    const row = subjectForm.ab_subjects[index];
    row.priority = Math.max(1, Math.min(100, (row.priority || 50) + delta));
}
function sendTestEmail() {
    openTestEmailModal();
}

// Recipients form
const recipientsForm = reactive({
    included: (props.campaign.recipients_config?.included?.length ? props.campaign.recipients_config.included : [{ list_id: '', tag_id: '' }]).map(r => ({ list_id: r.list_id ?? '', tag_id: r.tag_id ?? '' })),
    excluded: (props.campaign.recipients_config?.excluded ?? []).map(r => ({ list_id: r.list_id ?? '', tag_id: r.tag_id ?? '' })),
});

// By List & Tag vs By Advanced Filter are mutually exclusive - only the
// active mode's shape gets saved to recipients_config (see buildRecipientsConfig).
const recipientsMode  = ref(props.campaign.recipients_config?.mode ?? 'list_tag');
const filterTree      = reactive(props.campaign.recipients_config?.filter ?? { groups: [{ conditions: [{ field: null, operator: null, value: null }] }] });
const filterBuilderRef = ref(null);

function buildRecipientsConfig() {
    if (recipientsMode.value === 'advanced_filter') {
        return { mode: 'advanced_filter', filter: filterTree };
    }
    return {
        mode: 'list_tag',
        included: recipientsForm.included,
        excluded: recipientsForm.excluded.filter(r => r.list_id),
    };
}

// ── Computed ───────────────────────────────────────────────────────────────
function findBlockById(id) {
    for (const b of blocks.value) {
        if (b.id === id) return b;
        if (b.type === 'column') {
            for (const col of b.columns) {
                const found = col.blocks.find(nb => nb.id === id);
                if (found) return found;
            }
        }
    }
    return null;
}

const selectedBlock = computed(() => findBlockById(selectedBlockId.value));

// ── Social platforms ────────────────────────────────────────────────────────
const mkIcon = (path) => `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="#fff" width="16" height="16">${path}</svg>`;
const SOCIAL_PLATFORMS = [
    { id: 'facebook',  name: 'Facebook',  color: '#1877F2', iconSvg: mkIcon('<path d="M24 12.073c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.99 4.388 10.954 10.125 11.854v-8.385H7.078v-3.47h3.047V9.43c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874v2.25h3.328l-.532 3.47h-2.796v8.385C19.612 23.027 24 18.062 24 12.073z"/>') },
    { id: 'instagram', name: 'Instagram', color: '#E4405F', iconSvg: mkIcon('<path d="M12 2.163c3.204 0 3.584.012 4.85.07 3.252.148 4.771 1.691 4.919 4.919.058 1.265.069 1.645.069 4.849 0 3.205-.012 3.584-.069 4.849-.149 3.225-1.664 4.771-4.919 4.919-1.266.058-1.644.07-4.85.07-3.204 0-3.584-.012-4.849-.07-3.26-.149-4.771-1.699-4.919-4.92-.058-1.265-.07-1.644-.07-4.849 0-3.204.013-3.583.07-4.849.149-3.227 1.664-4.771 4.919-4.919 1.266-.057 1.645-.069 4.849-.069zM12 0C8.741 0 8.333.014 7.053.072 2.695.272.273 2.69.073 7.052.014 8.333 0 8.741 0 12c0 3.259.014 3.668.072 4.948.2 4.358 2.618 6.78 6.98 6.98C8.333 23.986 8.741 24 12 24c3.259 0 3.668-.014 4.948-.072 4.354-.2 6.782-2.618 6.979-6.98.059-1.28.073-1.689.073-4.948 0-3.259-.014-3.667-.072-4.947-.196-4.354-2.617-6.78-6.979-6.98C15.668.014 15.259 0 12 0zm0 5.838a6.162 6.162 0 100 12.324 6.162 6.162 0 000-12.324zM12 16a4 4 0 110-8 4 4 0 010 8zm6.406-11.845a1.44 1.44 0 100 2.881 1.44 1.44 0 000-2.881z"/>') },
    { id: 'twitter',   name: 'X (Twitter)', color: '#000000', iconSvg: mkIcon('<path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"/>') },
    { id: 'linkedin',  name: 'LinkedIn',  color: '#0A66C2', iconSvg: mkIcon('<path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.062 2.062 0 01-2.063-2.065 2.064 2.064 0 112.063 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z"/>') },
    { id: 'youtube',   name: 'YouTube',   color: '#FF0000', iconSvg: mkIcon('<path d="M23.495 6.205a3.007 3.007 0 00-2.088-2.088c-1.87-.501-9.396-.501-9.396-.501s-7.507-.01-9.396.501A3.007 3.007 0 00.527 6.205a31.247 31.247 0 00-.522 5.805 31.247 31.247 0 00.522 5.783 3.007 3.007 0 002.088 2.088c1.868.502 9.396.502 9.396.502s7.506 0 9.396-.502a3.007 3.007 0 002.088-2.088 31.247 31.247 0 00.5-5.783 31.247 31.247 0 00-.5-5.805zM9.609 15.601V8.408l6.264 3.602z"/>') },
    { id: 'tiktok',    name: 'TikTok',    color: '#010101', iconSvg: mkIcon('<path d="M12.525.02c1.31-.02 2.61-.01 3.91-.02.08 1.53.63 3.09 1.75 4.17 1.12 1.11 2.7 1.62 4.24 1.79v4.03c-1.44-.05-2.89-.35-4.2-.97-.57-.26-1.1-.59-1.62-.93-.01 2.92.01 5.84-.02 8.75-.08 1.4-.54 2.79-1.35 3.94-1.31 1.92-3.58 3.17-5.91 3.21-1.43.08-2.86-.31-4.08-1.03-2.02-1.19-3.44-3.37-3.65-5.71-.02-.5-.03-1-.01-1.49.18-1.9 1.12-3.72 2.58-4.96 1.66-1.44 3.98-2.13 6.15-1.72.02 1.48-.04 2.96-.04 4.44-.99-.32-2.15-.23-3.02.37-.63.41-1.11 1.04-1.36 1.75-.21.51-.15 1.07-.14 1.61.24 1.64 1.82 3.02 3.5 2.87 1.12-.01 2.19-.66 2.77-1.61.19-.33.4-.67.41-1.06.1-1.79.06-3.57.07-5.36.01-4.03-.01-8.05.02-12.07z"/>') },
    { id: 'pinterest', name: 'Pinterest', color: '#BD081C', iconSvg: mkIcon('<path d="M12 0C5.373 0 0 5.373 0 12c0 5.084 3.163 9.426 7.627 11.174-.105-.949-.2-2.405.042-3.441.218-.937 1.407-5.965 1.407-5.965s-.359-.719-.359-1.782c0-1.668.967-2.914 2.171-2.914 1.023 0 1.518.769 1.518 1.69 0 1.029-.655 2.568-.994 3.995-.283 1.194.599 2.169 1.777 2.169 2.133 0 3.772-2.249 3.772-5.495 0-2.873-2.064-4.882-5.012-4.882-3.414 0-5.418 2.561-5.418 5.207 0 1.031.397 2.138.893 2.738a.36.36 0 01.083.345l-.333 1.36c-.053.22-.174.267-.402.161-1.499-.698-2.436-2.889-2.436-4.649 0-3.785 2.75-7.262 7.929-7.262 4.163 0 7.398 2.967 7.398 6.931 0 4.136-2.607 7.464-6.227 7.464-1.216 0-2.359-.632-2.75-1.378l-.748 2.853c-.271 1.043-1.002 2.35-1.492 3.146C9.57 23.812 10.763 24 12 24c6.627 0 12-5.373 12-12S18.627 0 12 0z"/>') },
    { id: 'discord',   name: 'Discord',   color: '#5865F2', iconSvg: mkIcon('<path d="M20.317 4.37a19.791 19.791 0 00-4.885-1.515.074.074 0 00-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 00-5.487 0 12.64 12.64 0 00-.617-1.25.077.077 0 00-.079-.037A19.736 19.736 0 003.677 4.37a.07.07 0 00-.032.027C.533 9.046-.32 13.58.099 18.057a.082.082 0 00.031.057 19.9 19.9 0 005.993 3.03.078.078 0 00.084-.028 14.09 14.09 0 001.226-1.994.076.076 0 00-.041-.106 13.107 13.107 0 01-1.872-.892.077.077 0 01-.008-.128 10.2 10.2 0 00.372-.292.074.074 0 01.077-.01c3.928 1.793 8.18 1.793 12.062 0a.074.074 0 01.078.01c.12.098.246.198.373.292a.077.077 0 01-.006.127 12.299 12.299 0 01-1.873.892.077.077 0 00-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 00.084.028 19.839 19.839 0 006.002-3.03.077.077 0 00.032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 00-.031-.03zM8.02 15.33c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.956-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.956 2.418-2.157 2.418zm7.975 0c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.955-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.946 2.418-2.157 2.418z"/>') },
    { id: 'whatsapp',  name: 'WhatsApp',  color: '#25D366', iconSvg: mkIcon('<path d="M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51-.173-.008-.371-.01-.57-.01-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 01-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 01-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 012.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0012.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 005.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893a11.821 11.821 0 00-3.48-8.413z"/>') },
    { id: 'telegram',  name: 'Telegram',  color: '#229ED9', iconSvg: mkIcon('<path d="M11.944 0A12 12 0 000 12a12 12 0 0012 12 12 12 0 0012-12A12 12 0 0012 0a12 12 0 00-.056 0zm4.962 7.224c.1-.002.321.023.465.14a.506.506 0 01.171.325c.016.093.036.306.02.472-.18 1.898-.962 6.502-1.36 8.627-.168.9-.499 1.201-.82 1.23-.696.065-1.225-.46-1.9-.902-1.056-.693-1.653-1.124-2.678-1.8-1.185-.78-.417-1.21.258-1.91.177-.184 3.247-2.977 3.307-3.23.007-.032.014-.15-.056-.212s-.174-.041-.249-.024c-.106.024-1.793 1.14-5.061 3.345-.48.33-.913.49-1.302.48-.428-.008-1.252-.241-1.865-.44-.752-.245-1.349-.374-1.297-.789.027-.216.325-.437.893-.663 3.498-1.524 5.83-2.529 6.998-3.014 3.332-1.386 4.025-1.627 4.476-1.635z"/>') },
    { id: 'github',    name: 'GitHub',    color: '#181717', iconSvg: mkIcon('<path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/>') },
    { id: 'reddit',    name: 'Reddit',    color: '#FF4500', iconSvg: mkIcon('<path d="M12 0A12 12 0 0 0 0 12a12 12 0 0 0 12 12 12 12 0 0 0 12-12A12 12 0 0 0 12 0zm5.01 4.744c.688 0 1.25.561 1.25 1.249a1.25 1.25 0 0 1-2.498.056l-2.597-.547-.8 3.747c1.824.07 3.48.632 4.674 1.488.308-.309.73-.491 1.207-.491.968 0 1.754.786 1.754 1.754 0 .716-.435 1.333-1.01 1.614a3.111 3.111 0 0 1 .042.52c0 2.694-3.13 4.87-7.004 4.87-3.874 0-7.004-2.176-7.004-4.87 0-.183.015-.366.043-.534A1.748 1.748 0 0 1 4.028 12c0-.968.786-1.754 1.754-1.754.463 0 .898.196 1.207.49 1.207-.883 2.878-1.43 4.744-1.487l.885-4.182a.342.342 0 0 1 .14-.197.35.35 0 0 1 .238-.042l2.906.617a1.214 1.214 0 0 1 1.108-.701zM9.25 12C8.561 12 8 12.562 8 13.25c0 .687.561 1.248 1.25 1.248.687 0 1.248-.561 1.248-1.249 0-.688-.561-1.249-1.249-1.249zm5.5 0c-.687 0-1.248.561-1.248 1.25 0 .687.561 1.248 1.249 1.248.688 0 1.249-.561 1.249-1.249 0-.687-.562-1.249-1.25-1.249zm-5.466 3.99a.327.327 0 0 0-.231.094.33.33 0 0 0 0 .463c.842.842 2.484.913 2.961.913.477 0 2.105-.056 2.961-.913a.361.361 0 0 0 .029-.463.33.33 0 0 0-.464 0c-.547.533-1.684.73-2.512.73-.828 0-1.979-.196-2.512-.73a.326.326 0 0 0-.232-.095z"/>') },
    { id: 'twitch',    name: 'Twitch',    color: '#9146FF', iconSvg: mkIcon('<path d="M11.571 4.714h1.715v5.143H11.57zm4.715 0H18v5.143h-1.714zM6 0L1.714 4.286v15.428h5.143V24l4.286-4.286h3.428L22.286 12V0zm14.571 11.143l-3.428 3.428h-3.429l-3 3v-3H6.857V1.714h13.714z"/>') },
    { id: 'spotify',   name: 'Spotify',   color: '#1DB954', iconSvg: mkIcon('<path d="M12 0C5.4 0 0 5.4 0 12s5.4 12 12 12 12-5.4 12-12S18.66 0 12 0zm5.521 17.34c-.24.359-.66.48-1.021.24-2.82-1.74-6.36-2.101-10.561-1.141-.418.122-.779-.179-.899-.539-.12-.421.18-.78.54-.9 4.56-1.021 8.52-.6 11.64 1.32.42.18.479.659.301 1.02zm1.44-3.3c-.301.42-.841.6-1.262.3-3.239-1.98-8.159-2.58-11.939-1.38-.479.12-1.02-.12-1.14-.6-.12-.48.12-1.021.6-1.141C9.6 9.9 15 10.561 18.72 12.84c.361.181.54.78.241 1.2zm.12-3.36C15.24 8.4 8.82 8.16 5.16 9.301c-.6.179-1.2-.181-1.38-.721-.18-.601.18-1.2.72-1.381 4.26-1.26 11.28-1.02 15.721 1.621.539.3.719 1.02.419 1.56-.299.421-1.02.599-1.559.3z"/>') },
    { id: 'behance',   name: 'Behance',   color: '#1769FF', iconSvg: mkIcon('<path d="M6.938 4.503c.702 0 1.34.06 1.92.188.577.13 1.07.33 1.485.61.41.28.733.65.96 1.12.225.47.34 1.05.34 1.73 0 .74-.17 1.36-.507 1.86-.338.5-.837.9-1.502 1.22.906.26 1.576.72 2.022 1.37.448.66.665 1.45.665 2.36 0 .75-.13 1.39-.41 1.93-.28.55-.67 1-.16 1.35-.495.36-1.067.62-1.71.78-.65.17-1.32.25-2.016.25H0V4.51h6.938v-.007zm-.43 4.988c.585 0 1.06-.13 1.42-.4.36-.27.54-.69.54-1.26 0-.33-.06-.6-.18-.81-.12-.21-.28-.37-.49-.48-.21-.11-.45-.19-.72-.23-.27-.04-.55-.06-.85-.06H3.16v3.24h3.348zm.198 5.282c.317 0 .615-.03.896-.09.283-.06.53-.16.745-.31.212-.14.383-.34.51-.58.127-.25.19-.56.19-.93 0-.74-.207-1.26-.623-1.55-.415-.29-.97-.44-1.666-.44H3.158v3.9h3.548zm9.832-1.38c.378.37.923.55 1.637.55.51 0 .95-.13 1.32-.39.37-.26.6-.54.69-.83h2.55c-.408 1.28-1.034 2.2-1.878 2.76-.842.55-1.862.83-3.06.83-.832 0-1.582-.13-2.248-.4-.665-.27-1.23-.65-1.693-1.14-.462-.49-.818-1.08-1.067-1.76-.25-.69-.375-1.44-.375-2.25 0-.79.13-1.52.39-2.2.26-.68.628-1.27 1.1-1.77.474-.5 1.04-.89 1.7-1.17.66-.28 1.39-.42 2.19-.42.9 0 1.69.17 2.37.52.68.35 1.24.82 1.68 1.41.44.59.76 1.26.95 2.02.19.75.25 1.54.18 2.37H15.72c0 .74.19 1.28.568 1.64zM21.208 11c-.32-.37-.82-.55-1.5-.55-.44 0-.81.08-1.1.24-.29.17-.52.37-.7.61-.18.24-.3.5-.37.77-.07.28-.11.53-.12.77h4.36c-.1-.82-.38-1.47-.7-1.84h.13zM15.48 5.5h5.26v1.44H15.48V5.5z"/>') },
    { id: 'dribbble',  name: 'Dribbble',  color: '#EA4C89', iconSvg: mkIcon('<path d="M12 24C5.385 24 0 18.615 0 12S5.385 0 12 0s12 5.385 12 12-5.385 12-12 12zm10.12-10.358c-.35-.11-3.17-.953-6.384-.438 1.34 3.684 1.887 6.684 1.992 7.308 2.3-1.555 3.936-4.02 4.395-6.87zm-6.115 7.808c-.153-.9-.75-4.032-2.19-7.77l-.066.02c-5.79 2.015-7.86 6.025-8.04 6.4 1.73 1.358 3.92 2.166 6.29 2.166 1.42 0 2.77-.29 4-.816zm-11.62-2.073c.232-.4 3.045-5.055 8.332-6.765.135-.045.27-.084.405-.12-.26-.585-.54-1.167-.827-1.74C7.822 11.75 2.7 11.84 2.205 11.84c-.007.568.06 1.122.18 1.657.18.784.5 1.53.93 2.17l-.03.71zm-1.62-4.7c.505.013 4.783.052 9.222-1.29C9.55 7.39 8.35 5.665 8.217 5.47c-2.915 1.375-5.04 4.022-5.47 7.207zm8.8-7.49c.145.21 1.37 1.99 2.375 4.595 3.77-1.4 5.368-3.54 5.556-3.8C19.15 2.53 15.74 1.08 12.002 1.08c-.8 0-1.582.1-2.335.29z"/>') },
    { id: 'medium',    name: 'Medium',    color: '#000000', iconSvg: mkIcon('<path d="M13.54 12a6.8 6.8 0 01-6.77 6.82A6.8 6.8 0 010 12a6.8 6.8 0 016.77-6.82A6.8 6.8 0 0113.54 12zM20.96 12c0 3.54-1.51 6.42-3.38 6.42-1.87 0-3.39-2.88-3.39-6.42s1.52-6.42 3.39-6.42 3.38 2.88 3.38 6.42M24 12c0 3.17-.53 5.75-1.19 5.75-.66 0-1.19-2.58-1.19-5.75s.53-5.75 1.19-5.75C23.47 6.25 24 8.83 24 12z"/>') },
    { id: 'snapchat',  name: 'Snapchat',  color: '#FFFC00', iconSvg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="#000" width="16" height="16"><path d="M12.206.793c.99 0 4.347.276 5.93 3.821.529 1.193.403 3.219.317 4.184l-.004.048c-.002.029 0 .057.007.085.039.165.249.241.408.161.178-.088.38-.174.581-.174.227 0 .5.115.5.453 0 .553-.592.66-.592 1.063 0 .346.331.528.571.626.046.018.087.037.126.058.041.022.08.047.118.073.295.208.492.527.492.878 0 .47-.361.854-.877.854-.096 0-.192-.012-.288-.034a.95.95 0 00-.086-.013c-.093-.008-.19.013-.275.056-.117.06-.221.15-.281.274-.206.43-.426.781-.729 1.079-.309.303-.7.559-1.212.693l.02.096c.025.104.048.209.064.315.116.736-.021 1.283-.538 1.556-.253.134-.603.194-.987.194-.308 0-.626-.041-.918-.109a12.5 12.5 0 00-.706-.102 8.97 8.97 0 00-.549-.029c-.195 0-.399.013-.609.043-.226.033-.455.091-.672.174-.223.086-.432.195-.604.311-.235.158-.436.301-.674.301a.44.44 0 01-.142-.025c-.207-.07-.391-.207-.531-.392a2.06 2.06 0 01-.221-.367 2.78 2.78 0 01-.15-.418c-.046-.174-.085-.357-.117-.543a12.25 12.25 0 01-.054-.293c-.049.002-.098.003-.148.003-.39 0-.74-.06-.992-.193-.519-.274-.655-.82-.538-1.556a6.5 6.5 0 01.064-.316l.02-.095c-.51-.134-.901-.39-1.209-.692-.305-.3-.526-.65-.732-1.08-.062-.124-.166-.214-.282-.274a.607.607 0 00-.275-.056.947.947 0 00-.086.013c-.097.022-.193.034-.289.034-.516 0-.877-.384-.877-.854 0-.351.197-.67.492-.878.038-.026.077-.051.118-.073.039-.021.08-.04.126-.058.24-.098.571-.28.571-.626 0-.403-.592-.51-.592-1.063 0-.338.273-.453.5-.453.201 0 .403.086.581.174.159.08.369.004.408-.161a.436.436 0 00.007-.085l-.004-.048c-.086-.965-.212-2.991.317-4.184C7.859 1.069 11.216.793 12.206.793z"/></svg>` },
];

const filteredSocialPlatforms = computed(() => {
    const q = socialPickerSearch.value.toLowerCase();
    return q ? SOCIAL_PLATFORMS.filter(p => p.name.toLowerCase().includes(q)) : SOCIAL_PLATFORMS;
});

function getSocialPlatform(id) {
    return SOCIAL_PLATFORMS.find(p => p.id === id);
}

function socialIconStyle(block, link) {
    const p = getSocialPlatform(link.platform);
    const sizes = { small: '28px', medium: '36px', large: '44px' };
    const size = sizes[block.iconSize] || (typeof block.iconSize === 'number' ? `${block.iconSize}px` : (block.iconSize ? `${block.iconSize}` : '28px'));
    const radii = { circle: '50%', rounded: '6px', square: '0' };
    const radius = radii[block.iconShape || 'rounded'];
    const bg = block.iconTheme === 'black' ? '#000' : block.iconTheme === 'white' ? '#fff' : (p?.color || '#6b7280');
    return { display: 'inline-flex', alignItems: 'center', justifyContent: 'center', width: size, height: size, borderRadius: radius, background: bg, flexShrink: 0 };
}

function socialIconSvg(block, link) {
    const p = getSocialPlatform(link.platform);
    if (!p) return '';
    const isWhiteTheme = block.iconTheme === 'white';
    return p.iconSvg.replace(/fill="#fff"/g, `fill="${isWhiteTheme ? (p.color || '#000') : '#fff'}"`);
}

// Test email modal
const showTestEmailModal = ref(false);
const testEmailAddress   = ref('');
const testEmailSending   = ref(false);
const testEmailError     = ref('');
const testEmailSuccess   = ref('');
const testEmailInputRef  = ref(null);

function openTestEmailModal() {
    testEmailError.value   = '';
    testEmailSuccess.value = '';
    showTestEmailModal.value = true;
    nextTick(() => testEmailInputRef.value?.focus());
}

function closeTestModal() {
    showTestEmailModal.value = false;
    testEmailError.value   = '';
    testEmailSuccess.value = '';
}

async function doSendTestEmail() {
    testEmailError.value   = '';
    testEmailSuccess.value = '';

    const email = testEmailAddress.value.trim();
    if (!email) {
        testEmailError.value = 'Please enter a recipient email address.';
        return;
    }

    testEmailSending.value = true;
    try {
        await window.axios.post(route('campaigns.send-test', props.campaign.id), { email, blocks: blocks.value });
        testEmailSuccess.value = `Test email sent to ${email}`;
    } catch (err) {
        testEmailError.value = err.response?.data?.message ?? 'Failed to send test email. Please check your mail settings.';
    } finally {
        testEmailSending.value = false;
    }
}

const totalRecipients   = ref(props.campaign.recipients_count ?? 0);
const countingRecipients = ref(false);

let _countDebounce = null;

async function fetchRecipientCount() {
    // Avoid firing count-recipients against a filter the user is still
    // mid-way through building - a half-picked field/operator/value is
    // expected, not an error, so just skip the request until it's complete.
    if (recipientsMode.value === 'advanced_filter' && !filterBuilderRef.value?.isValid) {
        return;
    }

    countingRecipients.value = true;
    try {
        const res = await window.axios.post(route('campaigns.count-recipients'), buildRecipientsConfig());
        totalRecipients.value = res.data.count ?? 0;
    } catch {
        // silently ignore network/validation errors during count
    } finally {
        countingRecipients.value = false;
    }
}

// Advanced Filter conditions do NOT trigger this - that mode only recounts
// when the user clicks the explicit "Filter" button (@apply, above), since
// auto-firing a request after every keystroke/field-pick was noisy and often
// hit half-built, incomplete conditions.
watch(
    () => [recipientsMode.value, JSON.stringify(recipientsForm.included), JSON.stringify(recipientsForm.excluded)],
    () => {
        clearTimeout(_countDebounce);
        _countDebounce = setTimeout(fetchRecipientCount, 400);
    },
    { deep: true }
);





// ── Recipients ─────────────────────────────────────────────────────────────
function addIncluded()         { recipientsForm.included.push({ list_id: '', tag_id: '' }); }
function removeIncluded(idx)   { recipientsForm.included.splice(idx, 1); }
function addExcluded()         { recipientsForm.excluded.push({ list_id: '', tag_id: '' }); }
function removeExcluded(idx)   { recipientsForm.excluded.splice(idx, 1); }

// Tags filtered by selected list: since tags are contact-level (not list-scoped),
// return all tags but could be restricted in future once list-tag pivot exists.
function tagsForList(_listId) { return props.tags; }

// ── Save helpers ────────────────────────────────────────────────────────────
async function saveCompose() {
    saving.value = true;
    try {
        await window.axios.patch(route('campaigns.update', props.campaign.id), {
            settings: { blocks: blocks.value },
        });
        flashSaved();
    } finally {
        saving.value = false;
    }
}

async function saveSubject() {
    saving.value = true;
    try {
        await window.axios.patch(route('campaigns.update', props.campaign.id), {
            email_subject:     subjectForm.email_subject,
            email_pre_header:  subjectForm.email_pre_header,
            utm_status:   subjectForm.utm_status,
            utm_source:   subjectForm.utm_source,
            utm_medium:   subjectForm.utm_medium,
            utm_campaign: subjectForm.utm_campaign,
            utm_term:     subjectForm.utm_term,
            utm_content:  subjectForm.utm_content,
            settings: {
                ab_test:        subjectForm.ab_test,
                ab_subjects:    subjectForm.ab_subjects,
                reply_to_email: subjectForm.reply_to_email,
                smtp_config_id: subjectForm.smtp_config_id,
            },
        });
        flashSaved();
    } finally {
        saving.value = false;
    }
}

async function saveRecipients() {
    saving.value = true;
    try {
        await window.axios.patch(route('campaigns.update', props.campaign.id), {
            recipients_config: buildRecipientsConfig(),
        });
        flashSaved();
    } finally {
        saving.value = false;
    }
}

async function saveAll() {
    saving.value = true;
    try {
        await window.axios.patch(route('campaigns.update', props.campaign.id), {
            status:           'draft',
            email_subject:    subjectForm.email_subject,
            email_pre_header: subjectForm.email_pre_header,
            utm_status:       subjectForm.utm_status,
            utm_source:       subjectForm.utm_source,
            utm_medium:       subjectForm.utm_medium,
            utm_campaign:     subjectForm.utm_campaign,
            utm_term:         subjectForm.utm_term,
            utm_content:      subjectForm.utm_content,
            recipients_config: buildRecipientsConfig(),
            settings: {
                blocks:         blocks.value,
                ab_test:        subjectForm.ab_test,
                ab_subjects:    subjectForm.ab_subjects,
                reply_to_email: subjectForm.reply_to_email,
                smtp_config_id: subjectForm.smtp_config_id,
            },
        });
        flashSaved();
    } finally {
        saving.value = false;
    }
}

function flashSaved() {
    savedAt.value = new Date();
    setTimeout(() => { savedAt.value = null; }, 3000);
}

async function doBroadcast() {
    broadcastError.value   = '';
    broadcastSuccess.value = false;

    if (sendMode.value === 'schedule' && !scheduledAt.value) {
        broadcastError.value = 'Please set a date and time to schedule the campaign.';
        return;
    }
    if (sendMode.value === 'range' && (!rangeStart.value || !rangeEnd.value)) {
        broadcastError.value = 'Please set both a start and end date-time for the range.';
        return;
    }

    // Save everything first
    await saveAll();

    broadcasting.value = true;
    try {
        // Convert datetime-local values (interpreted in the tenant's configured
        // timezone) to UTC ISO strings so Laravel Carbon::parse() receives
        // unambiguous UTC timestamps.
        const toUtcIso = (v) => zonedTimeToUtcIso(v, tenantTimezone.value);

        const res = await window.axios.post(route('campaigns.broadcast', props.campaign.id), {
            send_mode:    sendMode.value,
            scheduled_at: sendMode.value === 'schedule' ? toUtcIso(scheduledAt.value) : null,
            range_start:  sendMode.value === 'range'    ? toUtcIso(rangeStart.value)  : null,
            range_end:    sendMode.value === 'range'    ? toUtcIso(rangeEnd.value)     : null,
        });
        broadcastSuccess.value = true;

        // Build success message using the tenant-timezone input times (not backend UTC)
        const fmt = (v) => v ? formatInTimeZone(toUtcIso(v), tenantTimezone.value) : '';

        if (sendMode.value === 'schedule') {
            broadcastMessage.value = `Campaign scheduled for ${fmt(scheduledAt.value)}.`;
        } else if (sendMode.value === 'range') {
            broadcastMessage.value = `Campaign queued - emails will be spread from ${fmt(rangeStart.value)} to ${fmt(rangeEnd.value)}.`;
        } else {
            broadcastMessage.value = 'Campaign is being sent. Emails are dispatched in the background.';
        }
    } catch (e) {
        broadcastError.value = e.response?.data?.message
            || Object.values(e.response?.data?.errors ?? {})[0]?.[0]
            || 'Something went wrong.';
    } finally {
        broadcasting.value = false;
    }
}

// ── Step navigation ────────────────────────────────────────────────────────
async function goToStep(target) {
    // Save current step before moving
    if (currentStep.value === 'compose')    await saveCompose();
    if (currentStep.value === 'subject')    await saveSubject();
    if (currentStep.value === 'recipients') await saveRecipients();

    doneSteps.value.add(currentStep.value);
    currentStep.value = target;

    // Refresh contact count when entering recipients step
    if (target === 'recipients') {
        fetchRecipientCount();
    }
}

function jumpToStep(target) {
    if (doneSteps.value.has(target) || target === currentStep.value) {
        currentStep.value = target;
    }
}
</script>

<style scoped>
/* ── Step bar ───────────────────────────────────────────────── */
.cw-stepbar {
    flex-shrink: 0;
    background: var(--bg-surface);
    border-bottom: 1px solid var(--border-color);
    display: flex;

    padding: 0 16px;
    z-index: 50;
}

.cw-back-btn {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 13px;
    color: var(--text-secondary);
    background: none;
    border: none;
    cursor: pointer;
    padding: 4px 8px;
    border-radius: 6px;
    white-space: nowrap;
    transition: background 150ms;
}
.cw-back-btn:hover { background: var(--bg-hover); color: var(--text-primary); }

.cw-steps {
    display: flex;
    align-items: center;
    gap: 2px;
    flex: 1;
    justify-content: center;
}

.cw-step {
    display: flex;
    align-items: center;
    gap: 7px;
    font-size: 12px;
    font-weight: 500;
    color: var(--text-muted);
    background: none;
    border: none;
    cursor: pointer;
    padding: 4px 10px;
    border-radius: 6px;
    transition: color 150ms, background 150ms;
    white-space: nowrap;
}
.cw-step:hover { background: var(--bg-hover); color: var(--text-secondary); }
.cw-step.is-active { color: var(--info); font-weight: 600; background: var(--active-bg); }
.cw-step.is-done   { color: var(--success); }

.cw-step-num {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    font-size: 10px;
    font-weight: 700;
    background: currentColor;
    color: var(--bg-surface);
    flex-shrink: 0;
}
.cw-step.is-active .cw-step-num { background: var(--info); color: #fff; }
.cw-step.is-done   .cw-step-num { background: var(--success); color: #fff; }
.cw-step:not(.is-active):not(.is-done) .cw-step-num { background: var(--border-color); color: var(--text-muted); }

.cw-stepbar-right {
    display: flex;
    align-items: center;
    gap: 10px;
    white-space: nowrap;
}

.cw-campaign-title {
    font-size: 12px;
    color: var(--text-muted);
    max-width: 160px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.cw-saved-indicator {
    display: flex;
    align-items: center;
    gap: 4px;
    font-size: 11px;
    color: var(--success);
}

.cw-saving-indicator { font-size: 11px; color: var(--text-muted); }

/* ── Step panels ────────────────────────────────────────────── */
.cw-step-panel {
    flex: 1;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    min-height: 0;
}

.cw-step-panel--scroll {
    overflow-y: auto;
}

</style>
