<?php
// pages/components/newsletter_collection_list.php
// Collections sidebar for NewsletterCampaigns using the new CollectionsList design
use Components\Router as R;
use Components\Base;
use Components\Models\NewsletterCampaign;
use Components\Models\NewsletterItem;
use Components\Resources\CollectionsList;
use Components\Support\Palette;
use Components\Newsletter\PageConfig;


$pageConfig = PageConfig::fromRequest();
$allowedTypes = $pageConfig->allowed_types;
$selectedGroup = mh_get('group', '', 'string');
$groupParam = $selectedGroup !== '' ? ['group' => $selectedGroup] : [];
if ($pageConfig->mode !== PageConfig::MODE_NEWSLETTER) {
    $groupParam['page_mode'] = $pageConfig->mode;
}

// Refresh URL intentionally omits the group param: the sidebar lists all collections regardless
// of the currently selected one. The active highlight is driven by Alpine's selectedSlug,
// and baking a stale group into hx-get would cause spurious ?group=campaign-N on every refresh.
$refreshUrl = R::url('newsletter_collection_list', ['partial' => 1, 'page_mode' => $pageConfig->mode]);
$initialSlug = $selectedGroup !== '' ? $selectedGroup : $pageConfig->default_smart_group;

// Build collections (campaigns) with counts and colors
$collections = [];
$archived = [];
$recentLimit = 10;

// Smart collection counts via SQL (efficient: no full row loading)
$nlUiState      = \Components\ConfigStore::getNewsletterUiState($pageConfig->mode);
$smartTimeframe = isset($nlUiState['smart_timeframe']) && (int)$nlUiState['smart_timeframe'] > 0 ? (int)$nlUiState['smart_timeframe'] : 180;

$smartFavorite   = 0;
$smartRecent     = 0;
$smartActive     = 0;
$smartScheduled  = 0;
$smartDraft      = 0;
$smartPaused     = 0;
$smartCompleted  = 0;

if (function_exists('mh_db_query')) {
    // Single COUNT queries — no PHP-level filtering

    try { $smartAll       = NewsletterItem::countAll($allowedTypes); }           catch (\Throwable $e) { $smartAll = 0; }
    try { $smartFavorite  = NewsletterItem::countSmart('favorite', 10, 0, $allowedTypes); }  catch (\Throwable $e) { $smartFavorite = 0; }
    try { $smartRecent    = NewsletterItem::countSmart('recent', $recentLimit, $smartTimeframe, $allowedTypes); } catch (\Throwable $e) { $smartRecent = 0; }
    try { $smartActive    = NewsletterItem::countSmart('active', 10, 0, $allowedTypes); }    catch (\Throwable $e) { $smartActive = 0; }
    try { $smartScheduled = NewsletterItem::countSmart('scheduled', 10, 0, $allowedTypes); } catch (\Throwable $e) { $smartScheduled = 0; }
    try { $smartDraft     = NewsletterItem::countSmart('draft', 10, $smartTimeframe, $allowedTypes); }     catch (\Throwable $e) { $smartDraft = 0; }
    try { $smartPaused     = NewsletterItem::countSmart('paused', 10, 0, $allowedTypes); }     catch (\Throwable $e) { $smartPaused = 0; }
    try { $smartCompleted  = NewsletterItem::countSmart('completed', 10, $smartTimeframe, $allowedTypes); } catch (\Throwable $e) { $smartCompleted = 0; }

    // Manual and archived collections derived from campaigns
    // Count items per campaign via a single SQL GROUP BY query to avoid N+1 loads
    $campaignCounts = [];
    try {
        $typeFilter = "schedule_type IN ('" . implode("','", array_map('\\mh_db_input', $allowedTypes)) . "')";
        $q = \mh_db_query(
            "SELECT newsletter_campaign_id, COUNT(*) AS cnt FROM " . NewsletterItem::table() .
            " WHERE COALESCE(newsletter_followup_id, 0) = 0 AND {$typeFilter}" .
            " GROUP BY newsletter_campaign_id"
        );
        while ($row = \mh_db_fetch_array($q)) {
            $campaignCounts[(int)$row['newsletter_campaign_id']] = (int)$row['cnt'];
        }
        \mh_db_free_result($q);
    } catch (\Throwable $e) { /* fallback to 0 counts */ }

    foreach (NewsletterCampaign::all($pageConfig->mode) as $campaign) {
        $cid = (int)($campaign->newsletter_campaign_id ?? 0);
        if ($cid <= 0) { continue; }
        $name = (string)($campaign->newsletter_campaign_name ?? sprintf(
            (string)mh_lng('UI_NEWSLETTER_COLLECTION_CAMPAIGN_FALLBACK', 'Campaign %s'),
            (string)$cid
        ));
        $description = (string)($campaign->newsletter_campaign_description ?? '');
        $count = $campaignCounts[$cid] ?? 0;
        // Uses NewsletterCampaign accessor: `newsletter_campaign_color()` provides deterministic fallback
        $dot = (string)($campaign->newsletter_campaign_color ?? '');
        $isArchived = ($campaign->newsletter_campaign_archived == 1);
        $entry = [
            'id'          => $cid,
            'slug'        => 'campaign-' . $cid,
            'attrs'       => [
                'hx-get' => R::url('newsletter_collection_list', ['partial' => 1, 'group' => 'campaign-' . $cid, 'page_mode' => $pageConfig->mode]),
            ],
            'name'        => $name,
//            'name_html'   => \Components\Base::h($name) . ' ' . $campaign->getApplicabilityBadgeHtml(),
            'description' => $description,
            'dot_class'   => $dot,
            'count'       => $count,
            'is_archived' => $isArchived,
        ];
        if ($isArchived) {
            $archived[] = $entry;
        } else {
            $collections[] = $entry;
        }
    }
}

// Smart section entries: recently edited, active, scheduled, draft
$smart = [];
foreach (NewsletterItem::smartCollectionDefs() as $key => $def) {
    if ($key === 'completed' && !$pageConfig->show_completed) {
        continue;
    }
    // Determine count variable name (e.g., $smartFavorite, $smartRecent, etc.)
    $countVarName = 'smart' . ucfirst($key);
    $countValue   = isset($$countVarName) ? (int)$$countVarName : 0;

    // Build the dynamic UI classes based on the color token
    $token        = (string)$def['color_token'];
    $dotClass     = "bg-{$token}-500";
    $cardBg       = "bg-{$token}-500/70 saturate-80";
    $cardBgActive = "bg-{$token}-500/90";

    // Completed has a slightly softer background in the original design
    if ($key === 'completed') {
        $cardBg = "bg-{$token}-500/50";
    }

    $smart[] = [
        'id'             => (int)$def['id'],
        'slug'           => (string)$def['slug'],
        'name'           => mh_lng((string)$def['name_key'], (string)$def['name_fallback']),
        'dot_class'      => $dotClass,
        'card_bg'        => $cardBg,
        'card_bg_active' => $cardBgActive,
        'icon'           => (string)$def['icon'],
        'count'          => $countValue,
    ];
}

// Always-visible smart filters rendered above the collapsible Smart section
$smartFixedSlugs = ['smart-active', 'smart-scheduled'];
$smartFixed = [];
$smartCollapsible = [];
foreach ($smart as $smartItem) {
    if (in_array((string)($smartItem['slug'] ?? ''), $smartFixedSlugs, true)) {
        $smartFixed[] = $smartItem;
        continue;
    }
    $smartCollapsible[] = $smartItem;
}

// Read smart layout + hidden from per-user newsletter UI state (new storage)
$smartLayout = isset($nlUiState['smart_layout']) ? (string)$nlUiState['smart_layout'] : 'cards';
if (!in_array($smartLayout, ['cards', 'list'], true)) { $smartLayout = 'cards'; }
$smartIsCards = ($smartLayout === 'cards');

// Hidden smart slugs stored as array in the new state key
$smartHidden = isset($nlUiState['smart_hidden']) && is_array($nlUiState['smart_hidden'])
    ? array_values(array_map('strval', $nlUiState['smart_hidden']))
    : [];

// Persisted section open states
$sectionsOpen = isset($nlUiState['sections_open']) && is_array($nlUiState['sections_open'])
    ? $nlUiState['sections_open']
    : [];
$sectionSmartOpen   = !array_key_exists('smart',   $sectionsOpen) || !empty($sectionsOpen['smart']);
$sectionManualOpen  = !array_key_exists('manual',  $sectionsOpen) || !empty($sectionsOpen['manual']);
$sectionArchiveOpen = !empty($sectionsOpen['archive']);

// Manual/Archive UI options
$collectionsUi = isset($nlUiState['collections_show_description']) && is_array($nlUiState['collections_show_description'])
    ? $nlUiState['collections_show_description']
    : [];
$manualShowDescription  = !empty($collectionsUi['manual']);
$archiveShowDescription = !empty($collectionsUi['archive']);

// Filter collapsible smart items: remove hidden ones ("smart-recent" is always visible)
$smartVisible = array_values(array_filter($smartCollapsible, function ($item) use ($smartHidden) {
    if (($item['slug'] ?? '') === 'smart-recent') {
        return true;
    }
    return !in_array((string)($item['slug'] ?? ''), $smartHidden, true);
}));

// Save URL for async persistence of section open state
$saveStateUrl = R::url('newsletter_ui_state_save', ['partial' => 1]);
$saveStateUrlEsc = \Components\Base::h($saveStateUrl, false);

// Helper: render a collapsible section with a title, optional dropdown, and a CollectionsList
$renderSection = function (string $title, array $items, string $selectedSlug, bool $startOpen = true, string $layout = 'list', array $dropdownItems = [], string $sectionKey = '', array $extraListOptions = []) use ($saveStateUrlEsc, $pageConfig) {
    $open        = $startOpen ? 'true' : 'false';
    $dropdownHtml = $dropdownItems
        ? CollectionsList::renderSectionDropdown(['items' => $dropdownItems])
        : '';
    $sectionKeyEsc = \Components\Base::h($sectionKey, false);
    // Persist open state when toggled; only if we have a key
    $clickHandler = $sectionKey !== ''
        ? "open = !open; fetch('" . $saveStateUrlEsc . "', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'X-Requested-With': 'XMLHttpRequest' }, body: new URLSearchParams({ state_patch: JSON.stringify({ sections_open: { '" . $sectionKeyEsc . "': open } }) }).toString() }).catch(()=>{})"
        : 'open = !open';
    ?>
    <div class="group/section" x-data="{ open: <?= $open; ?> }">
        <div class="group/collection  flex items-center justify-between px-2 pt-1 pb-2 cursor-pointer select-none" @click="<?= \Components\Base::h($clickHandler, false); ?>">
            <span class="text-xs uppercase tracking-wide text-secondary"><?= \Components\Base::h($title, false); ?></span>
            <span class="flex items-center gap-1">
                <?php if ($dropdownHtml): ?>
                    <?= $dropdownHtml; ?>
                <?php endif; ?>
                <div class=" min-w-12 flex justify-end">
                        <span :class="{ 'rotate-180': open }" class="size-4 shrink-0 text-secondary [&_svg]:size-4">
                        <?php echo \Components\Base::SVG_CHEVRON_DOWN; ?>
                    </span>
                </div>
            </span>
        </div>
        <div x-show="open" x-collapse x-cloak>
            <?php
            echo CollectionsList::render(array_merge([
                'items' => $items,
                'selected_slug' => $selectedSlug,
                'page_key' => $pageConfig->mode,
                'layout' => $layout,
            ], $extraListOptions));
            ?>
        </div>
    </div>
    <?php
};

$activeSlug = $selectedGroup !== '' ? $selectedGroup : 'smart-active';

?>
<div
    id="<?= $pageConfig->getTargetId('campaigns-list'); ?>"
    hx-get="<?= $refreshUrl; ?>"
    hx-trigger="<?= $pageConfig->getEventName('campaigns:refresh'); ?> from:body, <?= $pageConfig->getEventName('campaigns:created'); ?> from:body, <?= $pageConfig->getEventName('campaigns:updated'); ?> from:body, <?= $pageConfig->getEventName('newsletter_item:deleted'); ?> from:body, <?= $pageConfig->getEventName('newsletter_item:collections:refresh'); ?> from:body"
    hx-swap="outerHTML"
    data-no-global-loader="1"
    data-no-local-loader="1"
    class="min-w-0"
>
<!-- inner-start -->
<div id="<?= $pageConfig->getTargetId('campaigns-list-inner'); ?>" class="space-y-6">
    <?php
    // Build dropdown items for the Smart section
    $toggleLayoutUrl   = R::url('newsletter_smart_config_toggle', ['toggle' => 'toggle_layout', 'page_mode' => $pageConfig->mode]);
    $toggleLayoutLabel = $smartIsCards
        ? mh_lng('UI_NEWSLETTER_COLLECTION_LAYOUT_LIST', 'List layout')
        : mh_lng('UI_NEWSLETTER_COLLECTION_LAYOUT_CARDS', 'Cards layout');
    $toggleVisibilityUrl = function (string $slug) use ($pageConfig) {
        return R::url('newsletter_smart_config_toggle', ['toggle' => 'toggle_visibility', 'slug' => $slug, 'page_mode' => $pageConfig->mode]);
    };

    $smartDropdownItems = [
        [
            'label' => $toggleLayoutLabel,
            'icon'  => $smartIsCards ? \Components\Base::SVG_BARS_4 : \Components\Base::SVG_CARDS,
            'attrs' => [
                '@click.stop'           => '',
                'hx-post'               => $toggleLayoutUrl,
                'hx-target'             => '#' . $pageConfig->getTargetId('campaigns-list'),
                'hx-swap'               => 'outerHTML',
                'data-no-global-loader' => '1',
            ],
        ],
        ['divider' => true],
    ];
    // Visibility toggles for each smart list except 'smart-recent' (always shown)
    foreach ($smartCollapsible as $smartItem) {
        $slug  = $smartItem['slug'];
        if ($slug === 'smart-recent') { continue; }
        $isVisible = !in_array($slug, $smartHidden, true);
        $smartDropdownItems[] = [
            'label' => $smartItem['name'],
            'icon'  => $isVisible ? \Components\Base::SVG_MICRO_CHECK : '<span class="opacity-0">' . \Components\Base::SVG_MICRO_CHECK . '</span>',
            'attrs' => [
                '@click.stop'           => '',
                'hx-post'               => $toggleVisibilityUrl($slug),
                'hx-target'             => '#' . $pageConfig->getTargetId('campaigns-list'),
                'hx-swap'               => 'outerHTML',
                'data-no-global-loader' => '1',
            ],
        ];
    }

    $timeframeOptions = \Components\Models\NewsletterItem::smartTimeframeOptions();
    $smartDropdownItems[] = ['divider' => true];
    $smartDropdownItems[] = [
        'label' => mh_lng('UI_TIMEFRAME_LABEL', 'Timeframe'),
        'attrs' => ['disabled' => true, 'class' => 'opacity-50 font-bold uppercase text-[10px] tracking-wider py-1']
    ];
    foreach ($timeframeOptions as $days => $label) {
        $isActive = ($smartTimeframe === $days);
        $smartDropdownItems[] = [
            'label' => $label,
            'icon'  => $isActive ? \Components\Base::SVG_MICRO_CHECK : '<span class="opacity-0">' . \Components\Base::SVG_MICRO_CHECK . '</span>',
            'attrs' => [
                '@click.stop'           => '',
                'hx-post'               => R::url('newsletter_smart_config_toggle', ['toggle' => 'set_timeframe', 'timeframe' => $days, 'page_mode' => $pageConfig->mode]),
                'hx-target'             => '#' . $pageConfig->getTargetId('campaigns-list'),
                'hx-swap'               => 'outerHTML',
                'data-no-global-loader' => '1',
            ],
        ];
    }

    // Manual/Archive dropdown items (toggle description second line)
    $toggleCollectionsDescUrl = function (string $section) use ($pageConfig) {
        return R::url('newsletter_collections_config_toggle', ['toggle' => 'toggle_description', 'section' => $section, 'page_mode' => $pageConfig->mode]);
    };
    $descIcon = function (bool $on) {
        return $on
            ? \Components\Base::SVG_MICRO_CHECK
            : '<span class="opacity-0">' . \Components\Base::SVG_MICRO_CHECK . '</span>';
    };
    $manualDropdownItems = [
        [
            'label' => mh_lng('UI_COLLECTIONS_NEW', 'New collection'),
            'icon'  => \Components\Base::SVG_PLUS,
            'attrs' => [
                'command' => 'show-modal',
                'commandfor' => 'config-modal',
                'data-title' => mh_lng('UI_COLLECTIONS_NEW_TITLE', 'New Collection'),
                'data-size' => 'xl',
                'hx-get' => \Components\Router::url('newsletter_collection_modal', ['partial' => 1, 'mode' => 'new', 'page_mode' => $pageConfig->mode]),
                'hx-target' => '#config-modal-body',
                'hx-swap' => 'innerHTML',
                'data-no-global-loader' => '1',
                'data-no-local-loader' => '1',
            ],
        ],
        ['divider' => true],
        [
            'label' => mh_lng('UI_NEWSLETTER_COLLECTION_SHOW_DESCRIPTIONS', 'Show descriptions'),
            'icon'  => $descIcon($manualShowDescription),
            'attrs' => [
                '@click.stop'           => '',
                'hx-post'               => $toggleCollectionsDescUrl('manual'),
                'hx-target'             => '#' . $pageConfig->getTargetId('campaigns-list'),
                'hx-swap'               => 'outerHTML',
                'data-no-global-loader' => '1',
            ],
        ],
    ];
    $archiveDropdownItems = [
        [
            'label' => mh_lng('UI_COLLECTIONS_NEW', 'New collection'),
            'icon'  => \Components\Base::SVG_PLUS,
            'attrs' => [
                'command' => 'show-modal',
                'commandfor' => 'config-modal',
                'data-title' => mh_lng('UI_COLLECTIONS_NEW_TITLE', 'New Collection'),
                'data-size' => 'xl',
                'hx-get' => \Components\Router::url('newsletter_collection_modal', ['partial' => 1, 'mode' => 'new', 'preset_archived' => 1, 'page_mode' => $pageConfig->mode]),
                'hx-target' => '#config-modal-body',
                'hx-swap' => 'innerHTML',
                'data-no-global-loader' => '1',
                'data-no-local-loader' => '1',
            ],
        ],
        ['divider' => true],
        [
            'label' => mh_lng('UI_NEWSLETTER_COLLECTION_SHOW_DESCRIPTIONS', 'Show descriptions'),
            'icon'  => $descIcon($archiveShowDescription),
            'attrs' => [
                '@click.stop'           => '',
                'hx-post'               => $toggleCollectionsDescUrl('archive'),
                'hx-target'             => '#' . $pageConfig->getTargetId('campaigns-list'),
                'hx-swap'               => 'outerHTML',
                'data-no-global-loader' => '1',
            ],
        ],
    ];
    ?>
    <?php
    $sectionLiveTitle = mh_lng('UI_NEWSLETTER_COLLECTION_SECTION_LIVE', 'Live');
    $sectionSmartTitle = mh_lng('UI_NEWSLETTER_COLLECTION_SECTION_SMART', 'Smart');
    $sectionManualTitle = mh_lng('UI_NEWSLETTER_COLLECTION_SECTION_MANUAL', 'Manual');
    $sectionArchiveTitle = mh_lng('UI_NEWSLETTER_COLLECTION_SECTION_ARCHIVE', 'Archive');
    ?>
    <div class="space-y-6">
        <div>
            <div class="group/collection flex items-center justify-between px-2 pt-1 pb-2 select-none">
                <span class="text-xs uppercase tracking-wide text-secondary"><?= Base::h($sectionLiveTitle, false); ?></span>
            </div>
            <?php
            echo CollectionsList::render([
                'items' => $smartFixed,
                'selected_slug' => $activeSlug,
                'page_key' => $pageConfig->mode,
                'layout' =>  'cards',
            ]);
            ?>
        </div>
        <?php $renderSection($sectionSmartTitle, $smartVisible, $activeSlug, $sectionSmartOpen, $smartIsCards ? 'cards' : 'list', $smartDropdownItems, 'smart'); ?>
    </div>
    <?php $renderSection($sectionManualTitle, $collections, $activeSlug, $sectionManualOpen, 'list', $manualDropdownItems, 'manual', ['show_description' => $manualShowDescription]); ?>
    <?php $renderSection($sectionArchiveTitle, $archived, $activeSlug, $sectionArchiveOpen, 'list', $archiveDropdownItems, 'archive', ['empty_state_url_params' => ['preset_archived' => 1], 'show_description' => $archiveShowDescription]); ?>
</div>
<!-- inner-end -->
</div>
<?php
// OOB: keep the collapsed-sidebar overlay in sync with the main sidebar.
// IMPORTANT: Only emit OOB when this component endpoint itself is requested (partial=1).
// Otherwise (e.g., when this sidebar is embedded in a full-page HTMX navigation or preload),
// the OOB target may not exist in the current DOM and HTMX will log `htmx:oobErrorNoTarget`.
if (empty($isNewsletterPageInclude) && !empty($_SERVER['HTTP_HX_REQUEST']) && (int)mh_get('partial', 0, 'int') === 1) {
    ob_start();
    echo '<div class="space-y-6"><div>';
    echo '<div class="group/collection flex items-center justify-between px-2 pt-1 pb-2 select-none">';
    echo '<span class="text-xs uppercase tracking-wide text-secondary">' . Base::h($sectionLiveTitle, false) . '</span>';
    echo '</div>';
    echo CollectionsList::render([
        'items' => $smartFixed,
        'selected_slug' => $activeSlug,
        'page_key' => $pageConfig->mode,
        'layout' => $smartIsCards ? 'cards' : 'list',
    ]);
    echo '</div>';
    $renderSection($sectionSmartTitle, $smartVisible, $activeSlug, $sectionSmartOpen, $smartIsCards ? 'cards' : 'list', $smartDropdownItems, 'smart');
    echo '</div>';
    $renderSection($sectionManualTitle, $collections, $activeSlug, $sectionManualOpen, 'list', $manualDropdownItems, 'manual', ['show_description' => $manualShowDescription]);
    $renderSection($sectionArchiveTitle, $archived, $activeSlug, $sectionArchiveOpen, 'list', $archiveDropdownItems, 'archive', ['empty_state_url_params' => ['preset_archived' => 1], 'show_description' => $archiveShowDescription]);
    $overlayContent = ob_get_clean();
    echo '<div id="' . $pageConfig->getTargetId('collections-overlay-inner') . '" hx-swap-oob="innerHTML">' . $overlayContent . '</div>';
}
?>
