<?php

namespace RtmBusiness\PostSync\Model;

use DateTime;

class SyncData
{

    public int $id = 0;

    /**
     * @param string $syncType The sync type
     * @param int $parentBlogId The blog id for the main site
     * @param int $parentPostId The post id on the main site
     * @param SyncableChild[] $linkedChildren Map containing array of SyncableChild for blog id as index
     */
    public function __construct(public readonly string $syncType, public readonly int $parentBlogId, public readonly int $parentPostId, private array $linkedChildren = [], protected ?DateTime $deletedOn = null)
    {
    }

    /**
     * Verifies whether the given blog and post are a child of parent site
     * @param int $blog_id The child blog to check
     * @return bool Whether the given blog is linked to parent blog
     */
    public function isLinkedToChildBlog(int $blog_id): bool
    {
        foreach ($this->linkedChildren as $child) {
            if ($child->blogId == $blog_id) {
                return true;
            }
        }
        return false;
    }

    /**
     * Retrieves the post id of the linked post on child site
     * @param int $blog_id The child blog to check
     * @return int|null The id of the child post that is linked or null if no such thing exists
     */
    public function getLinkedPostId(int $blog_id): int|null
    {
        if ($blog_id == $this->parentBlogId) {
            return $this->parentPostId;
        }
        foreach ($this->linkedChildren as $child) {
            if ($child->blogId == $blog_id) {
                return $child->postId;
            }
        }
        return null;
    }

    /**
     * Retrieves the SyncableChild of a linked post on child site
     * @param int $blog_id The child blog to check
     * @return SyncableChild|null The SyncableChild object that is linked to this relation or null if no such thing exists
     */
    public function getLinkedChild(int $blog_id): SyncableChild|null
    {
        foreach ($this->linkedChildren as $child) {
            if ($child->blogId == $blog_id) {
                return $child;
            }
        }
        return null;
    }


    /**
     * Adds a reference to a child blog and post id as children for this SyncData object
     *
     * @param int $postId The child post id
     * @param int|null $blogId The child blog id or leave empty for current blog id
     * @return void
     */
    public function addChild(int $postId, ?int $blogId = null)
    {
        $blogId ??= get_current_blog_id();
        $this->linkedChildren[] = new SyncableChild($blogId, $postId);
    }

    /**
     * Removes a child blog and post id from the SyncData object's linked children
     *
     * @param int $postId The child post id
     * @param int|null $blogId The child blog id or leave empty for current blog id
     * @return void
     */
    public function removeChild(int $postId, ?int $blogId = null)
    {
        $blogId ??= get_current_blog_id();

        // Loop through the linked children and remove the specified child
        foreach ($this->linkedChildren as $key => $child) {
            if ($child->blogId === $blogId && $child->postId === $postId) {
                unset($this->linkedChildren[$key]);
                break;
            }
        }
    }

    /**
     * @return SyncableChild[]
     */
    public function getLinkedChildren(): array
    {
        return $this->linkedChildren;
    }

    /**
     * @param SyncableChild[] $linkedChildren
     */
    public function setLinkedChildren(array $linkedChildren): void
    {
        $this->linkedChildren = $linkedChildren;
    }


    /**
     * Clears the linked children for this SyncData object
     * @return void
     */
    public function clearChildren(): void
    {
        $this->linkedChildren = [];
    }

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

    /**
     * @param int $id
     */
    public function setId(int $id): void
    {
        $this->id = $id;
    }

    /**
     * @param DateTime|null $deletedOn
     */
    public function setDeletedOn(?DateTime $deletedOn): void
    {
        $this->deletedOn = $deletedOn;
    }


    /**
     * @return DateTime|null The datetime when the parent post was softdeleted
     */
    public function getDeletedOn(): ?DateTime
    {
        return $this->deletedOn;
    }


}
