<?php

namespace MintyPHP\Service\Scheduler;

use MintyPHP\Repository\Scheduler\ScheduledJobRepository;
use MintyPHP\Repository\Scheduler\ScheduledJobRunRepository;
use MintyPHP\Repository\Scheduler\SchedulerRuntimeRepository;
use MintyPHP\Service\User\UserLifecycleService;
use MintyPHP\Service\User\UserServicesFactory;

class SchedulerServicesFactory
{
    private ?ScheduledJobRepository $scheduledJobRepository = null;
    private ?ScheduledJobRunRepository $scheduledJobRunRepository = null;
    private ?SchedulerRuntimeRepository $schedulerRuntimeRepository = null;
    private ?ScheduleCalculator $scheduleCalculator = null;
    private ?UserServicesFactory $userServicesFactory = null;
    private ?ScheduledJobRegistry $scheduledJobRegistry = null;
    private ?ScheduledJobService $scheduledJobService = null;
    private ?SchedulerRunService $schedulerRunService = null;

    public function createScheduledJobService(): ScheduledJobService
    {
        return $this->scheduledJobService ??= new ScheduledJobService(
            $this->getScheduledJobRepository(),
            $this->getScheduledJobRunRepository(),
            $this->getScheduledJobRegistry(),
            $this->getScheduleCalculator()
        );
    }

    public function createSchedulerRunService(): SchedulerRunService
    {
        return $this->schedulerRunService ??= new SchedulerRunService(
            $this->createScheduledJobService(),
            $this->getScheduledJobRepository(),
            $this->getScheduledJobRunRepository(),
            $this->getSchedulerRuntimeRepository(),
            $this->getScheduledJobRegistry(),
            $this->getScheduleCalculator()
        );
    }

    public function createUserLifecycleService(): UserLifecycleService
    {
        return $this->getUserLifecycleService();
    }

    private function getScheduledJobRepository(): ScheduledJobRepository
    {
        return $this->scheduledJobRepository ??= new ScheduledJobRepository();
    }

    private function getScheduledJobRunRepository(): ScheduledJobRunRepository
    {
        return $this->scheduledJobRunRepository ??= new ScheduledJobRunRepository();
    }

    private function getSchedulerRuntimeRepository(): SchedulerRuntimeRepository
    {
        return $this->schedulerRuntimeRepository ??= new SchedulerRuntimeRepository();
    }

    private function getScheduleCalculator(): ScheduleCalculator
    {
        return $this->scheduleCalculator ??= new ScheduleCalculator();
    }

    private function getUserLifecycleService(): UserLifecycleService
    {
        return $this->getUserServicesFactory()->createUserLifecycleService();
    }

    private function getScheduledJobRegistry(): ScheduledJobRegistry
    {
        return $this->scheduledJobRegistry ??= new ScheduledJobRegistry($this->getUserLifecycleService());
    }

    private function getUserServicesFactory(): UserServicesFactory
    {
        return $this->userServicesFactory ??= new UserServicesFactory();
    }
}
