<?php
/**
 * BookiFlex Core
 *
 * @package    BookiFlex
 * @subpackage Core
 * @author     BookiFlex
 * @copyright  Copyright (c) 2025 BookiFlex
 * @license    GPL-2.0-or-later
 *
 * @link       https://bookiflex.com
 */

declare(strict_types=1);

namespace BookiFlex\Core\Admin\CPT\Event;

defined( 'ABSPATH' ) || exit;

/**
 * Event: AccommodationType was updated
 *
 * Dispatched when an existing AccommodationType CPT is modified
 *
 * This event includes information about what changed, allowing subscribers
 * to react only to specific field changes.
 *
 * This is an immediate event (not deferred) dispatched via EventDispatcher
 * after Carbon Fields has saved all post metadata.
 */
class AccommodationTypeWasUpdated
{
    /**
     * @param int $postId WordPress post ID (same as accommodationTypeId)
     * @param array $data Current post data snapshot
     * @param array $changes Detected changes in format ['field' => ['old' => value, 'new' => value]]
     */
    public function __construct(
        private readonly int $postId,
        private readonly array $data,
        private readonly array $changes
    ) {
    }

    /**
     * Get WordPress post ID
     */
    public function getPostId(): int
    {
        return $this->postId;
    }

    /**
     * Get AccommodationType ID (same as post ID)
     */
    public function getAccommodationTypeId(): int
    {
        return $this->postId;
    }

    /**
     * Get current post data
     */
    public function getData(): array
    {
        return $this->data;
    }

    /**
     * Get detected changes
     *
     * @return array Format: ['field' => ['old' => value, 'new' => value]]
     */
    public function getChanges(): array
    {
        return $this->changes;
    }

    /**
     * Get accommodation type name
     */
    public function getName(): string
    {
        return $this->data['name'] ?? '';
    }

    /**
     * Get post status (publish, draft, etc.)
     */
    public function getStatus(): string
    {
        return $this->data['status'] ?? '';
    }

    /**
     * Get current available units
     */
    public function getAvailableUnits(): int
    {
        return $this->data['available_units'] ?? 0;
    }

    /**
     * Check if available units changed
     */
    public function hasAvailableUnitsChanged(): bool
    {
        return isset($this->changes['available_units']);
    }

    /**
     * Get old available units value
     */
    public function getOldAvailableUnits(): ?int
    {
        return $this->changes['available_units']['old'] ?? null;
    }

    /**
     * Get new available units value
     */
    public function getNewAvailableUnits(): ?int
    {
        return $this->changes['available_units']['new'] ?? null;
    }

    /**
     * Check if status changed
     */
    public function hasStatusChanged(): bool
    {
        return isset($this->changes['status']);
    }

    /**
     * Get old status value
     */
    public function getOldStatus(): ?string
    {
        return $this->changes['status']['old'] ?? null;
    }

    /**
     * Get new status value
     */
    public function getNewStatus(): ?string
    {
        return $this->changes['status']['new'] ?? null;
    }

    /**
     * Check if name changed
     */
    public function hasNameChanged(): bool
    {
        return isset($this->changes['name']);
    }

    /**
     * Get old name value
     */
    public function getOldName(): ?string
    {
        return $this->changes['name']['old'] ?? null;
    }

    /**
     * Get new name value
     */
    public function getNewName(): ?string
    {
        return $this->changes['name']['new'] ?? null;
    }

    /**
     * Check if specific field changed
     */
    public function hasFieldChanged(string $fieldName): bool
    {
        return isset($this->changes[$fieldName]);
    }

    /**
     * Get change for specific field
     *
     * @return array|null Format: ['old' => value, 'new' => value] or null
     */
    public function getFieldChange(string $fieldName): ?array
    {
        return $this->changes[$fieldName] ?? null;
    }
}
