<?php
/**
 * Project-Pro Blog
 *
 * @author    Project-Pro <https://www.project-pro.pl>
 * @copyright 2024 Project-Pro
 * @license   https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
 */

if (!defined('_PS_VERSION_')) {
    exit;
}

require_once __DIR__ . '/classes/BlogCategory.php';
require_once __DIR__ . '/classes/BlogPost.php';

class Projectproblog extends Module
{
    const POSTS_PER_PAGE = 9;

    public function __construct()
    {
        $this->name          = 'projectproblog';
        $this->tab           = 'content_management';
        $this->version       = '1.0.0';
        $this->author        = 'Project-Pro';
        $this->author_uri    = 'https://www.project-pro.pl';
        $this->need_instance = 0;
        $this->bootstrap     = true;
        $this->ps_versions_compliancy = [
            'min' => '1.7.0.0',
            'max' => _PS_VERSION_,
        ];

        parent::__construct();

        $this->displayName = $this->l('Project-Pro Blog');
        $this->description = $this->l('Moduł bloga z obsługą kategorii, podkategorii i wpisów wielojęzycznych.');
    }

    /* ------------------------------------------------------------------ */
    /*  INSTALL / UNINSTALL                                                 */
    /* ------------------------------------------------------------------ */

    public function install()
    {
        $this->createImgDir();

        return parent::install()
            && $this->installSql()
            && $this->installTabs()
            && $this->registerHook('moduleRoutes')
            && $this->registerHook('displayHome');
    }

    protected function createImgDir()
    {
        $dir = _PS_MODULE_DIR_ . 'projectproblog/views/img/posts/';
        if (!is_dir($dir)) {
            @mkdir($dir, 0755, true);
        }
    }

    public function uninstall()
    {
        return $this->uninstallTabs()
            && $this->uninstallSql()
            && parent::uninstall();
    }

    /* ------------------------------------------------------------------ */
    /*  SQL                                                                 */
    /* ------------------------------------------------------------------ */

    protected function installSql()
    {
        $sql = file_get_contents(__DIR__ . '/sql/install.sql');
        $sql = str_replace('PREFIX_', _DB_PREFIX_, $sql);

        foreach (array_filter(array_map('trim', explode(';', $sql))) as $query) {
            if (!Db::getInstance()->execute($query)) {
                return false;
            }
        }

        return true;
    }

    protected function uninstallSql()
    {
        $sql = file_get_contents(__DIR__ . '/sql/uninstall.sql');
        $sql = str_replace('PREFIX_', _DB_PREFIX_, $sql);

        foreach (array_filter(array_map('trim', explode(';', $sql))) as $query) {
            if (!Db::getInstance()->execute($query)) {
                return false;
            }
        }

        return true;
    }

    /* ------------------------------------------------------------------ */
    /*  TABS (menu admina)                                                  */
    /* ------------------------------------------------------------------ */

    protected function installTabs()
    {
        // Szukamy odpowiedniego rodzica w menu BO — fallback do 0 (główne menu)
        $parentCandidates = ['AdminParentContent', 'AdminParentCmsContent', 'AdminParentThemes'];
        $idMenuParent = 0;
        foreach ($parentCandidates as $candidate) {
            $found = (int) Tab::getIdFromClassName($candidate);
            if ($found > 0) {
                $idMenuParent = $found;
                break;
            }
        }

        // Tab-rodzic (bez kontrolera — tylko nagłówek w menu)
        $idParent = $this->addTab(
            'AdminProjectproBlog',
            'Project-Pro Blog',
            $idMenuParent,
            ''
        );
        if (!$idParent) {
            return false;
        }

        // Podmenu: Kategorie
        if (!$this->addTab(
            'AdminProjectproBlogCategories',
            'Kategorie bloga',
            $idParent,
            $this->name
        )) {
            return false;
        }

        // Podmenu: Wpisy
        if (!$this->addTab(
            'AdminProjectproBlogPosts',
            'Wpisy bloga',
            $idParent,
            $this->name
        )) {
            return false;
        }

        return true;
    }

    protected function addTab($className, $name, $idParent, $module)
    {
        $tab = new Tab();
        $tab->active      = 1;
        $tab->class_name  = $className;
        $tab->id_parent   = (int) $idParent;
        $tab->module      = $module;
        $tab->name        = [];

        foreach (Language::getLanguages(false) as $lang) {
            $tab->name[$lang['id_lang']] = $name;
        }

        if (!$tab->add()) {
            return false;
        }

        return (int) $tab->id;
    }

    protected function uninstallTabs()
    {
        $tabs = [
            'AdminProjectproBlogCategories',
            'AdminProjectproBlogPosts',
            'AdminProjectproBlog',
        ];

        foreach ($tabs as $className) {
            $id = (int) Tab::getIdFromClassName($className);
            if ($id) {
                $tab = new Tab($id);
                $tab->delete();
            }
        }

        return true;
    }

    /* ------------------------------------------------------------------ */
    /*  ROUTING                                                             */
    /* ------------------------------------------------------------------ */

    public function hookModuleRoutes()
    {
        $this->ensureDisplayHomeHookRegistration();

        return [
            'module-projectproblog-list' => [
                'controller' => 'list',
                'rule'       => 'blog',
                'keywords'   => [],
                'params'     => [
                    'fc'     => 'module',
                    'module' => $this->name,
                ],
            ],
            'module-projectproblog-category' => [
                'controller' => 'list',
                'rule'       => 'blog/kategoria/{slug}',
                'keywords'   => [
                    'slug' => [
                        'regexp' => '[_a-zA-Z0-9\-]+',
                        'param'  => 'slug',
                    ],
                ],
                'params'     => [
                    'fc'     => 'module',
                    'module' => $this->name,
                ],
            ],
            'module-projectproblog-post' => [
                'controller' => 'post',
                'rule'       => 'blog/wpis/{slug}',
                'keywords'   => [
                    'slug' => [
                        'regexp' => '[_a-zA-Z0-9\-]+',
                        'param'  => 'slug',
                    ],
                ],
                'params'     => [
                    'fc'     => 'module',
                    'module' => $this->name,
                ],
            ],
        ];
    }

    /**
     * Zapewnia podpiecie hooka displayHome takze dla istniejacych instalacji.
     */
    protected function ensureDisplayHomeHookRegistration()
    {
        $idHook = (int) Hook::getIdByName('displayHome');
        if ($idHook <= 0) {
            return;
        }

        if (!$this->isRegisteredInHook('displayHome')) {
            $this->registerHook('displayHome');
        }
    }

    /* ------------------------------------------------------------------ */
    /*  HELPERS — generowanie linków                                        */
    /* ------------------------------------------------------------------ */

    public static function getBlogUrl($idLang = null)
    {
        return Context::getContext()->link->getModuleLink('projectproblog', 'list', [], true, $idLang);
    }

    public static function getCategoryUrl($linkRewrite, $idLang = null)
    {
        return Context::getContext()->link->getModuleLink(
            'projectproblog',
            'list',
            ['slug' => $linkRewrite],
            true,
            $idLang
        );
    }

    public static function getPostUrl($linkRewrite, $idLang = null)
    {
        return Context::getContext()->link->getModuleLink(
            'projectproblog',
            'post',
            ['slug' => $linkRewrite],
            true,
            $idLang
        );
    }

    /* ------------------------------------------------------------------ */
    /*  HOMEPAGE HOOK                                                      */
    /* ------------------------------------------------------------------ */

    public function hookDisplayHome()
    {
        $idLang = (int) $this->context->language->id;
        $posts = BlogPost::getLatest($idLang, 3);

        if (empty($posts)) {
            return '';
        }

        $base = $this->context->link->getBaseLink();
        foreach ($posts as &$post) {
            $post['thumbnail_url'] = $post['thumbnail']
                ? $base . 'modules/projectproblog/views/img/posts/' . $post['thumbnail']
                : null;
            $post['url'] = self::getPostUrl($post['link_rewrite'], $idLang);
        }
        unset($post);

        if (isset($this->context->controller)) {
            $this->context->controller->registerStylesheet(
                'module-projectproblog-blog',
                'modules/projectproblog/views/css/blog.css',
                ['media' => 'all', 'priority' => 200]
            );
        }

        $this->context->smarty->assign([
            'blog_home_title' => $this->l('Najnowsze na blogu'),
            'blog_home_posts' => $posts,
            'blog_url' => self::getBlogUrl($idLang),
        ]);

        return $this->display(__FILE__, 'views/templates/hook/home.tpl');
    }
}
