<?php
namespace Components\Data\Live;

use Components\Data\Contracts\NewsletterProvider;
use Components\Data\Mock\MockNewsletterProvider;
use Components\Data\DataRegistry;

/**
 * Live Newsletter provider.
 * Implements collections() by reading legacy MailBeez newsletter campaigns and counting items.
 * If the legacy runtime is not available, gracefully falls back to mock data.
 */
class LiveNewsletterProvider implements NewsletterProvider
{
    private static function isDev(): bool
    {
        return DataRegistry::isDev();
    }

    private function mock(): MockNewsletterProvider
    {
        return new MockNewsletterProvider();
    }

    /**
     * campaigns is alias for collections
     * Build collections from TABLE_MAILBEEZ_NEWSLETTER_CAMPAIGNS with counts from TABLE_MAILBEEZ_NEWSLETTER_ITEMS.
     * Mirrors the logic from mb_newsletter/admin_application_plugins/newsletter_campaigns.php (no pagination).
     */
    public function collections(): array
    {
        // Ensure legacy environment is available
        if (self::isDev()
            || !defined('TABLE_MAILBEEZ_NEWSLETTER_CAMPAIGNS') || !defined('TABLE_MAILBEEZ_NEWSLETTER_ITEMS')) {
            return $this->mock()->collections();
        }

        $collections = [];

        // Query all campaigns ordered by newest first (same as legacy file)
        $sql = "select * from " . TABLE_MAILBEEZ_NEWSLETTER_CAMPAIGNS . " order by newsletter_campaign_id DESC";
        try {
            $q = mh_db_query($sql);
        } catch (\Throwable $e) {
            // On DB error, fall back to mock so UI stays functional
            return $this->mock()->collections();
        }

        // Simple color palette for visual distinction; deterministic by id
        $palette = ['#6b7280', '#6366f1', '#10b981', '#f59e0b', '#ef4444', '#8b5cf6', '#14b8a6', '#84cc16'];

        while ($row = mh_db_fetch_array($q)) {
            $id = (int)($row['newsletter_campaign_id'] ?? 0);
            if ($id <= 0) { continue; }

            // Count related newsletter items
            $cnt = 0;
            try {
                $sqlCnt = "select count(*) as cnt from " . TABLE_MAILBEEZ_NEWSLETTER_ITEMS . " where newsletter_campaign_id='" . $id . "'";
                $qc = mh_db_query($sqlCnt);
                $rc = mh_db_fetch_array($qc);
                $cnt = isset($rc['cnt']) ? (int)$rc['cnt'] : 0;
            } catch (\Throwable $e) {
                // ignore, leave $cnt as 0
            }

            // Derive a slug; ensure it's stable and unique using id
            $name = (string)($row['newsletter_campaign_name'] ?? ('Campaign ' . $id));
            $slug = 'campaign-' . $id;

            // Pick a color based on id for stability
            $color = $palette[$id % count($palette)];

            $collections[] = [
                'id' => $id,
                'slug' => $slug,
                'name' => $name,
                'color' => $color,
                'count' => $cnt,
            ];
        }

        return $collections;
    }

    public function flows(): array
    {
        // Ensure legacy environment is available
        if (self::isDev()
            || !defined('TABLE_MAILBEEZ_NEWSLETTER_ITEMS') || !defined('TABLE_MAILBEEZ_NEWSLETTER_CAMPAIGNS')) {
            return $this->mock()->flows();
        }

        try {
            // Pull all newsletter items with their campaign and relevant fields.
            $sql = "select ".
                " n.newsletter_item_id, n.newsletter_item_name, n.newsletter_item_description, ".
                " n.newsletter_item_start, n.newsletter_item_end, n.last_modified, n.date_added, n.status, ".
                " n.newsletter_list_id, n.newsletter_item_type, n.newsletter_followup_id, ".
                " n.newsletter_coupon_id, n.newsletter_coupon_expire_days, ".
                " n.newsletter_campaign_id, ".
                " c.newsletter_list_id as campaign_newsletter_list_id".
                " from " . TABLE_MAILBEEZ_NEWSLETTER_ITEMS . " n join " . TABLE_MAILBEEZ_NEWSLETTER_CAMPAIGNS . " c on (c.newsletter_campaign_id = n.newsletter_campaign_id)".
                " order by n.newsletter_campaign_id DESC, n.newsletter_item_id DESC";

            $q = mh_db_query($sql);
        } catch (\Throwable $e) {
            return $this->mock()->flows();
        }

        // Group items per campaign and by main/follow-up for flattening
        $byCampaign = [];
        while ($row = mh_db_fetch_array($q)) {
            $cid = (int)($row['newsletter_campaign_id'] ?? 0);
            if (!isset($byCampaign[$cid])) {
                $byCampaign[$cid] = [
                    'main' => [],
                    'followups' => [],
                ];
            }
            $parentId = (int)($row['newsletter_followup_id'] ?? 0);
            $type = (int)($row['newsletter_item_type'] ?? 0);
            // Classification per requirements with graceful fallback for inconsistent data
            if ($parentId === 0 && $type === 0) {
                $byCampaign[$cid]['main'][] = $row;
            } elseif ($parentId > 0 && $type === 1) {
                if (!isset($byCampaign[$cid]['followups'][$parentId])) {
                    $byCampaign[$cid]['followups'][$parentId] = [];
                }
                $byCampaign[$cid]['followups'][$parentId][] = $row;
            } else {
                // Fallback: if a parent id is set, treat as follow-up; otherwise main
                if ($parentId > 0) {
                    if (!isset($byCampaign[$cid]['followups'][$parentId])) {
                        $byCampaign[$cid]['followups'][$parentId] = [];
                    }
                    $byCampaign[$cid]['followups'][$parentId][] = $row;
                } else {
                    $byCampaign[$cid]['main'][] = $row;
                }
            }
        }

        // Helper to flatten follow-ups depth-first, same order as legacy iterateFollowups
        $flatten = function(array $mainItem, array $followMap, array $stack = [], int $level = 0) use (&$flatten) {
            $mainItem['_level'] = $level;
            $stack[] = $mainItem;
            $id = (int)($mainItem['newsletter_item_id'] ?? 0);
            if (isset($followMap[$id]) && is_array($followMap[$id])) {
                foreach ($followMap[$id] as $child) {
                    $stack = $flatten($child, $followMap, $stack, $level + 1);
                }
            }
            return $stack;
        };

        $flows = [];

        // Sort campaigns by id DESC to mirror legacy UI overall grouping
        $campaignIds = array_keys($byCampaign);
        rsort($campaignIds, SORT_NUMERIC);

        foreach ($campaignIds as $cid) {
            $data = $byCampaign[$cid];
            foreach ($data['main'] as $main) {
                $flat = $flatten($main, $data['followups']);
                foreach ($flat as $row) {
                    $flows[] = $this->mapRowToFlow($row);
                }
            }
        }

        return $flows;
    }

    private function mapRowToFlow(array $row): array
    {
        // Status mapping: legacy stores 'True'/'False' strings
        $statusRaw = isset($row['status']) ? (string)$row['status'] : '';
        $status = (strcasecmp($statusRaw, 'True') === 0 || $statusRaw === '1') ? 'Active' : 'Draft';

        // Dates normalized to Y-m-d when possible
        $toDate = function($v) {
            if (!$v) { return null; }
            $ts = @strtotime((string)$v);
            if ($ts === false || $ts <= 0) { return null; }
            return date('Y-m-d', $ts);
        };
        $start = $toDate($row['newsletter_item_start'] ?? null);
        $end   = $toDate($row['newsletter_item_end'] ?? null);

        // Target list (only for non-followups, following legacy display)
        $targetList = null;
        $isFollowup = ((int)($row['newsletter_followup_id'] ?? 0)) !== 0;
        if (!$isFollowup) {
            $type = null; $name = null;
            if (class_exists('sourcebeez')) {
                try {
                    if (method_exists('sourcebeez', 'get_list_source_type')) {
                        $type = \sourcebeez::get_list_source_type($row['newsletter_list_id'] ?? null, $row['campaign_newsletter_list_id'] ?? null);
                    }
                    if (method_exists('sourcebeez', 'get_list_name')) {
                        $name = \sourcebeez::get_list_name($row['newsletter_list_id'] ?? null, $row['campaign_newsletter_list_id'] ?? null);
                    }
                } catch (\Throwable $e) { /* ignore */ }
            }
            if ($type || $name) {
                $targetList = ($type ? (string)$type : '') . ($type && $name ? ': ' : '') . ($name ? (string)$name : '');
            }
        }

        // Tags: annotate followups and coupon usage
        $tags = [];
        if ($isFollowup || (isset($row['newsletter_item_type']) && (int)$row['newsletter_item_type'] === 1)) { $tags[] = 'followup'; }
        if (!empty($row['newsletter_coupon_id'])) { $tags[] = 'coupon'; }

        // Visualize depth by prefixing name with arrows for follow-ups
        $level = (int)($row['_level'] ?? 0);
        $rawName = (string)($row['newsletter_item_name'] ?? 'Untitled');
        $prefix = $level > 0 ? str_repeat('↳ ', $level) : '';
        $displayName = $prefix . $rawName;

        return [
            'id' => (int)($row['newsletter_item_id'] ?? 0),
            'name' => $displayName,
            'collection_id' => (int)($row['newsletter_campaign_id'] ?? 0),
            'status' => $status,
            'tags' => $tags ?: null,
            'start_date' => $start,
            'end_date' => $end,
            'target_list' => $targetList,
            'level' => $level,
        ];
    }
}
