<?php
// components/CampaignFlow/DateRangeBadge.php
namespace Components\CampaignFlow;

use Components\Base;
use Components\Support\Palette;
use Components\Models\NewsletterItem;

class DateRangeBadge extends Base
{
    /**
     * Render a date-range badge, visually aligned with WaitBadge/ConditionBadge.
     * $cfg keys:
     * - from (int|string|null) unix timestamp or strtotime()-parseable, optional
     * - to (int|string|null) unix timestamp or strtotime()-parseable, optional
     * - label (string) optional explicit label; if present, overrides auto range label
     * - icon (string) optional raw HTML; defaults to Base::SVG_CALENDAR
     * - index (int) optional key for editing
     * - disabled (bool)
     * - href (string) optional link
     * - attrs (array) optional attributes
     * - dropdown (array) optional dropdown config (same shape as WaitBadge)
     */
    public static function render(array $cfg, array $opts = []): string
    {

        $size = $opts['size'] ?? 'md'; // xs|sm|md|lg
        $orientation = $opts['orientation'] ?? 'horizontal';
        $editable = (bool)($opts['editable'] ?? false);
        $index = isset($cfg['index']) ? (int)$cfg['index'] : -1;

        $icon = (string)($cfg['icon'] ?? self::SVG_CALENDAR);
        $isDisabled = (bool)($cfg['disabled'] ?? false);

        // Build labels: upper shows start date, lower shows end date
        // Also build a combined title for accessibility/tooltips
        $explicitLabel = isset($cfg['label']) ? (string)$cfg['label'] : '';
        [$labelUpper, $labelLower, $labelTitle] = self::buildRangeLabels($cfg['from'] ?? null, $cfg['to'] ?? null, $explicitLabel !== '' ? $explicitLabel : null);
        $labelUpperEsc = self::h($labelUpper);
        $labelLowerEsc = self::h($labelLower);
        $labelTitleEsc = self::h($labelTitle);

        // Determine schedule state using the model helper and map to palette token
        $fromVal = $cfg['from'] ?? null;
        $toVal = $cfg['to'] ?? null;
        $stateKey = 'active';
        try {
            $tmp = new NewsletterItem([
                'newsletter_item_start' => $fromVal,
                'newsletter_item_end' => $toVal,
            ]);
            $st = $tmp->scheduleState();
            if (is_array($st) && isset($st['state'])) {
                $stateKey = (string)$st['state'];
            }
        } catch (\Throwable $e) {
            // ignore, keep default
        }
        $tokenMap = ['pending' => 'pink', 'active' => 'green', 'past' => 'gray'];
        $token = $tokenMap[$stateKey] ?? 'gray';
        $paletteCls = Palette::classes($token);
        $paletteClsRing = Palette::map()[$token]['ring'] ?? '';
        $href = isset($cfg['href']) ? (string)$cfg['href'] : '';
        $extraAttrs = is_array($cfg['attrs'] ?? null) ? $cfg['attrs'] : [];
        $hasDropdown = !empty($cfg['dropdown']) && is_array($cfg['dropdown']);

        $sizes = [
            'xs' => ['iconWrap' => 'size-5 p-0.5', 'iconText' => 'text-[10px]', 'labelText' => 'hidden', 'pad' => 'px-0', 'gap' => 'mx-0'],
            'sm' => ['iconWrap' => 'size-7 p-1', 'iconText' => 'text-xs', 'labelText' => 'text-[10px] whitespace-nowrap', 'pad' => 'px-1', 'gap' => '-mx-0'],
            'md' => ['iconWrap' => 'size-8 p-2', 'iconText' => 'text-sm', 'labelText' => 'text-xs whitespace-nowrap', 'pad' => 'px-2', 'gap' => '-mx-1'],
            'lg' => ['iconWrap' => 'size-9 p-2', 'iconText' => 'text-base', 'labelText' => 'text-xs whitespace-nowrap', 'pad' => 'px-3', 'gap' => 'mx-1'],
        ];
        $sz = $sizes[$size] ?? $sizes['md'];

        // Add vertical margins in horizontal orientation to make room for labels above and below the icon
        $wrapBase = $orientation == 'vertical' ? 'flex flex-row items-center justify-center space-x-1' : 'flex flex-col items-center ' . $sz['gap'] . ' text-secondary shrink-0';
        // Colorize icon and background using Palette based on schedule state
        $iconWrapCls = 'flex items-center justify-center ' . $sz['iconWrap'] . ' rounded-full ring ' . $paletteCls . ' ' . $paletteClsRing . ' font-bold transition-colors duration-100 group-hover:bg-elevated group-hover:shadow group-hover:ring group-hover:ring-brand';
        $wrapClsBase = trim($wrapBase . ' ' . $sz['pad'] . ' ' . ($opts['class'] ?? ''));
        if ($isDisabled) {
            $wrapClsBase .= ' ' . self::DISABLED_CLASSES;
        }

        $hasAttrs = !empty($cfg['attrs']) && is_array($cfg['attrs']);
        $hasHref = isset($cfg['href']) && (string)$cfg['href'] !== '';
        $willHaveDropdown = !empty($cfg['dropdown']) && is_array($cfg['dropdown']);
        $isInteractive = !$isDisabled && ($hasHref || $hasAttrs || $willHaveDropdown);
        if ($isInteractive) {
            $wrapClsBase .= ' cursor-pointer group';
        }
        $outerClass = trim('relative daterange-badge ' . $wrapClsBase);

        $iconWrapEsc = self::h($iconWrapCls);
        $labelBaseCls = 'rounded bg-surface px-1 ' . $sz['labelText'] . ' transition-colors duration-100 group-hover:bg-elevated group-hover:shadow group-hover:ring ring-brand';
        $upperPosCls = 'absolute -top-3';
        $lowerPosCls = 'absolute -bottom-3';
        if ($orientation === 'vertical') {
            // Keep absolute positioning for consistency in both orientations
            // (outer wrapper is relative)
        }
        $upperLabelHtml = $labelUpperEsc !== '' ? '<div class="' . self::h(trim($upperPosCls . ' ' . $labelBaseCls)) . '">' . $labelUpperEsc . '</div>' : '';
        $lowerLabelHtml = $labelLowerEsc !== '' ? '<div class="' . self::h(trim($lowerPosCls . ' ' . $labelBaseCls)) . '">' . $labelLowerEsc . '</div>' : '';

        $badgeInner = <<<HTML
  $upperLabelHtml
  <div class="$iconWrapEsc" title="$labelTitleEsc">$icon</div>
  $lowerLabelHtml
HTML;

        if ($hasDropdown) {
            $dd = $cfg['dropdown'];
            $tr = is_array($dd['trigger'] ?? null) ? $dd['trigger'] : [];
            $items = is_array($dd['items'] ?? null) ? $dd['items'] : [];

            $triggerAttrs = array_merge(['class' => $outerClass, 'type' => 'button'], is_array($tr['attrs'] ?? null) ? $tr['attrs'] : []);
            if ($isDisabled) { $triggerAttrs['aria-disabled'] = 'true'; $triggerAttrs['disabled'] = true; }

            return \Components\Dropdown::render([
                'trigger_tag' => 'button',
                'trigger_attrs' => $triggerAttrs,
                'trigger_html' => $badgeInner,
                'items' => $items,
                'anchor' => 'bottom start',
                'popover' => 'manual',
                'wrapper_class' => 'inline-flex relative',
            ]);
        }

        $outerTag = ($href !== '') ? 'a' : ((!empty($extraAttrs)) ? 'button' : 'div');
        $outerAttrs = ['class' => $outerClass];
        if ($href !== '' && $outerTag === 'a') { $outerAttrs['href'] = $href; }
        if ($outerTag === 'button') { $outerAttrs['type'] = 'button'; }
        if ($isDisabled) { $outerAttrs['aria-disabled'] = 'true'; if ($outerTag === 'button') { $outerAttrs['disabled'] = true; } }
        foreach ($extraAttrs as $k => $v) { $outerAttrs[$k] = $v; }
        $outerAttrStr = self::attrs($outerAttrs);

        $html = <<<HTML
<{$outerTag}{$outerAttrStr}>
{$badgeInner}
</{$outerTag}>
HTML;
        return $html;
    }

    /**
     * Build a concise label for a date range.
     */
    public static function buildRangeLabel($from, $to): string
    {

        $fmt = function ($v): ?\DateTime {
            if ($v === null || $v === '') return null;
            if (is_int($v)) {
                $dt = (new \DateTime('@' . $v));
                $dt->setTimezone(new \DateTimeZone(date_default_timezone_get()));
                return $dt;
            }
            if (is_string($v)) {
                $ts = strtotime($v);
                if ($ts !== false) {
                    $dt = (new \DateTime('@' . $ts));
                    $dt->setTimezone(new \DateTimeZone(date_default_timezone_get()));
                    return $dt;
                }
            }
            return null;
        };

        $df = $fmt($from);
        $dt = $fmt($to);

        if ($df && $dt) {
            // If same month/year, compact form: 1–12 Dec 2025
            if ($df->format('Ym') === $dt->format('Ym')) {
                return $df->format('j') . '–' . $dt->format('j M Y');
            }
            return $df->format('j M Y') . ' → ' . $dt->format('j M Y');
        }
        if ($df) {
            return 'From ' . $df->format('j M Y');
        }
        if ($dt) {
            return 'Until ' . $dt->format('j M Y');
        }
        return 'Date range';
    }

    /**
     * Build split labels suitable for rendering above/below the icon.
     * Returns [upper, lower, title]
     * - upper: formatted start date (e.g., 1 Dec 2025) or '' if not set
     * - lower: formatted end date (e.g., 12 Dec 2025) or '' if not set
     * - title: combined readable label (using buildRangeLabel)
     * If $overrideLabel is provided, it will be used as the title and placed as the lower label,
     * leaving the upper empty to avoid double text. This preserves previous API behavior where
     * a custom label replaces autogenerated content.
     */
    public static function buildRangeLabels($from, $to, ?string $overrideLabel = null): array
    {
        $fmt = function ($v): ?\DateTime {
            if ($v === null || $v === '') return null;
            if (is_int($v)) {
                $dt = (new \DateTime('@' . $v));
                $dt->setTimezone(new \DateTimeZone(date_default_timezone_get()));
                return $dt;
            }
            if (is_string($v)) {
                $ts = strtotime($v);
                if ($ts !== false) {
                    $dt = (new \DateTime('@' . $ts));
                    $dt->setTimezone(new \DateTimeZone(date_default_timezone_get()));
                    return $dt;
                }
            }
            return null;
        };

        if ($overrideLabel !== null && $overrideLabel !== '') {
            $title = $overrideLabel;
            return ['', $overrideLabel, $title];
        }

        $df = $fmt($from);
        $dt = $fmt($to);

        $upper = $df ? $df->format('j M Y') : '';
        $lower = $dt ? $dt->format('j M Y') : '';
        $title = self::buildRangeLabel($from, $to);
        // Fallback: if both dates are empty, show the combined title as the lower label for visibility
        if ($upper === '' && $lower === '' && $title !== '') {
            $lower = $title;
        }

        return [$upper, $lower, $title];
    }
}
