<?php
declare(strict_types=1);

namespace App\Model\Table;

use Cake\ORM\Table;

class VideoCommentsTable extends Table
{
	public function initialize(array $config): void
	{
		parent::initialize($config);

		$this->setTable('video_comment');
		$this->setPrimaryKey('id');

		$this->belongsTo('Videos', [
			'foreignKey' => 'video_id',
		]);

		$this->belongsTo('Users', [
			'foreignKey' => 'user_id',
			'fields' => USER_FIELDS
		]);

		$this->belongsTo('Parents', [
			'className' => 'VideoComments',
			'foreignKey' => 'parent_id',
		]);

		$this->hasMany('Children', [
			'className' => 'VideoComments',
			'foreignKey' => 'parent_id',
		]);
	}

	public function getDetails(int $id): ?array
	{
		return $this->find()
			->where(['VideoComments.id' => $id])
			->enableHydration(false)
			->first();
	}

	public function countComments(int $video_id): int
	{
		return $this->find()
			->where(['VideoComments.video_id' => $video_id])
			->count();
	}

	public function getPinnedComment(int $video_id): ?array
	{
		return $this->find()
			->where([
				'VideoComments.video_id' => $video_id,
				'VideoComments.pin' => 1
			])
			->enableHydration(false)
			->first();
	}

	public function countCommentsBetweenDates(array $video_ids, string $start_datetime, string $end_datetime): int
	{
		return $this->find()
			->where([
				'VideoComments.video_id IN' => $video_ids,
				'VideoComments.created >=' => $start_datetime,
				'VideoComments.created <=' => $end_datetime,
			])
			->count();
	}

	public function getVideoComments(int $video_id, int $starting_point): array
	{
		$comments = $this->find()
			->where([
				'VideoComments.video_id' => $video_id,
				'VideoComments.parent_id' => 0,
			])
			->contain(['Users', 'Children.Users'])
			->order(['VideoComments.id' => 'DESC'])
			->limit(20)
			->offset($starting_point * 20)
			->enableHydration(false)
			->all()
			->toList();

		foreach ($comments as &$comment) {
			unset($comment['Video']);
			$comment['Children'] = $this->getNestedComments($comment['id']);
		}

		return $comments;
	}

	public function getNestedComments(int $parent_id): array
	{
		$children = $this->find()
			->where(['VideoComments.parent_id' => $parent_id])
			->contain(['Users', 'Children.Users'])
			->order(['VideoComments.id' => 'ASC'])
			->enableHydration(false)
			->all()
			->toList();

		foreach ($children as &$child) {
			unset($child['Video']);
			$child['Children'] = $this->getNestedComments($child['id']);
		}

		return $children;
	}

	public function getAll(): array
	{
		return $this->find()
			->enableHydration(false)
			->all()
			->toList();
	}

	public function updatePin(int $video_id): bool
	{
		return $this->updateAll(
			['pin' => 0],
			['video_id' => $video_id]
		);
	}
}
