<?php

declare(strict_types=1);

namespace App\Modules\Operation;

/**
 * OperationService — Orchestrates guest identity resolutions, check-in rules,
 * and declares the PrinterAdapter interface.
 *
 * Scoped only to business rules coordination; no SQL queries.
 *
 * @package Inveetaire
 * @ref     PILOT-007
 */
class OperationService
{
    private OperationModel $model;

    public function __construct()
    {
        $this->model = new OperationModel();
    }

    /**
     * Resolve a public guest token into a complete profile.
     * Throws InvalidArgumentException if the token is invalid within the workspace.
     *
     * @param int    $workspaceId
     * @param string $token
     * @return array Unified guest parameters bundle.
     */
    public function resolveGuest(int $workspaceId, string $token): array
    {
        $guest = $this->model->getGuestByToken($workspaceId, $token);
        if ($guest === null) {
            throw new \InvalidArgumentException("Invalid guest invitation code.");
        }

        $guestId = (int) $guest['id'];
        $events = $this->model->getAssignedEvents($workspaceId, $guestId);
        $hasWish = $this->model->hasWish($workspaceId, $guestId);

        return [
            'guest'    => $guest,
            'events'   => $events,
            'has_wish' => $hasWish
        ];
    }

    /**
     * Process check-in for a guest.
     * Idempotent check-in checks if already checked in, preventing double recording.
     *
     * @param int    $workspaceId
     * @param string $token
     * @return array Output status containing 'success' and message.
     */
    public function checkIn(int $workspaceId, string $token): array
    {
        try {
            $resolved = $this->resolveGuest($workspaceId, $token);
        } catch (\InvalidArgumentException $e) {
            throw $e;
        }

        $guest = $resolved['guest'];
        $guestId = (int) $guest['id'];

        // Perform checkin
        $isFirstCheckin = $this->model->checkInGuest($workspaceId, $guestId);

        if ($isFirstCheckin) {
            return [
                'success' => true,
                'message' => 'Check-in completed successfully.'
            ];
        } else {
            return [
                'success' => false,
                'message' => 'Already Checked In.'
            ];
        }
    }
}

/**
 * PrinterAdapter — Abstract interface for future printing hardware integrations.
 * Future drivers might include Angpao printer, name labels, or badge printers.
 *
 * Declared inside OperationService to comply with files allowed constraints.
 */
interface PrinterAdapter
{
    /**
     * Print a physical label or badge for the guest.
     *
     * @param array $guestData Complete guest details row.
     * @return bool True if print job spooled successfully.
     */
    public function printLabel(array $guestData): bool;
}
