<?php

class Comment extends BaseEntity {

    protected $db_name = 'comments';

    // Свойства комментария
    public $id;
    public $id_task;
    public $id_accounts;
    public $id_answer;  // ID родительского комментария (ответ на)
    public $text;
    public $date_create;

    // Создание комментария
    public function create() {
        static::$error_message = [];

        // Валидация
        if (!$this->id_task) {
            $this->addError('id_task', 'Задача не указана');
        }
        if (!$this->id_accounts) {
            $this->addError('id_accounts', 'Пользователь не указан');
        }
        if (!$this->text || trim($this->text) === '') {
            $this->addError('text', 'Текст комментария не может быть пустым');
        }
        if ($errors = $this->getErrors()) {
            return $errors;
        }

        // Проверяем что задача существует и не архивная
        $task = Task::check_task($this->id_task);
        if ((int)$task['archive'] === 1) {
            $this->addError('task', 'Нельзя комментировать архивные задачи');
            return $this->getErrors();
        }

        // Если это ответ — проверяем что родительский комментарий существует
        if ($this->id_answer) {
            self::checkComment($this->id_answer);
        }

        // Вставляем в базу
        Database::insert($this->db_name, [
            'id_task' => $this->id_task,
            'id_accounts' => $this->id_accounts,
            'id_answer' => $this->id_answer ?: null,
            'text' => $this->text,
            'date_create' => date('Y-m-d H:i:s'),
            'file_img' => '[]'
        ]);

        $this->id = Database::id();

        // Возвращаем созданный комментарий с данными пользователя
        return [
            'success' => true,
            'comment' => $this->getById($this->id)
        ];
    }

    // Обновление комментария
    public function update() {
        static::$error_message = [];

        // Валидация
        if (!$this->id) {
            $this->addError('id', 'ID комментария не указан');
        }
        if (!$this->text || trim($this->text) === '') {
            $this->addError('text', 'Текст комментария не может быть пустым');
        }
        if ($errors = $this->getErrors()) {
            return $errors;
        }

        // Проверяем что комментарий существует
        $comment = self::checkComment($this->id);

        // Проверяем что задача не архивная
        $task = Database::get('cards_task', ['archive'], ['id' => $comment['id_task']]);
        if ($task && (int)$task['archive'] === 1) {
            $this->addError('task', 'Нельзя редактировать комментарии архивных задач');
            return $this->getErrors();
        }

        // Проверяем что пользователь — автор комментария
        if ((int)$comment['id_accounts'] !== (int)$this->id_accounts) {
            $this->addError('access', 'Вы можете редактировать только свои комментарии');
            return $this->getErrors();
        }

        // Обновляем в БД
        Database::update($this->db_name, [
            'text' => $this->text
        ], [
            'id' => $this->id
        ]);

        return [
            'success' => true,
            'comment' => $this->getById($this->id)
        ];
    }

    // Удаление комментария (с дочерними)
    public static function delete($id, $id_accounts) {
        // Проверяем что комментарий существует
        $comment = self::checkComment($id);

        // Получаем задачу для проверки админа проекта и архивации
        $task = Database::get('cards_task', ['id_project', 'archive'], ['id' => $comment['id_task']]);
        
        // Нельзя удалять комментарии архивных задач
        if ($task && (int)$task['archive'] === 1) {
            RestApi::response([
                'success' => false,
                'errors' => ['task' => 'Нельзя удалять комментарии архивных задач']
            ], 400);
        }
        
        // Проверяем права: автор комментария ИЛИ админ проекта
        $isAuthor = (int)$comment['id_accounts'] === (int)$id_accounts;
        $isProjectAdmin = $task && ProjectAccess::isAdmin($task['id_project'], $id_accounts);
        
        if (!$isAuthor && !$isProjectAdmin) {
            RestApi::response([
                'success' => false,
                'errors' => ['access' => 'Нет прав на удаление комментария']
            ], 403);
        }

        // Рекурсивно удаляем все дочерние комментарии
        self::deleteWithChildren($id);

        return ['success' => true];
    }

    // Рекурсивное удаление комментария и всех его дочерних
    private static function deleteWithChildren($id) {
        // Находим все дочерние комментарии
        $children = Database::select('comments', ['id'], ['id_answer' => $id]);
        
        // Рекурсивно удаляем дочерние
        if ($children) {
            foreach ($children as $child) {
                self::deleteWithChildren($child['id']);
            }
        }
        
        // Удаляем папку с файлами комментария
        FileUpload::deleteFolder('comment', $id);
        
        // Удаляем сам комментарий
        Database::delete('comments', ['id' => $id]);
    }

    // Удаление комментария (проверка прав уже выполнена на уровне API)
    public static function deleteWithAccess($id) {
        // Рекурсивно удаляем все дочерние комментарии
        self::deleteWithChildren($id);
        return ['success' => true];
    }

    // === МЕТОДЫ ДЛЯ РАБОТЫ С ФАЙЛАМИ ===

    // Загрузка файла к комментарию (проверка прав уже выполнена на уровне API)
    public static function uploadFileSimple($comment_id, $file_base64, $file_name) {
        return FileUpload::upload('comment', $comment_id, $file_base64, $file_name);
    }

    // Удаление файлов комментария (проверка прав уже выполнена на уровне API)
    public static function deleteFileSimple($comment_id, $file_names) {
        return FileUpload::delete('comment', $comment_id, $file_names);
    }

    // Загрузка файла к комментарию (только автор может загружать) - DEPRECATED
    public static function uploadFile($comment_id, $file_base64, $file_name, $user_id) {
        // Проверка что комментарий существует
        $comment = self::checkComment($comment_id);
        
        // Проверка что пользователь — автор комментария
        if ((int)$comment['id_accounts'] !== (int)$user_id) {
            RestApi::response([
                'success' => false,
                'errors' => ['access' => 'Вы можете загружать файлы только к своим комментариям']
            ], 403);
        }
        
        return FileUpload::upload('comment', $comment_id, $file_base64, $file_name);
    }

    // Удаление файлов комментария (автор или админ проекта) - DEPRECATED
    public static function deleteFile($comment_id, $file_names, $user_id) {
        // Проверка что комментарий существует
        $comment = self::checkComment($comment_id);
        
        // Получаем задачу для проверки админа проекта
        $task = Database::get('cards_task', ['id_project'], ['id' => $comment['id_task']]);
        
        // Проверка прав: автор комментария ИЛИ админ проекта
        $isAuthor = (int)$comment['id_accounts'] === (int)$user_id;
        $isProjectAdmin = $task && ProjectAccess::isAdmin($task['id_project'], $user_id);
        
        if (!$isAuthor && !$isProjectAdmin) {
            RestApi::response([
                'success' => false,
                'errors' => ['access' => 'Нет прав на удаление файлов']
            ], 403);
        }
        
        return FileUpload::delete('comment', $comment_id, $file_names);
    }

    // Получение комментария по ID (с данными пользователя)
    public function getById($id) {
        $comment = Database::get($this->db_name, [
            '[>]accounts' => ['id_accounts' => 'id']
        ], [
            'comments.id',
            'comments.id_task',
            'comments.id_accounts',
            'comments.id_answer',
            'comments.text',
            'comments.date_create',
            'comments.file_img',
            'accounts.name(author_name)',
            'accounts.avatar_url(author_avatar)'
        ], [
            'comments.id' => $id
        ]);

        // Декодируем JSON файлов
        if ($comment) {
            $comment['file_img'] = $comment['file_img'] ? json_decode($comment['file_img'], true) : [];
        }

        return $comment;
    }

    // Получение всех комментариев задачи
    public function getByTask($id_task) {
        // Проверяем что задача существует
        Task::check_task($id_task);

        $comments = Database::select($this->db_name, [
            '[>]accounts' => ['id_accounts' => 'id']
        ], [
            'comments.id',
            'comments.id_task',
            'comments.id_accounts',
            'comments.id_answer',
            'comments.text',
            'comments.date_create',
            'comments.file_img',
            'accounts.name(author_name)',
            'accounts.avatar_url(author_avatar)'
        ], [
            'comments.id_task' => $id_task,
            'ORDER' => ['comments.date_create' => 'ASC']
        ]);

        // Декодируем JSON файлов для каждого комментария
        return array_map(function($comment) {
            $comment['file_img'] = $comment['file_img'] ? json_decode($comment['file_img'], true) : [];
            return $comment;
        }, $comments ?: []);
    }

    // Проверка и получение комментария (при ошибке — сразу ответ и exit)
    public static function checkComment($id) {
        $comment = Database::get('comments', '*', ['id' => $id]);
        if (!$id || !$comment) {
            RestApi::response(['success' => false, 'errors' => ['comment' => 'Комментарий не найден']], 404);
        }
        return $comment;
    }
}

?>
