<?php

namespace App\Rating\Entity;

use App\Auth\Entity\User;
use App\Doctor\Entity\Doctor;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use App\Rating\Repository\CommentRepository;
use Symfony\Component\Uid\Uuid;

#[ORM\Entity(repositoryClass: CommentRepository::class)]
#[ORM\Table(name: 'comments')]
#[ORM\Index(columns: ['doctor_id', 'status'], name: 'idx_comments_doctor_status')]
class Comment
{
    public const STATUS_PENDING  = 'pending';
    public const STATUS_APPROVED = 'approved';
    public const STATUS_REJECTED = 'rejected';

    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column(type: 'integer')]
    private ?int $id = null;

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

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

    #[ORM\ManyToOne(targetEntity: Doctor::class)]
    #[ORM\JoinColumn(name: 'doctor_id', referencedColumnName: 'id', nullable: false, onDelete: 'CASCADE')]
    private Doctor $doctor;

    #[ORM\ManyToOne(targetEntity: Comment::class, inversedBy: 'replies')]
    #[ORM\JoinColumn(name: 'parent_id', referencedColumnName: 'id', nullable: true, onDelete: 'CASCADE')]
    private ?Comment $parent = null;

    #[ORM\OneToMany(targetEntity: Comment::class, mappedBy: 'parent')]
    private Collection $replies;

    #[ORM\Column(type: 'text')]
    private string $body;

    #[ORM\Column(type: 'string', length: 20)]
    private string $status = self::STATUS_PENDING;

    #[ORM\OneToMany(targetEntity: Like::class, mappedBy: 'comment', cascade: ['remove'])]
    private Collection $likes;

    #[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, Doctor $doctor, string $body, ?Comment $parent = null)
    {
        $this->uuid      = Uuid::v4()->toRfc4122();
        $this->user      = $user;
        $this->doctor    = $doctor;
        $this->body      = $body;
        $this->parent    = $parent;
        $this->likes     = new ArrayCollection();
        $this->replies   = new ArrayCollection();
        $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 getDoctor(): Doctor { return $this->doctor; }
    public function getBody(): string   { return $this->body; }
    public function getStatus(): string { return $this->status; }
    public function getLikes(): Collection { return $this->likes; }
    public function getParent(): ?Comment { return $this->parent; }
    public function getReplies(): Collection { return $this->replies; }

    public function setBody(string $v): self { $this->body = $v; $this->updatedAt = time(); return $this; }

    public function approve(): self { $this->status = self::STATUS_APPROVED; $this->updatedAt = time(); return $this; }
    public function reject(): self  { $this->status = self::STATUS_REJECTED;  $this->updatedAt = time(); return $this; }

    public function toArray(?User $currentUser = null): array
    {
        $likeCount = 0;
        $dislikeCount = 0;
        $userLike = false;
        $userDislike = false;

        foreach ($this->likes as $like) {
            if ($like->getValue() >= 0) {
                $likeCount++;
            } else {
                $dislikeCount++;
            }
            if ($currentUser !== null && $like->getUser()->getId() === $currentUser->getId()) {
                $userLike = $like->getValue() >= 0;
                $userDislike = $like->getValue() < 0;
            }
        }

        $replies = [];
        foreach ($this->replies as $reply) {
            if ($reply->getStatus() === self::STATUS_APPROVED) {
                $replies[] = $reply->toArray($currentUser);
            }
        }

        return [
            'uuid'    => $this->uuid,
            'comment' => $this->body,
            'created' => $this->createdAt,
            'parent'  => $this->parent?->getUuid(),
            'author'  => [
                'real_name' => $this->user->getRealName() ?? 'کاربر نوبت‌۷۲۴',
                'picture'   => [],
            ],
            'like_status' => [
                'like_count'    => $likeCount,
                'dislike_count' => $dislikeCount,
                'current_user_like' => [
                    'like'    => $userLike,
                    'dislike' => $userDislike,
                ],
            ],
            'replies' => $replies,
        ];
    }
}
