<?php

declare(strict_types=1);

namespace App\Service;

use App\Entity\Device;
use App\Entity\DeviceImageHistory;
use App\Entity\Image;
use App\Entity\User;
use App\Repository\DeviceRepository;
use Doctrine\ORM\EntityManagerInterface;

class DeviceService
{
    public function __construct(
        private readonly DeviceRepository $repo,
        private readonly EntityManagerInterface $em,
    ) {}

    /**
     * Atomically link a MAC address to a user.
     * If the device was previously owned by a different user, image history is purged.
     */
    public function linkToUser(string $mac, User $newOwner): Device
    {
        $mac = strtoupper($mac);
        $device = $this->repo->findOneBy(['mac' => $mac]);

        if ($device === null) {
            $device = new Device();
            $device->setMac($mac);
        } elseif ($device->getUser() !== null && $device->getUser()->getId() !== $newOwner->getId()) {
            // Ownership transfer: purge prior image history for this device.
            // Full purge logic added in Epic 3 when Image/Approval entities exist.
            $this->purgeDeviceHistory($device);
        }

        $device->setUser($newOwner);
        $device->setLinkedAt(new \DateTimeImmutable());
        $this->em->persist($device);
        $this->em->flush();

        return $device;
    }

    /** Remove all image approvals and display history for this device. */
    private function purgeDeviceHistory(Device $device): void
    {
        // Remove device from every image's approval list
        $images = $this->em->createQueryBuilder()
            ->select('i')
            ->from(Image::class, 'i')
            ->join('i.approvedDevices', 'd')
            ->where('d = :device')
            ->setParameter('device', $device)
            ->getQuery()
            ->getResult();

        foreach ($images as $image) {
            $image->revokeForDevice($device);
        }

        // Purge display history (no ORM cascade fires on ownership transfer)
        $this->em->createQueryBuilder()
            ->delete(DeviceImageHistory::class, 'h')
            ->where('h.device = :device')
            ->setParameter('device', $device)
            ->getQuery()
            ->execute();
    }
}
