<?php

namespace app\foreignone\files;

use engine\Model;

class Book
    extends Model
    implements FileInterface
{
    const DB_TABLE = 'books';

    public int $id;
    public int $parentId;
    public string $author;
    public string $title;
    public string $subtitle;
    public int $year;
    public int $size;
    public string $type;
    public string $fileType;
    public string $path;
    public bool $external;
    public SectionType $category; // TODO: rename column to `section`

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

    public function getUrl(): string {
        if ($this->type == 'folder' && !$this->external)
            return '/files/'.$this->id.'/';
        global $config;
        $buf = 'https://'.$config['files_domain'];
        if (!str_starts_with($this->path, '/'))
            $buf .= '/';
        $buf .= $this->path;
        return $buf;
    }

    public function getTitleHtml(): ?string {
        if ($this->type == 'folder' || !$this->author)
            return null;
        $buf = '<b class="is-author">'.htmlescape($this->author).'</b><span class="is-title">';
        if (!str_ends_with($this->author, '.'))
            $buf .= '.';
        $buf .= ' '.htmlescape($this->title).'</span>';
        return $buf;
    }

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

    public function getMeta(?string $hl_matched = null): array {
        if ($this->type == 'folder')
            return [];

        $items = [
            sizeString($this->size),
            strtoupper($this->getExtension())
        ];

        return [
            'inline' => false,
            'items' => $items
        ];
    }

    protected function getExtension(): string {
        return extension(basename($this->path));
    }

    public function isTargetBlank(): bool {
        return $this->type == 'file' || $this->external;
    }

    public function getSubtitle(): ?string {
        if (!$this->year && !$this->subtitle)
            return null;
        $buf = '(';
        $buf .= $this->subtitle ?: $this->year;
        $buf .= ')';
        return $buf;
    }

    public function getSize(): ?int {
        return $this->type == 'file' ? $this->size : null;
    }

    public function getIcon(): string {
        if ($this->fileType == 'book')
            return 'book';
        return $this->type;
    }


    /**
     * Static methods
     */

    /**
     * @return Book[]
     */
    public static function getList(SectionType $section, int $parent_id = 0): array
    {
        $db = getDB();
        $order_by = $section == SectionType::BOOKS_AND_ARTICLES
            ? "type, ".($parent_id != 0 ? 'year, ': '')."author, title"
            : "type, title";
        $q = $db->query("SELECT * FROM books WHERE category=? AND parent_id=? ORDER BY $order_by",
            $section->value, $parent_id);
        return array_map(static::create_instance(...), $db->fetchAll($q));
    }

    /**
     * @param int $id
     * @param bool $with_parents
     * @return static[]|static|null
     */
    public static function getFolder(int $id, bool $with_parents = false): static|array|null {
        $db = getDB();
        $q = $db->query("SELECT * FROM books WHERE id=?", $id);
        if (!$db->numRows($q))
            return null;
        $item = new Book($db->fetch($q));
        if ($item->type != 'folder')
            return null;
        if ($with_parents) {
            $items = [$item];
            if ($item->parentId) {
                $parents = static::getFolder($item->parentId, with_parents: true);
                if ($parents !== null)
                    $items = array_merge($items, $parents);
            }
            return $items;
        }
        return $item;
    }
}
