<?php

/**
 * Configuration API
 *
 * The version of the OpenAPI document: 2
 * Generated by: https://openapi-generator.tech
 * OpenAPI Generator version: 6.0.1
 *
 * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
 * https://openapi-generator.tech
 * Do not edit the class manually.
 */


namespace Adyen\Model\BalancePlatform;

use ArrayAccess;
use Adyen\Model\BalancePlatform\ObjectSerializer;

/**
 * CardConfiguration Class Doc Comment
 *
 * @package  Adyen
 * @implements ArrayAccess<string, mixed>
 */
class CardConfiguration implements ModelInterface, ArrayAccess, \JsonSerializable
{
    public const DISCRIMINATOR = null;

    /**
      * The original name of the model.
      *
      * @var string
      */
    protected static $openAPIModelName = 'CardConfiguration';

    /**
      * Array of property to type mappings. Used for (de)serialization
      *
      * @var string[]
      */
    protected static $openAPITypes = [
        'activation' => 'string',
        'activationUrl' => 'string',
        'bulkAddress' => '\Adyen\Model\BalancePlatform\BulkAddress',
        'cardImageId' => 'string',
        'carrier' => 'string',
        'carrierImageId' => 'string',
        'configurationProfileId' => 'string',
        'currency' => 'string',
        'envelope' => 'string',
        'insert' => 'string',
        'language' => 'string',
        'logoImageId' => 'string',
        'pinMailer' => 'string',
        'shipmentMethod' => 'string'
    ];

    /**
      * Array of property to format mappings. Used for (de)serialization
      *
      * @var string[]
      * @phpstan-var array<string, string|null>
      * @psalm-var array<string, string|null>
      */
    protected static $openAPIFormats = [
        'activation' => null,
        'activationUrl' => null,
        'bulkAddress' => null,
        'cardImageId' => null,
        'carrier' => null,
        'carrierImageId' => null,
        'configurationProfileId' => null,
        'currency' => null,
        'envelope' => null,
        'insert' => null,
        'language' => null,
        'logoImageId' => null,
        'pinMailer' => null,
        'shipmentMethod' => null
    ];

    /**
      * Array of nullable properties. Used for (de)serialization
      *
      * @var boolean[]
      */
    protected static $openAPINullables = [
        'activation' => false,
        'activationUrl' => false,
        'bulkAddress' => false,
        'cardImageId' => false,
        'carrier' => false,
        'carrierImageId' => false,
        'configurationProfileId' => false,
        'currency' => false,
        'envelope' => false,
        'insert' => false,
        'language' => false,
        'logoImageId' => false,
        'pinMailer' => false,
        'shipmentMethod' => false
    ];

    /**
      * If a nullable field gets set to null, insert it here
      *
      * @var boolean[]
      */
    protected $openAPINullablesSetToNull = [];

    /**
     * Array of property to type mappings. Used for (de)serialization
     *
     * @return array
     */
    public static function openAPITypes()
    {
        return self::$openAPITypes;
    }

    /**
     * Array of property to format mappings. Used for (de)serialization
     *
     * @return array
     */
    public static function openAPIFormats()
    {
        return self::$openAPIFormats;
    }

    /**
     * Array of nullable properties
     *
     * @return array
     */
    protected static function openAPINullables(): array
    {
        return self::$openAPINullables;
    }

    /**
     * Array of nullable field names deliberately set to null
     *
     * @return boolean[]
     */
    private function getOpenAPINullablesSetToNull(): array
    {
        return $this->openAPINullablesSetToNull;
    }

    /**
     * Setter - Array of nullable field names deliberately set to null
     *
     * @param boolean[] $openAPINullablesSetToNull
     */
    private function setOpenAPINullablesSetToNull(array $openAPINullablesSetToNull): void
    {
        $this->openAPINullablesSetToNull = $openAPINullablesSetToNull;
    }

    /**
     * Checks if a property is nullable
     *
     * @param string $property
     * @return bool
     */
    public static function isNullable(string $property): bool
    {
        return self::openAPINullables()[$property] ?? false;
    }

    /**
     * Checks if a nullable property is set to null.
     *
     * @param string $property
     * @return bool
     */
    public function isNullableSetToNull(string $property): bool
    {
        return in_array($property, $this->getOpenAPINullablesSetToNull(), true);
    }

    /**
     * Array of attributes where the key is the local name,
     * and the value is the original name
     *
     * @var string[]
     */
    protected static $attributeMap = [
        'activation' => 'activation',
        'activationUrl' => 'activationUrl',
        'bulkAddress' => 'bulkAddress',
        'cardImageId' => 'cardImageId',
        'carrier' => 'carrier',
        'carrierImageId' => 'carrierImageId',
        'configurationProfileId' => 'configurationProfileId',
        'currency' => 'currency',
        'envelope' => 'envelope',
        'insert' => 'insert',
        'language' => 'language',
        'logoImageId' => 'logoImageId',
        'pinMailer' => 'pinMailer',
        'shipmentMethod' => 'shipmentMethod'
    ];

    /**
     * Array of attributes to setter functions (for deserialization of responses)
     *
     * @var string[]
     */
    protected static $setters = [
        'activation' => 'setActivation',
        'activationUrl' => 'setActivationUrl',
        'bulkAddress' => 'setBulkAddress',
        'cardImageId' => 'setCardImageId',
        'carrier' => 'setCarrier',
        'carrierImageId' => 'setCarrierImageId',
        'configurationProfileId' => 'setConfigurationProfileId',
        'currency' => 'setCurrency',
        'envelope' => 'setEnvelope',
        'insert' => 'setInsert',
        'language' => 'setLanguage',
        'logoImageId' => 'setLogoImageId',
        'pinMailer' => 'setPinMailer',
        'shipmentMethod' => 'setShipmentMethod'
    ];

    /**
     * Array of attributes to getter functions (for serialization of requests)
     *
     * @var string[]
     */
    protected static $getters = [
        'activation' => 'getActivation',
        'activationUrl' => 'getActivationUrl',
        'bulkAddress' => 'getBulkAddress',
        'cardImageId' => 'getCardImageId',
        'carrier' => 'getCarrier',
        'carrierImageId' => 'getCarrierImageId',
        'configurationProfileId' => 'getConfigurationProfileId',
        'currency' => 'getCurrency',
        'envelope' => 'getEnvelope',
        'insert' => 'getInsert',
        'language' => 'getLanguage',
        'logoImageId' => 'getLogoImageId',
        'pinMailer' => 'getPinMailer',
        'shipmentMethod' => 'getShipmentMethod'
    ];

    /**
     * Array of attributes where the key is the local name,
     * and the value is the original name
     *
     * @return array
     */
    public static function attributeMap()
    {
        return self::$attributeMap;
    }

    /**
     * Array of attributes to setter functions (for deserialization of responses)
     *
     * @return array
     */
    public static function setters()
    {
        return self::$setters;
    }

    /**
     * Array of attributes to getter functions (for serialization of requests)
     *
     * @return array
     */
    public static function getters()
    {
        return self::$getters;
    }

    /**
     * The original name of the model.
     *
     * @return string
     */
    public function getModelName()
    {
        return self::$openAPIModelName;
    }


    /**
     * Associative array for storing property values
     *
     * @var mixed[]
     */
    protected $container = [];

    /**
     * Constructor
     *
     * @param mixed[] $data Associated array of property values
     *                      initializing the model
     */
    public function __construct(?array $data = null)
    {
        $this->setIfExists('activation', $data ?? [], null);
        $this->setIfExists('activationUrl', $data ?? [], null);
        $this->setIfExists('bulkAddress', $data ?? [], null);
        $this->setIfExists('cardImageId', $data ?? [], null);
        $this->setIfExists('carrier', $data ?? [], null);
        $this->setIfExists('carrierImageId', $data ?? [], null);
        $this->setIfExists('configurationProfileId', $data ?? [], null);
        $this->setIfExists('currency', $data ?? [], null);
        $this->setIfExists('envelope', $data ?? [], null);
        $this->setIfExists('insert', $data ?? [], null);
        $this->setIfExists('language', $data ?? [], null);
        $this->setIfExists('logoImageId', $data ?? [], null);
        $this->setIfExists('pinMailer', $data ?? [], null);
        $this->setIfExists('shipmentMethod', $data ?? [], null);
    }

    /**
    * Sets $this->container[$variableName] to the given data or to the given default Value; if $variableName
    * is nullable and its value is set to null in the $fields array, then mark it as "set to null" in the
    * $this->openAPINullablesSetToNull array
    *
    * @param string $variableName
    * @param array  $fields
    * @param mixed  $defaultValue
    */
    private function setIfExists(string $variableName, array $fields, $defaultValue): void
    {
        if (self::isNullable($variableName) && array_key_exists($variableName, $fields) && is_null($fields[$variableName])) {
            $this->openAPINullablesSetToNull[] = $variableName;
        }

        $this->container[$variableName] = $fields[$variableName] ?? $defaultValue;
    }

    /**
     * Show all the invalid properties with reasons.
     *
     * @return array invalid properties with reasons
     */
    public function listInvalidProperties()
    {
        $invalidProperties = [];

        if ($this->container['configurationProfileId'] === null) {
            $invalidProperties[] = "'configurationProfileId' can't be null";
        }
        return $invalidProperties;
    }

    /**
     * Validate all the properties in the model
     * return true if all passed
     *
     * @return bool True if all properties are valid
     */
    public function valid()
    {
        return count($this->listInvalidProperties()) === 0;
    }


    /**
     * Gets activation
     *
     * @return string|null
     */
    public function getActivation()
    {
        return $this->container['activation'];
    }

    /**
     * Sets activation
     *
     * @param string|null $activation The activation label attached to the card that contains the activation instructions.  This field overrides the activation label design ID defined in the card configuration profile.
     *
     * @return self
     */
    public function setActivation($activation)
    {
        $this->container['activation'] = $activation;

        return $this;
    }

    /**
     * Gets activationUrl
     *
     * @return string|null
     */
    public function getActivationUrl()
    {
        return $this->container['activationUrl'];
    }

    /**
     * Sets activationUrl
     *
     * @param string|null $activationUrl Your app's URL, if you want to activate cards through your app. For example, **my-app://ref1236a7d**. A QR code is created based on this URL, and is included in the carrier. Before you use this field, reach out to your Adyen contact to set up the QR code process.   Maximum length: 255 characters.
     *
     * @return self
     */
    public function setActivationUrl($activationUrl)
    {
        $this->container['activationUrl'] = $activationUrl;

        return $this;
    }

    /**
     * Gets bulkAddress
     *
     * @return \Adyen\Model\BalancePlatform\BulkAddress|null
     */
    public function getBulkAddress()
    {
        return $this->container['bulkAddress'];
    }

    /**
     * Sets bulkAddress
     *
     * @param \Adyen\Model\BalancePlatform\BulkAddress|null $bulkAddress bulkAddress
     *
     * @return self
     */
    public function setBulkAddress($bulkAddress)
    {
        $this->container['bulkAddress'] = $bulkAddress;

        return $this;
    }

    /**
     * Gets cardImageId
     *
     * @return string|null
     */
    public function getCardImageId()
    {
        return $this->container['cardImageId'];
    }

    /**
     * Sets cardImageId
     *
     * @param string|null $cardImageId The unique identifier of the card image. This image is printed on the full front of the card.
     *
     * @return self
     */
    public function setCardImageId($cardImageId)
    {
        $this->container['cardImageId'] = $cardImageId;

        return $this;
    }

    /**
     * Gets carrier
     *
     * @return string|null
     */
    public function getCarrier()
    {
        return $this->container['carrier'];
    }

    /**
     * Sets carrier
     *
     * @param string|null $carrier The letter or packaging to which the card is attached.  This field overrides the carrier design ID defined in the card configuration profile.
     *
     * @return self
     */
    public function setCarrier($carrier)
    {
        $this->container['carrier'] = $carrier;

        return $this;
    }

    /**
     * Gets carrierImageId
     *
     * @return string|null
     */
    public function getCarrierImageId()
    {
        return $this->container['carrierImageId'];
    }

    /**
     * Sets carrierImageId
     *
     * @param string|null $carrierImageId The unique identifier of the carrier image. This image is printed on the letter to which the card is attached.
     *
     * @return self
     */
    public function setCarrierImageId($carrierImageId)
    {
        $this->container['carrierImageId'] = $carrierImageId;

        return $this;
    }

    /**
     * Gets configurationProfileId
     *
     * @return string
     */
    public function getConfigurationProfileId()
    {
        return $this->container['configurationProfileId'];
    }

    /**
     * Sets configurationProfileId
     *
     * @param string $configurationProfileId The unique identifier of the card configuration profile that contains the settings that are applied to the card. For example, the envelope and PIN mailer designs or the logistics company handling the shipment.  You can override some of the existing settings in the configuration profile by providing the corresponding fields in the `configuration` object. For example, send the `shipmentMethod` to override the logistics company defined in the card configuration profile.
     *
     * @return self
     */
    public function setConfigurationProfileId($configurationProfileId)
    {
        $this->container['configurationProfileId'] = $configurationProfileId;

        return $this;
    }

    /**
     * Gets currency
     *
     * @return string|null
     */
    public function getCurrency()
    {
        return $this->container['currency'];
    }

    /**
     * Sets currency
     *
     * @param string|null $currency The three-letter [ISO-4217](https://en.wikipedia.org/wiki/ISO_4217) currency code of the card. For example, **EUR**.  This field overrides the existing currency setting on the card configuration profile.
     *
     * @return self
     */
    public function setCurrency($currency)
    {
        $this->container['currency'] = $currency;

        return $this;
    }

    /**
     * Gets envelope
     *
     * @return string|null
     */
    public function getEnvelope()
    {
        return $this->container['envelope'];
    }

    /**
     * Sets envelope
     *
     * @param string|null $envelope Overrides the envelope design ID defined in the card configuration profile.
     *
     * @return self
     */
    public function setEnvelope($envelope)
    {
        $this->container['envelope'] = $envelope;

        return $this;
    }

    /**
     * Gets insert
     *
     * @return string|null
     */
    public function getInsert()
    {
        return $this->container['insert'];
    }

    /**
     * Sets insert
     *
     * @param string|null $insert Any additional material, such as marketing material, that is shipped together with the card.  This field overrides the insert design ID defined in the card configuration profile.
     *
     * @return self
     */
    public function setInsert($insert)
    {
        $this->container['insert'] = $insert;

        return $this;
    }

    /**
     * Gets language
     *
     * @return string|null
     */
    public function getLanguage()
    {
        return $this->container['language'];
    }

    /**
     * Sets language
     *
     * @param string|null $language The two-letter [ISO-639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) language code of the card. For example, **en**.
     *
     * @return self
     */
    public function setLanguage($language)
    {
        $this->container['language'] = $language;

        return $this;
    }

    /**
     * Gets logoImageId
     *
     * @return string|null
     */
    public function getLogoImageId()
    {
        return $this->container['logoImageId'];
    }

    /**
     * Sets logoImageId
     *
     * @param string|null $logoImageId The unique identifier of the logo image. This image is printed on the partial front of the card, for example, a logo on the upper right corner.
     *
     * @return self
     */
    public function setLogoImageId($logoImageId)
    {
        $this->container['logoImageId'] = $logoImageId;

        return $this;
    }

    /**
     * Gets pinMailer
     *
     * @return string|null
     */
    public function getPinMailer()
    {
        return $this->container['pinMailer'];
    }

    /**
     * Sets pinMailer
     *
     * @param string|null $pinMailer The letter on which the PIN of the card is printed.  This field overrides the PIN mailer design ID defined in the card configuration profile.
     *
     * @return self
     */
    public function setPinMailer($pinMailer)
    {
        $this->container['pinMailer'] = $pinMailer;

        return $this;
    }

    /**
     * Gets shipmentMethod
     *
     * @return string|null
     */
    public function getShipmentMethod()
    {
        return $this->container['shipmentMethod'];
    }

    /**
     * Sets shipmentMethod
     *
     * @param string|null $shipmentMethod The logistics company that ships the card.  This field overrides the logistics company defined in the card configuration profile.
     *
     * @return self
     */
    public function setShipmentMethod($shipmentMethod)
    {
        $this->container['shipmentMethod'] = $shipmentMethod;

        return $this;
    }
    /**
     * Returns true if offset exists. False otherwise.
     *
     * @param integer $offset Offset
     *
     * @return boolean
     */
    public function offsetExists($offset): bool
    {
        return isset($this->container[$offset]);
    }

    /**
     * Gets offset.
     *
     * @param integer $offset Offset
     *
     * @return mixed|null
     */
    #[\ReturnTypeWillChange]
    public function offsetGet($offset)
    {
        return $this->container[$offset] ?? null;
    }

    /**
     * Sets value based on offset.
     *
     * @param int|null $offset Offset
     * @param mixed    $value  Value to be set
     *
     * @return void
     */
    public function offsetSet($offset, $value): void
    {
        if (is_null($offset)) {
            $this->container[] = $value;
        } else {
            $this->container[$offset] = $value;
        }
    }

    /**
     * Unsets offset.
     *
     * @param integer $offset Offset
     *
     * @return void
     */
    public function offsetUnset($offset): void
    {
        unset($this->container[$offset]);
    }

    /**
     * Serializes the object to a value that can be serialized natively by json_encode().
     * @link https://www.php.net/manual/en/jsonserializable.jsonserialize.php
     *
     * @return mixed Returns data which can be serialized by json_encode(), which is a value
     * of any type other than a resource.
     */
    #[\ReturnTypeWillChange]
    public function jsonSerialize()
    {
        return ObjectSerializer::sanitizeForSerialization($this);
    }

    public function toArray(): array
    {
        $array = [];
        foreach (self::$openAPITypes as $propertyName => $propertyType) {
            $propertyValue = $this[$propertyName];
            if ($propertyValue !== null) {
                // Check if the property value is an object and has a toArray() method
                if (is_object($propertyValue) && method_exists($propertyValue, 'toArray')) {
                    $array[$propertyName] = $propertyValue->toArray();
                // Check if it's type datetime
                } elseif ($propertyValue instanceof \DateTime) {
                    $array[$propertyName] = $propertyValue->format(DATE_ATOM);
                // If it's an array type we should check whether it contains objects and if so call toArray method
                } elseif (is_array($propertyValue)) {
                    $array[$propertyName] = array_map(function ($item) {
                        return $item instanceof ModelInterface ? $item->toArray() : $item;
                    }, $propertyValue);
                } else {
                    // Otherwise, directly assign the property value to the array
                    $array[$propertyName] = $propertyValue;
                }
            }
        }
        return $array;
    }

    /**
     * Gets the string presentation of the object
     *
     * @return string
     */
    public function __toString()
    {
        return json_encode(
            ObjectSerializer::sanitizeForSerialization($this),
            JSON_PRETTY_PRINT
        );
    }
}
