<?php
// components/Form/ScheduleConfig.php
// Composite scheduling UI element: flow-like left-to-right layout
// with Start condition box (Now / On Date) and End condition box
// (varies per schedule_type: Bulk?Completed/Date, Scheduled?Date, Automation?Never/Date).
// Fully Alpine.js-driven reactivity.

namespace Components\Form;

class ScheduleConfig extends BaseField
{
    /**
     * Render the schedule configuration composite element.
     *
     * Expected form fields (managed via Alpine x-model on the parent form):
     *   - schedule_type:          'bulk_mail' | 'scheduled_window' | 'automation'
     *   - start_mode:             'now' | 'date'
     *   - newsletter_item_start:  date string (when start_mode=date)
     *   - newsletter_item_end:    date string (when end requires a date)
     *   - automation_end_mode:    'never' | 'date' (for automation schedule_type)
     *
     * Field name mappings can be overridden via $def keys.
     */
    public static function render(string $name, string $label, $value, array $def, array $opts): string
    {
        $errors = $opts['errors'] ?? [];

        // Field name mappings (configurable via YAML def)
        $f = [
            'schedule_type'     => (string)($def['schedule_type_field']     ?? 'schedule_type'),
            'start_mode'        => (string)($def['start_mode_field']        ?? 'start_mode'),
            'start_date'        => (string)($def['start_date_field']        ?? 'newsletter_item_start'),
            'end_date'          => (string)($def['end_date_field']          ?? 'newsletter_item_end'),
            'automation_end'    => (string)($def['automation_end_mode_field'] ?? 'automation_end_mode'),
        ];

        // Translated labels
        $t = [
            'start'             => self::h((string)\mh_lng('MAILBEEZ_SCHEDULE_START', 'Start')),
            'end'               => self::h((string)\mh_lng('MAILBEEZ_SCHEDULE_END', 'End')),
            'now'               => self::h((string)\mh_lng('MAILBEEZ_NEWSLETTER_START_NOW', 'Now')),
            'on_date'           => self::h((string)\mh_lng('MAILBEEZ_NEWSLETTER_START_DATE', 'On Date')),
            'completed'         => self::h((string)\mh_lng('MAILBEEZ_SCHEDULE_COMPLETED_SHORT', 'Completed')),
            'completed_date'    => self::h((string)\mh_lng('MAILBEEZ_SCHEDULE_COMPLETED_DATE_SHORT', 'Not later as Date')),
            'never'             => self::h((string)\mh_lng('MAILBEEZ_NEWSLETTER_AUTOMATION_END_NEVER', 'Never')),
            'date'              => self::h((string)\mh_lng('MAILBEEZ_SCHEDULE_DATE', 'Date')),
            'not_later_than'    => self::h((string)\mh_lng('MAILBEEZ_SCHEDULE_NOT_LATER', 'but not later than')),
            // Inline explainers to reduce visual clutter when inputs are not needed
            'start_now_hint'    => self::h((string)\mh_lng('MAILBEEZ_SCHEDULE_HINT_START_NOW', 'Sending starts as soon as you set the newsletter active.')),
            'end_completed_hint'=> self::h((string)\mh_lng('MAILBEEZ_SCHEDULE_HINT_END_COMPLETED', 'Sending stops automatically when all recipients are processed.')),
            'end_never_hint'    => self::h((string)\mh_lng('MAILBEEZ_SCHEDULE_HINT_END_NEVER', 'This automation keeps running until you stop it.')),
            // Summary tokens
            'starts_now'        => (string)\mh_lng('MAILBEEZ_SCHEDULE_SUMMARY_STARTS_NOW', 'Starts immediately'),
            'starts_on'         => (string)\mh_lng('MAILBEEZ_SCHEDULE_SUMMARY_STARTS_ON', 'Starts'),
            'stops_finished'    => (string)\mh_lng('MAILBEEZ_SCHEDULE_SUMMARY_STOPS_FINISHED', 'Stops when finished'),
            'stops_on'          => (string)\mh_lng('MAILBEEZ_SCHEDULE_SUMMARY_STOPS_ON', 'Stops'),
            'runs_indefinitely' => (string)\mh_lng('MAILBEEZ_SCHEDULE_SUMMARY_RUNS_INDEFINITELY', 'Runs indefinitely'),
        ];

        // JSON-safe versions for Alpine
        $fJson = htmlspecialchars(json_encode($f, JSON_UNESCAPED_UNICODE), ENT_QUOTES);
        $tJson = htmlspecialchars(json_encode($t, JSON_UNESCAPED_UNICODE), ENT_QUOTES);

        $errorHtml = self::errorsHtml($errors);
        $clientErrStart = self::clientErrorHtml($f['start_date']);
        $clientErrEnd   = self::clientErrorHtml($f['end_date']);

        // Picker open JS snippet
        $pickerJs = "if (\$event.target && typeof \$event.target.showPicker === 'function') { \$event.target.showPicker() }";

        // Tab button classes
        $tabBase = "px-3 py-1 text-sm font-medium rounded-md cursor-pointer transition-all duration-150 focus:outline-none truncate";
        $tabActive = "bg-white shadow-sm text-gray-900 dark:bg-gray-600 dark:text-white";
        $tabInactive = "text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200";

        // Date input classes
        $dateInputCls = "block w-full rounded-md bg-white px-3 py-1.5 text-sm text-gray-900 outline-1 -outline-offset-1 outline-gray-300 placeholder:text-gray-400 focus:outline-2 focus:-outline-offset-2 focus:outline-brand dark:bg-white/5 dark:text-white dark:outline-white/10";

        // Arrow SVG connector
        $arrowSvg = '<svg class="shrink-0 w-8 h-8 text-gray-300 dark:text-gray-600" fill="none" viewBox="0 0 32 32"><path d="M8 16h16m0 0l-5-5m5 5l-5 5" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>';

        return <<<HTML
<div x-data="{
    f: {$fJson},
    t: {$tJson},
    get st()    { return (typeof form!=='undefined' && form) ? (form[this.f.schedule_type] || 'scheduled_window') : 'scheduled_window'; },
    get sm()    { return (typeof form!=='undefined' && form) ? (form[this.f.start_mode] || 'now') : 'now'; },
    get sd()    { return (typeof form!=='undefined' && form) ? (form[this.f.start_date] || '') : ''; },
    get ed()    { return (typeof form!=='undefined' && form) ? (form[this.f.end_date] || '') : ''; },
    get ae()    { return (typeof form!=='undefined' && form) ? (form[this.f.automation_end] || 'never') : 'never'; },
    _bulkEnd: null,
    // Timeout holder to defer clearing the end date until after the collapse animation
    _clearEndTimeout: null,
    _clearEndDelayMs: 220,
    _fmtDateLocal(d) {
        var y = d.getFullYear();
        var m = String(d.getMonth() + 1).padStart(2, '0');
        var da = String(d.getDate()).padStart(2, '0');
        return y + '-' + m + '-' + da;
    },
    _isInvalidDate(v) {
        return !v || v === '1000-01-01' || v === '0000-00-00' || String(v).startsWith('0000');
    },
    _tomorrow() {
        var d = new Date();
        d.setHours(0,0,0,0);
        d.setDate(d.getDate() + 1);
        return this._fmtDateLocal(d);
    },
    _addDays(dateStr, days) {
        if (this._isInvalidDate(dateStr)) return '';
        var ds = String(dateStr).slice(0, 10);
        var d = new Date(ds + 'T00:00:00');
        if (isNaN(d.getTime())) return '';
        d.setHours(0,0,0,0);
        d.setDate(d.getDate() + days);
        return this._fmtDateLocal(d);
    },
    _ensureEndDate() {
        if (!(typeof form!=='undefined' && form)) return;
        var sd = form[this.f.start_date];
        // If start date is missing or sentinel, seed it (it's always needed for relative end calculations)
        if (this._isInvalidDate(sd)) {
            sd = this._tomorrow();
            form[this.f.start_date] = sd;
        }

        var st = this.st;
        var requireDate = false;
        if (st === 'scheduled_window') {
            requireDate = true;
        } else if (st === 'bulk_mail') {
            requireDate = (this.endTab === 'date');
        } else if (st === 'automation') {
            requireDate = (this.ae === 'date');
        }
        if (!requireDate) return;

        var ed = form[this.f.end_date];
        var minEnd = this._addDays(sd, 1);
        var defaultEnd = this._addDays(sd, 7);
        if (this._isInvalidDate(ed)) {
            form[this.f.end_date] = defaultEnd;
        }
        else if (ed < minEnd) {
            form[this.f.end_date] = minEnd;
        }
    },
    setStart(v) {
        if (!(typeof form!=='undefined' && form)) return;
        form[this.f.start_mode] = v;
        if (v === 'now') { /* keep previously chosen date to preserve user intent */ }
        else if (!form[this.f.start_date]) { form[this.f.start_date] = this._tomorrow(); this._ensureEndDate(); }
    },
    setEndTab(v) {
        var st = this.st;
        if (st === 'bulk_mail') {
            this._bulkEnd = v;
            if (!(typeof form!=='undefined' && form)) return;
            // When hiding the date field, defer clearing the model to avoid placeholder flash during x-collapse
            if (v === 'completed') {
                if (this._clearEndTimeout) { clearTimeout(this._clearEndTimeout); }
                this._clearEndTimeout = setTimeout(() => {
                    if (this.st === 'bulk_mail' && this.endTab === 'completed' && typeof form!=='undefined' && form) {
                        form[this.f.end_date] = '';
                    }
                    this._clearEndTimeout = null;
                }, this._clearEndDelayMs);
            }
            else if (v === 'date' && !form[this.f.end_date]) {
                if (this._clearEndTimeout) { clearTimeout(this._clearEndTimeout); this._clearEndTimeout = null; }
                var sd = form[this.f.start_date];
                form[this.f.end_date] = sd ? this._addDays(sd, 7) : this._addDays(this._tomorrow(), 7);
            }
        } else if (st === 'automation') {
            if (!(typeof form!=='undefined' && form)) return;
            form[this.f.automation_end] = v;
            if (v === 'never') {
                if (this._clearEndTimeout) { clearTimeout(this._clearEndTimeout); }
                this._clearEndTimeout = setTimeout(() => {
                    if (this.st === 'automation' && this.ae === 'never' && typeof form!=='undefined' && form) {
                        form[this.f.end_date] = '';
                    }
                    this._clearEndTimeout = null;
                }, this._clearEndDelayMs);
            }
            else if (v === 'date' && !form[this.f.end_date]) {
                if (this._clearEndTimeout) { clearTimeout(this._clearEndTimeout); this._clearEndTimeout = null; }
                var sd = form[this.f.start_date];
                form[this.f.end_date] = sd ? this._addDays(sd, 7) : this._addDays(this._tomorrow(), 7);
            }
        }
    },
    get endTab() {
        var st = this.st;
        if (st === 'bulk_mail') { return this._bulkEnd !== null ? this._bulkEnd : (this.ed ? 'date' : 'completed'); }
        if (st === 'automation') { return this.ae; }
        return 'date'; // scheduled_window
    },
    get showEndDate() {
        var st = this.st;
        if (st === 'scheduled_window') return true;
        if (st === 'bulk_mail') return this.endTab === 'date';
        if (st === 'automation') return this.ae === 'date';
        return false;
    },
    // summary computed by shared BeezUI helper; keep getter for compatibility but delegate
    get summaryText() {
        var hasBeez = (typeof window!=='undefined' && window.BeezUI && typeof window.BeezUI.scheduleSummary==='function');
        var f = (typeof form!=='undefined' && form) ? form : {};
        return hasBeez ? window.BeezUI.scheduleSummary(this.f, this.t, f) : '';
    }
}"
    x-init="setTimeout(() => {
        if (this.f && typeof form!=='undefined' && form) {
            if (window.BeezUI && BeezUI.seedDefaultStartEnd) {
                BeezUI.seedDefaultStartEnd(this.f.start_date, this.f.end_date, form);
            }
            this._ensureEndDate();
        }
    }, 0);
    \$watch('st', () => { this._ensureEndDate(); });
    \$watch('ae', () => { this._ensureEndDate(); });
    \$watch('sm', () => { this._ensureEndDate(); });
    \$watch('sd', () => { this._ensureEndDate(); });"
    class="space-y-3">

    <!-- Summary line -->
    <div class="text-sm text-secondary leading-relaxed" x-text="summaryText"></div>

    <!-- Flow: Start ? End -->
    <!-- Stack vertically on small screens, side-by-side from sm+ -->
    <div class="flex flex-col sm:flex-row items-stretch gap-3">

        <!-- ?? START BOX ?? -->
        <div class="flex-1 rounded-lg border border-gray-200 dark:border-white/10  dark:bg-gray-800/40 overflow-hidden">
            <!-- Header with tabs -->
            <div x-ref="startHeader" class="flex flex-wrap items-center gap-2  px-3 py-2">
                <span class="text-sm font-semibold text-gray-500 dark:text-gray-400 uppercase tracking-wider">{$t['start']}</span>
                <div class="ml-auto flex flex-nowrap gap-1 rounded-lg bg-gray-100 dark:bg-gray-800/60 p-1 min-w-0">
                    <button type="button"
                        @click="setStart('now')"
                        :class="sm === 'now' ? '{$tabActive}' : '{$tabInactive}'"
                        class="{$tabBase}">{$t['now']}</button>
                    <button type="button"
                        @click="setStart('date')"
                        :class="sm === 'date' ? '{$tabActive}' : '{$tabInactive}'"
                        class="{$tabBase}">{$t['on_date']}</button>
                </div>
            </div>
            <!-- Body: keep height stable; show either input or explainer -->
            <div class="px-3 py-2.5 min-h-[44px]">
                <!-- Show date input when On Date -->
                <template x-if="sm === 'date'">
                    <div>
                        <input type="date"
                            :name="f.start_date"
                            x-model="form[f.start_date]"
                            @input="validateField(f.start_date); _ensureEndDate()"
                            @change="validateField(f.start_date); _ensureEndDate()"
                            @click="{$pickerJs}"
                            class="{$dateInputCls}" />
                        {$clientErrStart}
                    </div>
                </template>
                <!-- Otherwise show a short explainer to avoid empty space -->
                <template x-if="sm !== 'date'">
                    <p class="text-sm text-gray-500 dark:text-gray-400 leading-relaxed" x-text="t.start_now_hint"></p>
                </template>
            </div>
            <!-- Hidden inputs to persist values -->
            <input type="hidden" :name="f.start_mode" x-model="form[f.start_mode]" />
        </div>

        <!-- Arrow connector: rotates downwards on small screens when stacked -->
        <div class="flex items-center justify-center shrink-0 self-center sm:self-start pt-0 sm:pt-2 sm:rotate-0 rotate-90 transition-transform">
            {$arrowSvg}
        </div>

        <!-- ?? END BOX ?? -->
        <div class="flex-1 rounded-lg border border-gray-200 dark:border-white/10 dark:bg-gray-800/40 overflow-hidden">
            <!-- Header with tabs (vary by schedule_type) -->
            <div class="flex flex-wrap items-center gap-2 px-3 py-2">
                <span class="text-sm font-semibold text-gray-500 dark:text-gray-400 uppercase tracking-wider">{$t['end']}</span>
                <div class="ml-auto flex flex-nowrap gap-1 rounded-lg bg-gray-100 dark:bg-gray-800/60 p-1 min-w-0">

                    <!-- Bulk Mail: Completed | Date -->
                    <template x-if="st === 'bulk_mail'">
                        <div class="flex flex-nowrap gap-1 min-w-0">
                            <button type="button"
                                @click="setEndTab('completed')"
                                :class="endTab === 'completed' ? '{$tabActive}' : '{$tabInactive}'"
                                class="{$tabBase}">{$t['completed']}</button>
                            <button type="button"
                                @click="setEndTab('date')"
                                :class="endTab === 'date' ? '{$tabActive}' : '{$tabInactive}'"
                                class="{$tabBase}">{$t['completed_date']}</button>
                        </div>
                    </template>

                    <!-- Scheduled Window: always Date (no tabs needed) -->
                    <template x-if="st === 'scheduled_window'">
                        <div class="flex flex-nowrap gap-1 min-w-0">
                            <span class="{$tabBase} {$tabActive}">{$t['date']}</span>
                        </div>
                    </template>

                    <!-- Automation: Never | Date -->
                    <template x-if="st === 'automation'">
                        <div class="flex flex-nowrap gap-1 min-w-0">
                            <button type="button"
                                @click="setEndTab('never')"
                                :class="ae === 'never' ? '{$tabActive}' : '{$tabInactive}'"
                                class="{$tabBase}">{$t['never']}</button>
                            <button type="button"
                                @click="setEndTab('date')"
                                :class="ae === 'date' ? '{$tabActive}' : '{$tabInactive}'"
                                class="{$tabBase}">{$t['date']}</button>
                        </div>
                    </template>
                </div>
            </div>

            <!-- Body: keep height stable; show either input or explainer -->
            <div class="px-3 py-2.5 min-h-[44px]">
                <!-- Show date picker when required -->
                <template x-if="showEndDate">
                    <div>
                        <!-- Bulk "not later than" hint -->
                        <template x-if="st === 'bulk_mail' && endTab === 'date'">
                            <p class="text-sm text-gray-500 dark:text-gray-400 mb-1.5">{$t['not_later_than']}</p>
                        </template>
                        <input type="date"
                            :name="f.end_date"
                            x-model="form[f.end_date]"
                            :min="_addDays(sd, 1)"
                            @input="validateField(f.end_date); _ensureEndDate()"
                            @change="validateField(f.end_date); _ensureEndDate()"
                            @click="{$pickerJs}"
                            class="{$dateInputCls}" />
                        {$clientErrEnd}
                    </div>
                </template>
                <!-- Otherwise show contextual explainer (Completed/Never) -->
                <template x-if="!showEndDate">
                    <div>
                        <template x-if="st === 'bulk_mail' && endTab === 'completed'">
                            <p class="text-sm text-gray-500 dark:text-gray-400 leading-relaxed" x-text="t.end_completed_hint"></p>
                        </template>
                        <template x-if="st === 'automation' && ae === 'never'">
                            <p class="text-sm text-gray-500 dark:text-gray-400 leading-relaxed" x-text="t.end_never_hint"></p>
                        </template>
                    </div>
                </template>
            </div>

            <!-- Hidden inputs for end mode persistence -->
            <input type="hidden" :name="f.automation_end" x-model="form[f.automation_end]" />
        </div>
    </div>

    {$errorHtml}
</div>
HTML;
    }
}
