<?php

namespace Cron;

use Doctrine\ORM\EntityManager;
use Entity\User;
use Entity\Werbenetzwerk;
use Entity\Kampagne;

abstract class AbstractCron
{
    protected EntityManager $entityManager;
    protected User $werbenetzwerkUser;
    protected Werbenetzwerk $werbenetzwerk;

    public function __construct(EntityManager $entityManager)
    {
        $this->entityManager = $entityManager;
    }

    /**
     * Hauptmethode zum Ausführen des Cron-Jobs
     */
    abstract public function run(): void;

    /**
     * Gibt den Username des Werbenetzwerk-Users zurück
     */
    abstract protected function getWerbenetzwerkUsername(): string;

    /**
     * Lädt User und Werbenetzwerk-Daten aus der Datenbank
     */
    protected function loadWerbenetzwerkData(): void
    {
        $username = $this->getWerbenetzwerkUsername();

        // Werbenetzwerk-User holen
        $this->werbenetzwerkUser = $this->entityManager
            ->getRepository(User::class)
            ->findByUsername($username);

        if (!$this->werbenetzwerkUser) {
            throw new \RuntimeException("Werbenetzwerk-User '$username' nicht gefunden.");
        }

        // Werbenetzwerk-Daten holen
        $this->werbenetzwerk = $this->entityManager
            ->getRepository(Werbenetzwerk::class)
            ->findByUser($this->werbenetzwerkUser);

        if (!$this->werbenetzwerk) {
            throw new \RuntimeException("Werbenetzwerk-Daten für User '$username' nicht gefunden.");
        }
    }

    /**
     * Führt einen API-Call durch
     */
    protected function fetchFromApi(string $url, array $params = []): string
    {
        $fullUrl = $url;
        if (!empty($params)) {
            $fullUrl .= '?' . http_build_query($params);
        }

        $this->log("Fetching from API: $fullUrl");

        $response = file_get_contents($fullUrl);

        if ($response === false) {
            throw new \RuntimeException("Fehler beim Abrufen der API-Daten von: $fullUrl");
        }

        return $response;
    }

    /**
     * Prüft ob eine Kampagne bereits existiert
     */
    protected function findExistingKampagne(string $kid, bool $isFb = false, bool $isTr = false, bool $isMail = false): ?Kampagne
    {
        $criteria = [
            'user' => $this->werbenetzwerkUser,
            'kid' => $kid
        ];

        if ($isFb) {
            $criteria['is_fb'] = true;
        }
        if ($isTr) {
            $criteria['is_tr'] = true;
        }
        if ($isMail) {
            $criteria['is_mail'] = true;
        }

        return $this->entityManager
            ->getRepository(Kampagne::class)
            ->findOneBy($criteria);
    }

    /**
     * Speichert alle Änderungen in der Datenbank
     */
    protected function flush(): void
    {
        $this->entityManager->flush();
    }

    /**
     * Gibt eine Log-Nachricht aus
     */
    protected function log(string $message): void
    {
        echo "[" . date('Y-m-d H:i:s') . "] $message\n";
    }

    /**
     * Gibt eine Zusammenfassung aus
     */
    protected function printSummary(int $total, int $created, int $updated): void
    {
        $this->log("=== Summary ===");
        $this->log("Total campaigns processed: $total");
        $this->log("Created: $created");
        $this->log("Updated: $updated");
    }
}
