<?php
namespace Components\Data\Mock;

use Components\Data\Contracts\CalendarEventProvider;
use DateTimeImmutable;
use DateTimeZone;

class MockCalendarEventProvider implements CalendarEventProvider
{
    /**
     * @param array<string,mixed> $state
     * @return array<int,array<string,mixed>>
     */
    public function events(array $state = []): array
    {
        $tz = $state['tz'] instanceof DateTimeZone
            ? $state['tz']
            : new DateTimeZone((string)date_default_timezone_get());

        $now = $state['now'] instanceof DateTimeImmutable
            ? $state['now']
            : new DateTimeImmutable('now', $tz);

        $rangeStart = $state['range_start'] instanceof DateTimeImmutable ? $state['range_start'] : null;
        $rangeEnd = $state['range_end'] instanceof DateTimeImmutable ? $state['range_end'] : null;
        $filter = $state['filter'] ?? 'all';

        $flows = (new MockNewsletterProvider())->flows();
        $events = [];

        foreach ($flows as $flow) {
            $type = $this->resolveType($flow);
            if ($filter === 'newsletter' && $type !== \Components\Newsletter\PageConfig::MODE_NEWSLETTER) {
                continue;
            }
            if ($filter === 'automations' && $type !== \Components\Newsletter\PageConfig::MODE_AUTOMATION) {
                continue;
            }

            $start = $this->parseDate($flow['start_date'] ?? null, $tz);
            $end = $this->parseDate($flow['end_date'] ?? null, $tz);

            if (!$start && !$end) {
                continue;
            }

            if (!$start) {
                $start = $end;
            }
            if (!$end) {
                $end = $start;
            }
            if (!$start || !$end) {
                continue;
            }
            if ($start > $end) {
                [$start, $end] = [$end, $start];
            }

            if (!$this->overlaps($start, $end, $rangeStart, $rangeEnd)) {
                continue;
            }

            $status = $this->resolveStatus($start, $end, $now);
            $type = $this->resolveType($flow);

            $campaignId = isset($flow['collection_id']) ? (int)$flow['collection_id'] : 0;
            $editUrl = $campaignId > 0
                ? \Components\Router::url('newsletter', ['group' => 'campaign-' . $campaignId])
                : \Components\Router::url('newsletter');

            $id = (int)($flow['id'] ?? 0);
            $pageMode = $type;
            $active = ($pageMode === 'automation') ? 'trigger' : 'newsletter';

            $events[] = [
                'id' => $id,
                'newsletter_campaign_id' => $campaignId,
                'title' => (string)($flow['name'] ?? 'Untitled'),
                'start' => $start,
                'end' => $end,
                'status' => $status,
                'type' => $type,
                'active' => $active,
                'open_key' => $pageMode . '-flow:' . $id,
                'edit_url' => $editUrl,
            ];
        }

        return $events;
    }

    private function parseDate($raw, DateTimeZone $tz): ?DateTimeImmutable
    {
        if (!is_scalar($raw)) {
            return null;
        }

        $value = trim((string)$raw);
        if ($value === '') {
            return null;
        }

        $dt = DateTimeImmutable::createFromFormat('Y-m-d', $value, $tz);
        if ($dt instanceof DateTimeImmutable) {
            return $dt->setTime(0, 0, 0);
        }

        $ts = @strtotime($value);
        if ($ts === false || $ts <= 0) {
            return null;
        }

        return (new DateTimeImmutable('@' . $ts))->setTimezone($tz)->setTime(0, 0, 0);
    }

    private function resolveStatus(DateTimeImmutable $start, DateTimeImmutable $end, DateTimeImmutable $now): string
    {
        $today = $now->setTime(0, 0, 0);

        if ($end < $today) {
            return 'previous';
        }
        if ($start > $today) {
            return 'scheduled';
        }

        return 'active';
    }

    private function overlaps(DateTimeImmutable $start, DateTimeImmutable $end, ?DateTimeImmutable $rangeStart, ?DateTimeImmutable $rangeEnd): bool
    {
        if ($rangeStart === null || $rangeEnd === null) {
            return true;
        }

        return !($end < $rangeStart || $start > $rangeEnd);
    }

    /**
     * @param array<string,mixed> $flow
     */
    private function resolveType(array $flow): string
    {
        $scheduleType = strtolower((string)($flow['schedule_type'] ?? ''));
        $isFollowup = false;

        $tags = isset($flow['tags']) && is_array($flow['tags']) ? $flow['tags'] : [];
        foreach ($tags as $tag) {
            if (strtolower((string)$tag) === 'followup') {
                $isFollowup = true;
                break;
            }
        }

        return \Components\Newsletter\PageConfig::resolveModeFromScheduleType($scheduleType, $isFollowup);
    }
}
