<?php

/* --------------------------------------------------------------
*  demo_for_ai – образцовый модуль.
*  Содержит минимум кода, но использует все приёмы,
*  продемонстрированные в других модулях:
*
*   • регистрация модуля в $cms["modules"]
*   • проверка отключения через $cms["config"][…]["disabled"]
*   • добавление функций‑хуков (create_tables, admin, api …)
*   • работа с БД через глобальный PDO ($cms["pdo"])
*       – позиционные параметры,
*       – INSERT … SET вместо VALUES,
*       – совместимость MySQL/PGSQL.
*   • безопасные запросы в try…catch, минимум кода в блоке catch
*   • JSON‑ответы API (result / error)
*   • простая разметка и стили (Less) без лишних деталей.
* -------------------------------------------------------------- */

/* --------------------------------------------------------------
* Создайте файл .continue/rules/project-rules.md:
---
description: Правила для проекта
alwaysApply: true
---

- Ты помощник программиста, отвечай на вопросы кратко.
- Мы работаем над CMS, написанной в минималистичном стиле на PHP, JS, HTML, CSS.
- Единственный применяемый фреймворк для админки - less.js.
- В PHP используй `array()` вместо `[]`.
- В запросах PDO используй `SET` вместо `VALUES`. Объект PDO находится в глобальной переменной `$cms["pdo"]`. В запросах используй позиционные параметры. SQL-запросы для PDO должны быть совместимыми как с mysql так и с pgsql. Транзакции при запросах к БД не нужны.
- В try...catch заворачивай минимум кода, чтобы при ошибке можно было сразу ее вернуть из функции.
- Делай отступы между скобками и параметрами в скобках.
- Предпочитай использование двойных кавычек перед одинарными, в PHP даже внутри строк в двойных кавычках: `$x = "{$a["y"]} - word";`
* -------------------------------------------------------------- */

$cms["modules"]["demo_for_ai.mod.php"] = array(
    "name"        => "demo_for_ai_module_name",
    "description" => "demo_for_ai_module_decription",
    "files"       => array(
        ".cms/mod/demo_for_ai.mod.php",
        ".cms/js/demo_for_ai.js",
        ".cms/js/demo_for_ai_admin.js",
        ".cms/css/demo_for_ai.less",
        ".cms/css/demo_for_ai.css",
        ".cms/lang/ru_RU.UTF-8/demo_for_ai.mod.php",
        ".cms/man/ru_RU.UTF-8/demo_for_ai.html",
    ),
);

// Если модуль отключён – выходим
if ( ! empty( $cms["config"]["demo_for_ai.mod.php"]["disabled"] ) ) {
    return;
}

// Хуки для админки
if ( is_admin() ) {
    // Хук создания таблиц вызывается при сохранении настроек базы данных
    hook_add_fn( "create_tables", "demo_create_tables"       );
    // Подключение скриптов и стилей в админку
    hook_add_fn( "admin_header",  "demo_for_ai_admin_header" );
    // Вывод страницы в админке
    hook_add_fn( "admin",         "demo_for_ai_admin_page"   );
    // Хук api - только для админки. url для API-запросов секретен (в config.php).
    // Используется для сохранения настроек и других операций в админке.
    hook_add_fn( "api",           "demo_for_ai_api"  );
}

// Хук шаблонизации.
// Добавляем на страницы элементы для взаимодействия с пользователем сайта.
hook_add_fn( "template", "demo_for_ai_template" );

// Хук для обработки данных поступивших от пользователя.
// Скрипт на сайте при нажатии на кнопку собирает данные и отправляет
// на url /demo_for_ai_pub_api
// Данные строки создают так называемый роутинг на хук demo_for_ai_pub_hook.
// К хуку привязывается функция и будет вызвана.
// Она сохранит данные в базе данных.
$cms["urls"]["^{$cms["base_path"]}demo_for_ai_pub_api$"] = "demo_for_ai_pub_hook";
hook_add_fn( "demo_for_ai_pub_hook", "demo_for_ai_pub_api" );

/* -----------------------------------------------------------------
 *  demo_create_tables()
 *
 *  Создаёт простую таблицу demo_for_ai со столбцами, совместимыми
 *  с MySQL и PostgreSQL.
 * ----------------------------------------------------------------- */
function demo_create_tables() {
    global $cms;
    if ( empty( $cms["pdo"] ) ) { return; }

    $type = $cms["pdo"]->getAttribute( PDO::ATTR_DRIVER_NAME );
    if ( $type === "mysql" ) {
        $id_type = "BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY";
        $text_type = "LONGTEXT DEFAULT NULL";
    } elseif ( $type === "pgsql" ) {
        $id_type = "BIGSERIAL PRIMARY KEY";
        $text_type = "TEXT DEFAULT NULL";
    } else {
        return; // Неизвестный тип БД
    }

    $sql = "
        CREATE TABLE IF NOT EXISTS demo_for_ai (
            id      {$id_type},
            title   VARCHAR(255) DEFAULT '',
            content {$text_type},
            created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
        );
    ";

    try {
        $cms["pdo"]->exec( $sql );
    } catch ( PDOException $e ) {
        error_log( "Demo table creation failed: " . $e->getMessage() );
    }
}

/* -----------------------------------------------------------------
 *  demo_for_ai_admin_header()
 *
 *  Подключает в <head> админки стили и скрипты для админки.
 * ----------------------------------------------------------------- */
function demo_for_ai_admin_header() {
    global $cms;
    if ( is_admin_header_on( "demo_for_ai.mod.php" ) ) {
        // Отступ 8 пробелов для красоты вывода.
        echo "        <link rel=stylesheet href='{$cms["base_path"]}css/demo_for_ai.css'>\n";
        echo "        <script src='{$cms["base_path"]}js/demo_for_ai_admin.js'></script>\n";
    }
}

/* -----------------------------------------------------------------
 *  demo_for_ai_admin_page()
 *
 *  Вывод страницы настроек в админке.
 * ----------------------------------------------------------------- */
function demo_for_ai_admin_page() {
    global $cms;

    // Регистрируем пункт меню в боковой панели.
    $conf = & $cms["config"]["demo_for_ai.mod.php"];
    if ( empty( $conf["menu"]["demo_for_ai"] ) ) {
        $conf["menu"]["demo_for_ai"] = array(
            "title"    => "demo_for_ai_module_name",
            "sort"     => 100,
            "section"  => "settings",
            // Скрываем по умолчанию, но модули сделанные по образцу
            // данного модуля скрывать не нужно.
            "hide"     => true,
        );
        cms_save_config();
    }

    // Формируем простую форму управления записями.
    // Прижимаем к левому краю, админская страница добавит отступов.
    $page = "
<h2>" . __( "settings" ) . "</h2>

<div class='panel'>
    <label>
        <div class='title'>" . __( "title" ) . ":</div>
        <input type='text' name='title'>
    </label>
    <label>
        <div class='title'>" . __( "content" ) . ":</div>
        <textarea name='content' rows='5' cols='50'></textarea>
    </label>
    <button class='button create'>
        <span>" . __( "create_record" ) . "</span>
    </button>
</div>

<div class='panel'>
    <label>
        <div class='title'>" . __( "id" ) . ":</div>
        <input type='text' name='id'>
    </label>
    <button class='button get'>
        <span>" . __( "get_record" ) . "</span>
    </button>
    <button class='button del'>
        <span>" . __( "delete_record" ) . "</span>
    </button>
</div>
";

    // Добавляем в список выводимых страниц
    $cms["admin_pages"]["demo_for_ai"] = $page;
}

/* -----------------------------------------------------------------
 *  demo_for_ai_template()
 *
 * Добавляем на страницу запись если для такой страницы она есть.
 * ----------------------------------------------------------------- */
function demo_for_ai_template() {
    global $cms;

    if ( empty( $cms["pdo"] ) ) { return; }

    // Это проверка что запрошена обычная страница, а не файл
    $regular_page = ! empty( $cms["output"] ) && ! is_array( $cms["output"] );

    if ( $regular_page && preg_match( "/(.*)(<!--\s*demo_form\s*-->)(.*)/us", $cms["output"], $matches ) ) {
        try {
            $stmt = $cms["pdo"]->prepare(
                "SELECT title, content, created FROM demo_for_ai WHERE id = ?"
            );
            $id = (int) $cms["page"]["id"];
            $stmt->execute( array( $id ) );
            $row = $stmt->fetch( PDO::FETCH_ASSOC );

            if ( $row ) {
                $form = "
                <h3>{$row["title"]}</h3>
                <p>{$row["content"]}</p>
                <p>{$row["created"]}</p>
                <p><button data-id={$id} class='button demo'>Нажми чтобы обновить дату</button></p>
                ";
            } else {
                $form = "<p>Нет демо-формы для id:{$id}.</p>";
            }

            $cms["output"] = $matches[1] . $form . $matches[3];

            // Добавление стилей
            $styles = "";
            $alternate_file = $cms["cms_dir"] . "/{$cms['template']}/demo_for_ai.css";
            $default_file = $cms["cms_dir"] . "/css/demo_for_ai.css";
            // TODO: отступы
            if ( file_exists( $alternate_file ) ) {
                $styles = file_get_contents( $alternate_file );
            } elseif ( file_exists( $default_file ) ) {
                $styles = file_get_contents( $default_file );
            }
            $cms["output"] = str_replace( "</head>", "<style>\n{$styles}\n</style>\n</head>", $cms["output"] );

            // Добавление скрипта
            $script = file_get_contents( $cms["cms_dir"] . "/js/demo_for_ai.js" );
            $tr = json_encode( $cms["lang"]["demo_for_ai.mod.php"]["frontend"][ $cms["config"]["locale"] ] );
            $translate  = "let translate = {$tr};\n";
            $translate .= "let pid = {$cms['page']['id']};\n";
            $translate .= "let base_path = \"{$cms["base_path"]}\";\n";
            $script = str_replace( "/*translate*/", $translate, $script );
            $cms["output"] = str_replace( "</body>", "<script>\n{$script}\n</script>\n</body>", $cms["output"] );
        }
        catch ( PDOException $e ) {
            error_log( "Demo query failed: " . $e->getMessage() );
        }
    }
}

/* -----------------------------------------------------------------
 *  demo_for_ai_api()
 *
 *  Обрабатывает AJAX‑запросы из админки:
 *   – fn=demo_for_ai_create  → INSERT запись
 *   – fn=demo_for_ai_get     → SELECT запись
 *   – fn=demo_for_ai_delete  → DELETE запись
 *  Возвращает JSON, как в остальных модулях.
 * ----------------------------------------------------------------- */
function demo_for_ai_api() {
    global $cms;
    if ( empty( $_POST["fn"] ) || empty( $cms["pdo"] ) ) { return; }

    switch ( $_POST["fn"] ) {

        case "demo_for_ai_create":
            // INSERT … SET, позиционные параметры
            $stmt = $cms["pdo"]->prepare(
                "INSERT INTO demo_for_ai (title, content, created) VALUES (?, ?, ?)"
            );
            try {
                $now = date( "Y-m-d H:i:sP" );
                $stmt->execute( array( $_POST["title"], $_POST["content"], $now ) );
                $id = $cms["pdo"]->lastInsertId();
                echo json_encode( array(
                    "result" => array(
                        "id"   => $id,
                        "notify_html" => __( "record_created" )
                    )
                ) );
            }
            catch ( PDOException $e ) {
                error_log( $e->getMessage() );
                echo json_encode( array(
                    "error" => array(
                        "notify_html" => __( "error_creating_record" ) . $e->getMessage()
                    )
                ) );
            }
        break;

        case "demo_for_ai_get":
            $stmt = $cms["pdo"]->prepare(
                "SELECT title, content FROM demo_for_ai WHERE id = ?"
            );
            try {
                $stmt->execute( array( $_POST["id"] ) );
                $row = $stmt->fetch( PDO::FETCH_ASSOC );
                if ( $row ) {
                    $row["notify_html"] = "{$row["title"]}<br>{$row["content"]}";
                    echo json_encode( array(
                        "result" => $row
                    ) );
                } else {
                    echo json_encode( array(
                        "error" => array( "notify_html" => __( "record_not_found" ) )
                    ) );
                }
            }
            catch ( PDOException $e ) {
                error_log( $e->getMessage() );
                echo json_encode( array(
                    "error" => array( "notify_html" => $e->getMessage() )
                ) );
            }
        break;

        case "demo_for_ai_delete":
            $stmt = $cms["pdo"]->prepare( "DELETE FROM demo_for_ai WHERE id = ?" );
            try {
                $stmt->execute( array( $_POST["id"] ) );
                echo json_encode( array(
                    "result" => array(
                        "notify_html" => __( "record_deleted" )
                    )
                ) );
            }
            catch ( PDOException $e ) {
                error_log( $e->getMessage() );
                echo json_encode( array(
                    "error" => array( "notify_html" => $e->getMessage() )
                ) );
            }
        break;

        case "demo_for_ai_get_files":
            $count = 0;
            $wrapped_files = "";
            foreach ( $cms["modules"]["demo_for_ai.mod.php"]["files"] as $file ) {
                $file_path = $cms["site_dir"] . "/" .$file;
                $content = file_get_contents( $file_path );
                $ext = strtolower( pathinfo( $file_path, PATHINFO_EXTENSION ) );
                $wrapped = "```{$ext} {$file}\n{$content}\n```\n\n";
                $wrapped_files .= $wrapped;
                $count++;
            }
            echo json_encode( array(
                "result" => array(
                    "size"  => strlen( $wrapped_files ),
                    "lines" => count( explode( "\n", $wrapped_files ) ),
                    "files" => $wrapped_files,
                    "count" => $count,
                )
            ) );
        break;
    }
}

function demo_for_ai_pub_api() {
    global $cms;
    if ( empty( $_POST["id"] ) || empty( $cms["pdo"] ) ) { return; }

    switch ( $_POST["fn"] ) {

        case "demo_for_ai_update":
            $stmt = $cms["pdo"]->prepare(
                "UPDATE demo_for_ai SET created = ? WHERE id = ?"
            );
            try {
                $now   = date( "Y-m-d H:i:sP" );
                $id    = (int) $_POST["id"];
                $stmt->execute( array( $now, $id ) );
                echo json_encode( array(
                    "result" => "ok",
                ) );
            } catch ( PDOException $e ) {
                error_log( $e->getMessage() );
            }
        break;
    }

}
