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

use Components\Base;

class FlowViz extends Base
{
    /**
     * Render a campaign flow visualization from a sequence of items.
     * $items: array of elements like
     *   [
     *     ['type'=>'step','id'=>'trigger','title'=>'Last Purchase','subtitle'=>'Trigger','icon'=>'⚡','color'=>'blue', 'markers' => [['color'=>'blue','label'=>'Filter applied']]],
     *     ['type'=>'wait','label'=>'Wait 3 days','icon'=>'⏱', 'index'=>0],
     *     ['type'=>'step','id'=>'step1','title'=>'Reminder Email','subtitle'=>'Step 1','icon'=>'📧','color'=>'indigo', 'markers' => [['color'=>'red','label'=>'Coupon']]],
     *     ['type'=>'add','icon'=>Base::SVG_ADD],
     *     ...
     *   ]
     * $opts:
     *  - orientation: 'horizontal'|'vertical' (default: 'horizontal')
     *  - size: 'xs'|'sm'|'md'|'lg' (default: 'md')
     *  - editable: bool (default: false)
     *  - class: extra classes for wrapper
     */
    public static function render(array $items, array $opts = []): string
    {
        $orientation = $opts['orientation'] ?? 'horizontal';
        $size = $opts['size'] ?? 'md';
        $id = $opts['id'] ?? 'flowViz';
        $editable = (bool)($opts['editable'] ?? false);
        $extraClass = trim((string)($opts['class'] ?? ''));

        $wrapBase = '';
        $dirCls = $orientation === 'vertical'
            ? 'flex flex-col  w-full space-y-2'
            : 'flex items-center shrink max-w-full';

        $wrapperCls = trim($wrapBase . ' ' . $dirCls . ' ' . $extraClass);

        $html = '<div class="' . self::h($wrapperCls) . '" id="' . $id . '">';

        $count = count($items);
        $hasExplicitAdd = false;
        for ($i = 0; $i < $count; $i++) {
            $it = $items[$i];
            $type = $it['type'] ?? 'step';

            // If this item is a 'branch' and previous item wasn't a wait/date_range/add, insert a connector first
            if ($i > 0 && $type === 'branch') {
                $prevType = $items[$i-1]['type'] ?? 'step';
                if ($prevType !== 'wait' && $prevType !== 'date_range' && $prevType !== 'add') {
                    $html .= Connector::render(null, ['orientation' => $orientation, 'size' => $size, 'editable' => $editable]);
                }
            }

            if ($type === 'step') {
                $html .= StepCard::render($it, ['size' => $size, 'editable' => $editable]);
            } elseif ($type === 'wait' || $type === 'condition' || $type === 'date_range') {
                // Render a connector hosting the wait/condition/date_range badge
                // Between adjacent badges, suppress any elements on the left side of the
                // current badge (arrow AND line) so badges move closer and only the
                // previous badge's right arrow remains between them.
                $prevType = $i > 0 ? ($items[$i-1]['type'] ?? null) : null;
                $prevIsBadge = in_array($prevType, ['wait','condition','date_range'], true);
                $nextType = $i < $count - 1 ? ($items[$i+1]['type'] ?? null) : null;
                $nextIsBadge = in_array($nextType, ['wait','condition','date_range'], true);
                $html .= Connector::render($it, [
                    'orientation' => $orientation,
                    'size' => $size,
                    'editable' => $editable,
                    'left_arrow' => !$prevIsBadge,
                    'left_line' => !$prevIsBadge,
                    // If the next item is also a badge, hide the right arrow + line of this badge
                    // so the badges move closer with no line segment between them.
                    'right_arrow' => true, // !$nextIsBadge,
                    'right_line' => true, !$nextIsBadge,
                ]);
            } elseif ($type === 'branch') {
                $html .= BranchViz::render($it, ['size' => $size, 'editable' => $editable, 'addTail' => $opts['addTail'] ?? null]);
            } elseif ($type === 'add') {
                // Explicit AddTail item support
                $hasExplicitAdd = true;
                // Render regardless of overall editable to ensure visibility across sizes
                $html .= AddTail::render([
                    'orientation' => $orientation,
                    'size' => $size,
                    'editable' => true,
                    'href' => $it['href'] ?? null,
                    'attrs' => $it['attrs'] ?? [],
                    'icon' => $it['icon'] ?? null,
                ]);
            } else {
                // Unknown type: skip
                continue;
            }

            // If current is step and next is step (not branch) and there is no explicit wait in between, insert connector
            // Branches are handled explicitly at the beginning of their iteration to avoid duplicate connectors
            if ($type === 'step' && $i < $count - 1) {
                $next = $items[$i+1];
                $nextType = $next['type'] ?? 'step';
                if ($nextType === 'step') {
                    $html .= Connector::render(null, ['orientation' => $orientation, 'size' => $size, 'editable' => $editable]);
                }
            }
        }

        // Add an end-of-flow AddTail when editable, controlled by data param "addTail"
        // The "addTail" flag can be provided either:
        // - in $opts['addTail'] (boolean), or
        // - inside any item in $items as ['addTail' => true|false]
        // Backwards compatible: if not provided, defaults to previous behavior (show when editable).
        $showTail = $opts['addTail'] ?? null;
        foreach ($items as $it) {
            if (array_key_exists('addTail', $it)) {
                $showTail = (bool)$it['addTail'];
                break;
            }
        }
        $showTail = $showTail === null ? $editable : (bool)$showTail;

        if ($showTail && !$hasExplicitAdd) {
//            $html .= Connector::render(null, ['orientation' => $orientation, 'size' => $size, 'editable' => $editable]);
            $html .= AddTail::render(['orientation' => $orientation, 'size' => $size, 'editable' => $editable]);
        }

        $html .= '</div>';
        return $html;
    }
}
