<?php

namespace App\Representation\Entity;

use App\Auth\Entity\User;
use Doctrine\ORM\Mapping as ORM;
use App\Representation\Repository\RepresentationRepository;
use Symfony\Component\Uid\Uuid;

#[ORM\Entity(repositoryClass: RepresentationRepository::class)]
#[ORM\Table(name: 'representations')]
class Representation
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column(type: 'integer')]
    private ?int $id = null;

    #[ORM\Column(type: 'string', length: 36, unique: true)]
    private string $uuid;

    #[ORM\OneToOne(targetEntity: User::class)]
    #[ORM\JoinColumn(name: 'user_id', referencedColumnName: 'id', nullable: false, onDelete: 'CASCADE')]
    private User $user;

    #[ORM\Column(type: 'string', length: 255)]
    private string $fullName;

    #[ORM\Column(type: 'string', length: 20, nullable: true)]
    private ?string $mobileNumber = null;

    #[ORM\Column(name: 'city_id', type: 'integer', nullable: true)]
    private ?int $cityId = null;

    #[ORM\Column(name: 'commission_percent', type: 'decimal', precision: 5, scale: 2)]
    private string $commissionPercent = '10.00';

    /**
     * آرایه‌ی ۰ تا ۲ شماره شبای نماینده.
     * هر آیتم: { id, iban, bank_name, owner_name, verified, created_at }
     */
    #[ORM\Column(name: 'bank_account', type: 'json', nullable: true)]
    private ?array $bankAccount = null;

    #[ORM\Column(type: 'boolean')]
    private bool $active = true;

    #[ORM\Column(name: 'created_at', type: 'integer')]
    private int $createdAt;

    #[ORM\Column(name: 'updated_at', type: 'integer')]
    private int $updatedAt;

    public function __construct(User $user, string $fullName)
    {
        $this->uuid      = Uuid::v4()->toRfc4122();
        $this->user      = $user;
        $this->fullName  = $fullName;
        $this->createdAt = time();
        $this->updatedAt = time();
    }

    public function getId(): ?int              { return $this->id; }
    public function getUuid(): string          { return $this->uuid; }
    public function getUser(): User            { return $this->user; }
    public function getFullName(): string      { return $this->fullName; }
    public function getMobileNumber(): ?string { return $this->mobileNumber; }
    public function getCityId(): ?int          { return $this->cityId; }
    public function getCommissionPercent(): string { return $this->commissionPercent; }
    public function getBankAccount(): ?array   { return $this->bankAccount; }
    public function isActive(): bool           { return $this->active; }

    public function setFullName(string $v): self           { $this->fullName = $v; $this->touch(); return $this; }
    public function setMobileNumber(?string $v): self      { $this->mobileNumber = $v; $this->touch(); return $this; }
    public function setCityId(?int $v): self               { $this->cityId = $v; $this->touch(); return $this; }
    public function setCommissionPercent(string $v): self  { $this->commissionPercent = $v; $this->touch(); return $this; }
    public function setBankAccount(?array $v): self        { $this->bankAccount = $v; $this->touch(); return $this; }
    public function setActive(bool $v): self               { $this->active = $v; $this->touch(); return $this; }

    /** @return array<int,array<string,mixed>> */
    public function getIbans(): array { return $this->bankAccount ?? []; }

    /**
     * افزودن یک شبا (حداکثر ۲). id خودکار تولید می‌شود.
     * @param array{iban:string,bank_name:?string,owner_name:?string,verified?:bool} $iban
     */
    public function addIban(array $iban): self
    {
        $ibans = $this->getIbans();
        if (count($ibans) >= 2) {
            throw new \DomainException('iban_limit');
        }
        $ibans[] = [
            'id'         => Uuid::v4()->toRfc4122(),
            'iban'       => $iban['iban'],
            'bank_name'  => $iban['bank_name'] ?? null,
            'owner_name' => $iban['owner_name'] ?? null,
            'verified'   => $iban['verified'] ?? false,
            'created_at' => time(),
        ];
        $this->bankAccount = $ibans;
        $this->touch();
        return $this;
    }

    public function removeIban(string $id): self
    {
        $this->bankAccount = array_values(array_filter(
            $this->getIbans(),
            fn(array $i) => ($i['id'] ?? null) !== $id
        ));
        $this->touch();
        return $this;
    }

    /** @return array<string,mixed>|null یک شبای تأییدشده با این id */
    public function findVerifiedIban(string $id): ?array
    {
        foreach ($this->getIbans() as $iban) {
            if (($iban['id'] ?? null) === $id && ($iban['verified'] ?? false)) {
                return $iban;
            }
        }
        return null;
    }

    private function touch(): void { $this->updatedAt = time(); }

    public function toArray(): array
    {
        return [
            'uuid'               => $this->uuid,
            'full_name'          => $this->fullName,
            'mobile_number'      => $this->mobileNumber,
            'city_id'            => $this->cityId,
            'commission_percent' => $this->commissionPercent,
            'bank_account'       => $this->bankAccount,
            'active'             => $this->active,
            'created_at'         => $this->createdAt,
        ];
    }
}
