<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity]
#[ORM\Index(columns: ['eflex_id', 'state'], name: 'idx_eflex_line_state')]
class EFlexLine
{
    public const STATE_PREPARED = 'prepared';
    public const STATE_OK = 'ok';
    public const STATE_KO = 'ko';

    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column]
    private ?int $id = null;

    #[ORM\ManyToOne(targetEntity: EFlex::class, inversedBy: 'lines')]
    #[ORM\JoinColumn(nullable: false, onDelete: 'CASCADE')]
    private EFlex $eflex;

    #[ORM\Column(type: 'smallint')]
    private int $position;

    #[ORM\Column(type: 'decimal', precision: 10, scale: 2)]
    private string $amount;

    #[ORM\Column]
    private \DateTimeImmutable $scheduledAt;

    #[ORM\Column(length: 20, options: ['default' => 'prepared'])]
    private string $state = self::STATE_PREPARED;

    #[ORM\Column(length: 255, nullable: true)]
    private ?string $stripePaymentIntentId = null;

    #[ORM\Column(nullable: true)]
    private ?\DateTimeImmutable $paidAt = null;

    #[ORM\Column(length: 255, nullable: true)]
    private ?string $failureReason = null;

    #[ORM\Column(length: 30, nullable: true)]
    private ?string $paidMethod = null;

    #[ORM\Column]
    private \DateTimeImmutable $createdAt;

    public function __construct(EFlex $eflex, int $position, string $amount, \DateTimeImmutable $scheduledAt)
    {
        $this->eflex = $eflex;
        $this->position = $position;
        $this->amount = $amount;
        $this->scheduledAt = $scheduledAt;
        $this->createdAt = new \DateTimeImmutable();
    }

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getEflex(): EFlex
    {
        return $this->eflex;
    }

    public function getPosition(): int
    {
        return $this->position;
    }

    public function getAmount(): string
    {
        return $this->amount;
    }

    public function setAmount(string $amount): static
    {
        $this->amount = $amount;

        return $this;
    }

    public function getScheduledAt(): \DateTimeImmutable
    {
        return $this->scheduledAt;
    }

    public function getState(): string
    {
        return $this->state;
    }

    public function setState(string $state): static
    {
        $this->state = $state;

        return $this;
    }

    public function getStripePaymentIntentId(): ?string
    {
        return $this->stripePaymentIntentId;
    }

    public function setStripePaymentIntentId(?string $stripePaymentIntentId): static
    {
        $this->stripePaymentIntentId = $stripePaymentIntentId;

        return $this;
    }

    public function getPaidAt(): ?\DateTimeImmutable
    {
        return $this->paidAt;
    }

    public function setPaidAt(?\DateTimeImmutable $paidAt): static
    {
        $this->paidAt = $paidAt;

        return $this;
    }

    public function getFailureReason(): ?string
    {
        return $this->failureReason;
    }

    public function setFailureReason(?string $failureReason): static
    {
        $this->failureReason = $failureReason;

        return $this;
    }

    public function getPaidMethod(): ?string
    {
        return $this->paidMethod;
    }

    public function setPaidMethod(?string $paidMethod): static
    {
        $this->paidMethod = $paidMethod;

        return $this;
    }

    public function getCreatedAt(): \DateTimeImmutable
    {
        return $this->createdAt;
    }

    public function getLabel(): string
    {
        $months = [1 => 'Janvier', 'Fevrier', 'Mars', 'Avril', 'Mai', 'Juin', 'Juillet', 'Aout', 'Septembre', 'Octobre', 'Novembre', 'Decembre'];
        $month = $months[(int) $this->scheduledAt->format('n')] ?? '';
        $total = $this->eflex->getNbLines();

        return 'Echeance '.$this->position.'/'.$total.' - '.$month.' '.$this->scheduledAt->format('Y');
    }

    public function isPaid(): bool
    {
        return self::STATE_OK === $this->state;
    }

    public function isFailed(): bool
    {
        return self::STATE_KO === $this->state;
    }

    public function isPending(): bool
    {
        return self::STATE_PREPARED === $this->state;
    }
}
