<?php

namespace Square\Types;

use Square\Core\Json\JsonSerializableType;
use Square\Core\Json\JsonProperty;
use Square\Core\Types\ArrayType;

/**
 * Represents a [dispute](https://developer.squareup.com/docs/disputes-api/overview) a cardholder initiated with their bank.
 */
class Dispute extends JsonSerializableType
{
    /**
     * @var ?string $disputeId The unique ID for this `Dispute`, generated by Square.
     */
    #[JsonProperty('dispute_id')]
    private ?string $disputeId;

    /**
     * @var ?string $id The unique ID for this `Dispute`, generated by Square.
     */
    #[JsonProperty('id')]
    private ?string $id;

    /**
     * The disputed amount, which can be less than the total transaction amount.
     * For instance, if multiple items were purchased but the cardholder only initiates a dispute over some of the items.
     *
     * @var ?Money $amountMoney
     */
    #[JsonProperty('amount_money')]
    private ?Money $amountMoney;

    /**
     * The reason why the cardholder initiated the dispute.
     * See [DisputeReason](#type-disputereason) for possible values
     *
     * @var ?value-of<DisputeReason> $reason
     */
    #[JsonProperty('reason')]
    private ?string $reason;

    /**
     * The current state of this dispute.
     * See [DisputeState](#type-disputestate) for possible values
     *
     * @var ?value-of<DisputeState> $state
     */
    #[JsonProperty('state')]
    private ?string $state;

    /**
     * @var ?string $dueAt The deadline by which the seller must respond to the dispute, in [RFC 3339 format](https://developer.squareup.com/docs/build-basics/common-data-types/working-with-dates).
     */
    #[JsonProperty('due_at')]
    private ?string $dueAt;

    /**
     * @var ?DisputedPayment $disputedPayment The payment challenged in this dispute.
     */
    #[JsonProperty('disputed_payment')]
    private ?DisputedPayment $disputedPayment;

    /**
     * @var ?array<string> $evidenceIds The IDs of the evidence associated with the dispute.
     */
    #[JsonProperty('evidence_ids'), ArrayType(['string'])]
    private ?array $evidenceIds;

    /**
     * The card brand used in the disputed payment.
     * See [CardBrand](#type-cardbrand) for possible values
     *
     * @var ?value-of<CardBrand> $cardBrand
     */
    #[JsonProperty('card_brand')]
    private ?string $cardBrand;

    /**
     * @var ?string $createdAt The timestamp when the dispute was created, in RFC 3339 format.
     */
    #[JsonProperty('created_at')]
    private ?string $createdAt;

    /**
     * @var ?string $updatedAt The timestamp when the dispute was last updated, in RFC 3339 format.
     */
    #[JsonProperty('updated_at')]
    private ?string $updatedAt;

    /**
     * @var ?string $brandDisputeId The ID of the dispute in the card brand system, generated by the card brand.
     */
    #[JsonProperty('brand_dispute_id')]
    private ?string $brandDisputeId;

    /**
     * @var ?string $reportedDate The timestamp when the dispute was reported, in RFC 3339 format.
     */
    #[JsonProperty('reported_date')]
    private ?string $reportedDate;

    /**
     * @var ?string $reportedAt The timestamp when the dispute was reported, in RFC 3339 format.
     */
    #[JsonProperty('reported_at')]
    private ?string $reportedAt;

    /**
     * @var ?int $version The current version of the `Dispute`.
     */
    #[JsonProperty('version')]
    private ?int $version;

    /**
     * @var ?string $locationId The ID of the location where the dispute originated.
     */
    #[JsonProperty('location_id')]
    private ?string $locationId;

    /**
     * @param array{
     *   disputeId?: ?string,
     *   id?: ?string,
     *   amountMoney?: ?Money,
     *   reason?: ?value-of<DisputeReason>,
     *   state?: ?value-of<DisputeState>,
     *   dueAt?: ?string,
     *   disputedPayment?: ?DisputedPayment,
     *   evidenceIds?: ?array<string>,
     *   cardBrand?: ?value-of<CardBrand>,
     *   createdAt?: ?string,
     *   updatedAt?: ?string,
     *   brandDisputeId?: ?string,
     *   reportedDate?: ?string,
     *   reportedAt?: ?string,
     *   version?: ?int,
     *   locationId?: ?string,
     * } $values
     */
    public function __construct(
        array $values = [],
    ) {
        $this->disputeId = $values['disputeId'] ?? null;
        $this->id = $values['id'] ?? null;
        $this->amountMoney = $values['amountMoney'] ?? null;
        $this->reason = $values['reason'] ?? null;
        $this->state = $values['state'] ?? null;
        $this->dueAt = $values['dueAt'] ?? null;
        $this->disputedPayment = $values['disputedPayment'] ?? null;
        $this->evidenceIds = $values['evidenceIds'] ?? null;
        $this->cardBrand = $values['cardBrand'] ?? null;
        $this->createdAt = $values['createdAt'] ?? null;
        $this->updatedAt = $values['updatedAt'] ?? null;
        $this->brandDisputeId = $values['brandDisputeId'] ?? null;
        $this->reportedDate = $values['reportedDate'] ?? null;
        $this->reportedAt = $values['reportedAt'] ?? null;
        $this->version = $values['version'] ?? null;
        $this->locationId = $values['locationId'] ?? null;
    }

    /**
     * @return ?string
     */
    public function getDisputeId(): ?string
    {
        return $this->disputeId;
    }

    /**
     * @param ?string $value
     */
    public function setDisputeId(?string $value = null): self
    {
        $this->disputeId = $value;
        return $this;
    }

    /**
     * @return ?string
     */
    public function getId(): ?string
    {
        return $this->id;
    }

    /**
     * @param ?string $value
     */
    public function setId(?string $value = null): self
    {
        $this->id = $value;
        return $this;
    }

    /**
     * @return ?Money
     */
    public function getAmountMoney(): ?Money
    {
        return $this->amountMoney;
    }

    /**
     * @param ?Money $value
     */
    public function setAmountMoney(?Money $value = null): self
    {
        $this->amountMoney = $value;
        return $this;
    }

    /**
     * @return ?value-of<DisputeReason>
     */
    public function getReason(): ?string
    {
        return $this->reason;
    }

    /**
     * @param ?value-of<DisputeReason> $value
     */
    public function setReason(?string $value = null): self
    {
        $this->reason = $value;
        return $this;
    }

    /**
     * @return ?value-of<DisputeState>
     */
    public function getState(): ?string
    {
        return $this->state;
    }

    /**
     * @param ?value-of<DisputeState> $value
     */
    public function setState(?string $value = null): self
    {
        $this->state = $value;
        return $this;
    }

    /**
     * @return ?string
     */
    public function getDueAt(): ?string
    {
        return $this->dueAt;
    }

    /**
     * @param ?string $value
     */
    public function setDueAt(?string $value = null): self
    {
        $this->dueAt = $value;
        return $this;
    }

    /**
     * @return ?DisputedPayment
     */
    public function getDisputedPayment(): ?DisputedPayment
    {
        return $this->disputedPayment;
    }

    /**
     * @param ?DisputedPayment $value
     */
    public function setDisputedPayment(?DisputedPayment $value = null): self
    {
        $this->disputedPayment = $value;
        return $this;
    }

    /**
     * @return ?array<string>
     */
    public function getEvidenceIds(): ?array
    {
        return $this->evidenceIds;
    }

    /**
     * @param ?array<string> $value
     */
    public function setEvidenceIds(?array $value = null): self
    {
        $this->evidenceIds = $value;
        return $this;
    }

    /**
     * @return ?value-of<CardBrand>
     */
    public function getCardBrand(): ?string
    {
        return $this->cardBrand;
    }

    /**
     * @param ?value-of<CardBrand> $value
     */
    public function setCardBrand(?string $value = null): self
    {
        $this->cardBrand = $value;
        return $this;
    }

    /**
     * @return ?string
     */
    public function getCreatedAt(): ?string
    {
        return $this->createdAt;
    }

    /**
     * @param ?string $value
     */
    public function setCreatedAt(?string $value = null): self
    {
        $this->createdAt = $value;
        return $this;
    }

    /**
     * @return ?string
     */
    public function getUpdatedAt(): ?string
    {
        return $this->updatedAt;
    }

    /**
     * @param ?string $value
     */
    public function setUpdatedAt(?string $value = null): self
    {
        $this->updatedAt = $value;
        return $this;
    }

    /**
     * @return ?string
     */
    public function getBrandDisputeId(): ?string
    {
        return $this->brandDisputeId;
    }

    /**
     * @param ?string $value
     */
    public function setBrandDisputeId(?string $value = null): self
    {
        $this->brandDisputeId = $value;
        return $this;
    }

    /**
     * @return ?string
     */
    public function getReportedDate(): ?string
    {
        return $this->reportedDate;
    }

    /**
     * @param ?string $value
     */
    public function setReportedDate(?string $value = null): self
    {
        $this->reportedDate = $value;
        return $this;
    }

    /**
     * @return ?string
     */
    public function getReportedAt(): ?string
    {
        return $this->reportedAt;
    }

    /**
     * @param ?string $value
     */
    public function setReportedAt(?string $value = null): self
    {
        $this->reportedAt = $value;
        return $this;
    }

    /**
     * @return ?int
     */
    public function getVersion(): ?int
    {
        return $this->version;
    }

    /**
     * @param ?int $value
     */
    public function setVersion(?int $value = null): self
    {
        $this->version = $value;
        return $this;
    }

    /**
     * @return ?string
     */
    public function getLocationId(): ?string
    {
        return $this->locationId;
    }

    /**
     * @param ?string $value
     */
    public function setLocationId(?string $value = null): self
    {
        $this->locationId = $value;
        return $this;
    }

    /**
     * @return string
     */
    public function __toString(): string
    {
        return $this->toJson();
    }
}
