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

declare(strict_types=1);

namespace BookiFlex\Extensions\Onboarding\ValueObject;

defined( 'ABSPATH' ) || exit;

/**
 * Accommodation Value Object
 *
 * Represents a single accommodation type configuration from user input.
 *
 * @package BookiFlex\Extensions\Onboarding\ValueObject
 * @since   1.0.0
 */
class AccommodationType
{
    /**
     * Accommodation constructor
     *
     * @param string             $name           Accommodation name (e.g., "Standard Room")
     * @param int                $mainPlaces     Capacity - number of main places
     * @param string             $unitType       Room type/category
     * @param int                $availableUnits Inventory count
     * @param string|null        $description    Optional description text (200-300 chars)
     * @param array|null         $amenities      Optional list of amenities
     * @param string|null        $address        Optional string of address
     * @param WeeklyPricing|null $weeklyPricing  Optional weekly pricing (required for QuickSetup mode)
     *
     * @throws \InvalidArgumentException If validation fails
     */
    public function __construct(
        public readonly string $name,
        public readonly int $mainPlaces,
        public readonly string $unitType,
        public readonly int $availableUnits,
        public readonly ?string $description = null,
        public readonly ?array $amenities = null,
        public readonly ?string $address = null,
        public readonly ?WeeklyPricing $weeklyPricing = null,
    ) {
        $this->validate();
    }

    /**
     * Validate accommodation data
     *
     * @return void
     * @throws \InvalidArgumentException If validation fails
     */
    public function validate(): void
    {
        if (empty($this->name)) {
            throw new \InvalidArgumentException('Accommodation name required');
        }

        if ($this->mainPlaces < 1) {
            throw new \InvalidArgumentException('Main places must be at least 1');
        }

        if (empty($this->unitType)) {
            throw new \InvalidArgumentException('Unit type required');
        }

        if ($this->availableUnits < 1) {
            throw new \InvalidArgumentException('Available units must be at least 1');
        }
    }

    /**
     * Convert to array representation
     *
     * @return array{name: string, mainPlaces: int, unitType: string, availableUnits: int, description: string|null, amenities: array|null, weeklyPricing: array|null}
     */
    public function toArray(): array
    {
        return [
            'name' => $this->name,
            'mainPlaces' => $this->mainPlaces,
            'unitType' => $this->unitType,
            'availableUnits' => $this->availableUnits,
            'description' => $this->description,
            'amenities' => $this->amenities,
            'address' => $this->address,
            'weeklyPricing' => $this->weeklyPricing?->toArray(),
        ];
    }

    /**
     * Create from array
     *
     * @param  array<string, mixed> $data Array representation
     * @return self
     * @throws \InvalidArgumentException If required field is missing
     */
    public static function fromArray(array $data): self
    {
        // Create WeeklyPricing if present in data
        $weeklyPricing = null;
        if (isset($data['weeklyPricing']) && is_array($data['weeklyPricing'])) {
            $weeklyPricing = WeeklyPricing::fromArray($data['weeklyPricing']);
        }

        return new self(
            name: $data['name'] ?? throw new \InvalidArgumentException('name required'),
            mainPlaces: $data['mainPlaces'] ?? throw new \InvalidArgumentException('mainPlaces required'),
            unitType: $data['unitType'] ?? throw new \InvalidArgumentException('unitType required'),
            availableUnits: $data['availableUnits'] ?? throw new \InvalidArgumentException('availableUnits required'),
            description: $data['description'] ?? null,
            amenities: $data['amenities'] ?? null,
	        address: $data['address'] ?? null,
            weeklyPricing: $weeklyPricing,
        );
    }
}
