<?php

// It's good practice to use namespaces, e.g.:
// namespace VintageCoding\Models;
// namespace VintageCoding\Repositories;

require_once 'functions/db.php';  // For exec_stmt() and get_connection() (though get_connection is used by exec_stmt)
require_once 'functions/user.php';  // For User and Author classes
require_once 'functions/space.php';

// -- Data Transfer Object for Topics --
class Topic
{
    public int $topicId;
    public string $name;

    public function __construct(int $topicId, string $name)
    {
        $this->topicId = $topicId;
        $this->name = $name;
    }

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

    public function getName(): string
    {
        return $this->name;
    }
}

// -- Post Data Models (as previously defined, with setReadCount in Post) --
class Post
{
    private ?Space $space;
    private ?int $id;
    private User $creator;
    private int $postType;
    private ?int $status;
    private int $seenCount;
    private ?DateTime $createdAt;
    private ?DateTime $updatedAt;

    public function __construct(?Space $space = null, ?int $id = null, User $creator, int $postType, int $status)
    {
        $this->space = $space;
        $this->id = $id;
        $this->creator = $creator;
        $this->postType = $postType;
        $this->status = $status;

        $this->seenCount = 0;
    }

    public static function exists(int $id): bool
    {
        $stmt = 'SELECT count(id) FROM post WHERE id = ?';
        $result = exec_stmt($stmt, 'i', $id)->fetch_assoc();
        if ($result['count(id)'] == 1)
            return true;
        else if ($result['count(id)'] > 1) {
            // TODO: Add additional logging here, since that means multiple posts have the same ID.
            return true;
        }

        return false;
    }

    public static function retrieveFromDB(int $id): ?Post
    {
        $stmt = 'SELECT * FROM post WHERE id = ?';
        $post = exec_stmt($stmt, 'i', $id)->fetch_assoc();
        if ($post) {
            $creator = User::retrieveFromDB($post['creator']);

            switch ($post['postType']) {
                case 1:
                    return new Essay(null, $id, $creator, 1, $post['status'], $post['title'], $post['markdown'], $post['excerpt']);
                case 3:
                    return new Thought(null, $post['id'], $creator, 3, $post['status'], $post['thought']);
                default:
                    return null;
            }
        } else
            return null;
    }

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

    public function authUser(User $user): bool
    {
        return true;
    }

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

    public function getCreator(): User
    {
        return $this->creator;
    }

    public function getPostType(): int
    {
        return $this->postType;
    }

    public function getSeenCount(): int
    {
        return $this->seenCount;
    }

    public function getCreatedAt(): ?DateTime
    {
        return $this->createdAt;
    }

    public function getUpdatedAt(): ?DateTime
    {
        return $this->updatedAt;
    }

    public function getStatus(): ?DateTime
    {
        return $this->status;
    }

    public function incrementSeenCount(): void
    {
        $this->seenCount++;
    }

    public function setStatus(?int $status): void
    {
        $this->status = $status;
    }

    public function setSpace(Space $space): void
    {
        $this->space = $space;
    }

    public function getSpace(): ?Space
    {
        return $this->space;
    }
}

class Essay extends Post
{
    private string $title;
    private string $html;
    private string $excerpt;
    /* private array $files; */

    public function __construct(?Space $space = null, ?int $id = null, User $creator, int $postType, int $status, string $title, string $markdown, string $excerpt)
    {
        parent::__construct($space, $id, $creator, 1, $postType, $status);
        require_once 'vendor/autoload.php';

        $parsedown = new Parsedown();
        $parsedown->setSafeMode(true);

        $this->title = $title;
        $this->excerpt = $excerpt;
        $this->html = $parsedown->text($markdown);
    }

    public function getCardHTML(): ?string
    {
        /* <a href="user.php?view=display&id=' . parent::getCreator()->getId() . '">@' . parent::getCreator()->getUsername() . '</a> */
        $html = '
            <div class="full_width std_border padding center top_margin bottom_margin">
                <a href="spaces.php?view=essay&id=' . parent::getId() . '" class="divLink">
                    <div class="row space_between full_width">
                        <div class="column std_width">
                            <h4>' . $this->title . '</h4>
                        </div>
                        
                        <div class="">
                            <span>Something</span>
                        </div>
                    </div>
                    <div class="row full_width">
                        <p>' . $this->excerpt . '</p>
                    </div>
                </a>
            </div>
        ';

        return $html;
    }

    public function getTitle(): ?string
    {
        return $this->title;
    }

    public function getHTML(): ?string
    {
        return $this->html;
    }

    public function getExcerpt(): ?string
    {
        return $this->excerpt;
    }

    public function setMarkdown(?string $markdown): void
    {
        require_once 'vendor/autoload.php';
        $parsedown = new Parsedown();
        $parsedown->setSafeMode(true);
        $this->html = $parsedown->text($markdown);
    }

    public function setExcerpt(?string $excerpt): void
    {
        $this->excerpt = $excerpt;
    }
}

class Moment extends Post
{
    private ?string $caption;
    private ?array $images;

    public function __construct(?Space $space = null, ?int $id = null, User $creator, int $postType, int $status, ?array $images = null, ?string $caption = null)
    {
        parent::__construct($space, $id, $creator, $postType, $status);
        $this->caption = $caption;
        $this->images = $images;
    }

    public function getCaption(): ?string
    {
        return $this->caption;
    }

    public function getImages(): ?array
    {
        return $this->images;
    }

    public function setCaption(?string $caption): void
    {
        $this->caption = $caption;
    }

    public function setImages(?array $images): void
    {
        $this->images = $images;
    }
}

class Thought extends Post
{
    private ?string $thought;

    public function __construct(?Space $space = null, ?int $id = null, User $creator, int $postType, int $status, string $thought)
    {
        parent::__construct($space, $id, $creator, $postType, $status);
        $this->thought = $thought;

        if ($id == null) {
            $stmt = 'INSERT INTO post (id, parentSpace, creator, postType, status, thought) VALUES (?, ?, ?, ?, ?, ?)';
            $newID = randomId(1);
            parent::setId($newID);
            $space = isset($space) ? $space->getId() : $creator->getHomeSpace()->getId();
            exec_stmt($stmt, 'iiiiis', $newID, $space, $creator->getId(), 3, 2, $this->thought);
            $stmt = 'INSERT INTO spacePosts (post, space) VALUES (?, ?)';
            exec_stmt($stmt, 'ii', $newID, $space);
        }
    }

    public function getCardHTML(): ?string
    {
        $html = '
            <div class="std_border padding center full_width top_margin bottom_margin">
                <div class="row space_between full_width">
                    <a href="user.php?view=display&id=' . parent::getCreator()->getId() . '">@' . parent::getCreator()->getUsername() . '</a>
                    
                    <div class="">
                        <span>Something</span>
                    </div>
                </div>
                <div class="line"></div>
                <div class="row full_width">
                    <p>' . $this->thought . '</p>
                </div>
            </div>
        ';

        return $html;
    }

    public function getThought(): ?string
    {
        return $this->thought;
    }

    public function setThought(?string $thought): void
    {
        $this->thought = $thought;
    }
}
