<?php

namespace MintyPHP\Service\Scheduler;

use MintyPHP\Repository\Scheduler\ScheduledJobRepositoryInterface;
use MintyPHP\Repository\Scheduler\ScheduledJobRunRepositoryInterface;
use MintyPHP\Repository\Scheduler\SchedulerRuntimeRepositoryInterface;
use MintyPHP\Repository\Support\DatabaseSessionRepository;
use MintyPHP\Service\Audit\AuditServicesFactory;
use MintyPHP\Service\Audit\SystemAuditService;
use MintyPHP\Service\User\UserLifecycleService;
use MintyPHP\Service\User\UserServicesFactory;

class SchedulerServicesFactory
{
    private ?ScheduleCalculator $scheduleCalculator = null;
    private ?ScheduledJobRegistry $scheduledJobRegistry = null;
    private ?ScheduledJobService $scheduledJobService = null;
    private ?SchedulerRunService $schedulerRunService = null;

    public function __construct(
        private readonly UserServicesFactory $userServicesFactory,
        private readonly AuditServicesFactory $auditServicesFactory,
        private readonly DatabaseSessionRepository $databaseSessionRepository,
        private readonly SchedulerRepositoryFactory $schedulerRepositoryFactory
    ) {
    }

    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(),
            $this->getDatabaseSessionRepository(),
            $this->getSystemAuditService()
        );
    }

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

    private function getScheduledJobRepository(): ScheduledJobRepositoryInterface
    {
        return $this->schedulerRepositoryFactory->createScheduledJobRepository();
    }

    private function getScheduledJobRunRepository(): ScheduledJobRunRepositoryInterface
    {
        return $this->schedulerRepositoryFactory->createScheduledJobRunRepository();
    }

    private function getSchedulerRuntimeRepository(): SchedulerRuntimeRepositoryInterface
    {
        return $this->schedulerRepositoryFactory->createSchedulerRuntimeRepository();
    }

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

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

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

    private function getDatabaseSessionRepository(): DatabaseSessionRepository
    {
        return $this->databaseSessionRepository;
    }

    private function getSystemAuditService(): SystemAuditService
    {
        return $this->auditServicesFactory->createSystemAuditService();
    }

}
