<?php

class Task extends BaseEntity {

    protected $db_name = 'cards_task';

    // Свойства задачи
    public $id;
    public $id_project;
    public $id_department;
    public $id_label;
    public $order;
    public $column_id;
    public $date;
    public $date_closed;
    public $id_account;
    public $create_id_account;  // ID создателя задачи
    public $title;
    public $descript;
    public $descript_full;
    public $archive;

    // Валидация данных
    protected function validate() {
        static::$error_message = [];

        if (!$this->id) {
            $this->addError('id', 'ID задачи не указан');
        }
        if (!$this->title) {
            $this->addError('title', 'Название не может быть пустым');
        }

        return $this->getErrors();
    }

    // Валидация данных (для create)
    protected function validateCreate() {
        static::$error_message = [];

        if (!$this->title) {
            $this->addError('title', 'Название не может быть пустым');
        }
        if (!$this->column_id) {
            $this->addError('column_id', 'Колонка не указана');
        }
        if (!$this->id_department) {
            $this->addError('id_department', 'Департамент не указан');
        }
        if (!$this->id_project) {
            $this->addError('id_project', 'Проект не указан');
        }

        return $this->getErrors();
    }

    // Создание задачи (с файлами)
    public function create($files = []) {
        // Валидация
        if ($errors = $this->validateCreate()) {
            return $errors;
        }

        // Формируем дату создания (одна переменная для БД и ответа)
        $date_create = date('Y-m-d H:i:s');
        
        // Вставляем в базу
        Database::insert($this->db_name, [
            'id_project' => $this->id_project,
            'id_department' => $this->id_department,
            'id_label' => $this->id_label,
            'order' => $this->order ?? 0,
            'column_id' => $this->column_id,
            'date' => $this->date ?: null,
            'id_account' => $this->id_account,
            'create_id_account' => $this->create_id_account,
            'title' => $this->title,
            'descript' => $this->descript ?: null,
            'descript_full' => $this->descript_full ?: null,
            'archive' => 0,
            'date_create' => $date_create,
            'file_img' => '[]'
        ]);

        // Получаем ID созданной задачи
        $this->id = Database::id();

        // Загружаем файлы если есть
        $uploaded_files = [];
        if (!empty($files)) {
            foreach ($files as $file) {
                $result = FileUpload::upload('task', $this->id, $file['data'], $file['name']);
                if ($result['success']) {
                    $uploaded_files[] = $result['file'];
                }
            }
        }

        return [
            'success' => true,
            'id' => $this->id,
            'date' => $this->date ?: null,
            'date_create' => $date_create,
            'date_closed' => null,
            'files' => $uploaded_files
        ];
    }

    // Обновление задачи
    public function update() {
        // Валидация
        if ($errors = $this->validate()) {
            return $errors;
        }

        // Проверка что задача существует и получаем текущие данные
        $task = Database::get($this->db_name, ['id', 'column_id', 'order', 'id_project', 'archive'], ['id' => $this->id]);
        if (!$task) {
            $this->addError('task', 'Задача не найдена');
            return $this->getErrors();
        }

        // Архивные задачи нельзя редактировать
        if ((int)$task['archive'] === 1) {
            $this->addError('task', 'Архивные задачи нельзя редактировать');
            return $this->getErrors();
        }

        // Получаем текущую колонку
        $old_column_id = (int)$task['column_id'];

        // Если column_id не передан — оставляем текущий
        $new_column_id = $this->column_id !== null ? (int)$this->column_id : $old_column_id;

        // Получаем id_ready (колонка "Готово") из проекта
        $done_column_id = Project::getReadyColumnId($task['id_project']);

        // Формируем данные для обновления
        $update_data = [
            'id_department' => $this->id_department,
            'id_label' => $this->id_label,
            'order' => $this->order ?? $task['order'],
            'column_id' => $new_column_id,
            'date' => $this->date ?: null,
            'id_account' => $this->id_account,
            'title' => $this->title,
            'descript' => $this->descript ?: null,
            'descript_full' => $this->descript_full ?: null
        ];

        // Обновляем date_closed при смене колонки
        if ($done_column_id && $new_column_id === $done_column_id && $old_column_id !== $done_column_id) {
            $update_data['date_closed'] = date('Y-m-d H:i:s');
        } elseif ($done_column_id && $old_column_id === $done_column_id && $new_column_id !== $done_column_id) {
            $update_data['date_closed'] = null;
        }

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

        return ['success' => true];
    }

    // Удаление задачи
    public static function delete($id) {
        // Проверка что задача существует
        self::check_task($id);

        // Удаляем папку с файлами задачи
        FileUpload::deleteFolder('task', $id);

        // Удаляем все комментарии задачи и их файлы
        $comments = Database::select('comments', ['id'], ['id_task' => $id]);
        if ($comments) {
            foreach ($comments as $comment) {
                FileUpload::deleteFolder('comment', $comment['id']);
            }
            Database::delete('comments', ['id_task' => $id]);
        }

        // Удаляем задачу из базы
        Database::delete('cards_task', ['id' => $id]);

        return ['success' => true];
    }

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

    // Загрузка файла к задаче
    public static function uploadFile($task_id, $file_base64, $file_name) {
        // Проверка что задача существует
        $task = self::check_task($task_id);
        
        // Архивные задачи нельзя редактировать
        if ((int)$task['archive'] === 1) {
            RestApi::response([
                'success' => false, 
                'errors' => ['task' => 'Нельзя загружать файлы в архивную задачу']
            ], 400);
        }
        
        return FileUpload::upload('task', $task_id, $file_base64, $file_name);
    }

    // Удаление файлов задачи
    public static function deleteFile($task_id, $file_names) {
        // Проверка что задача существует
        $task = self::check_task($task_id);
        
        // Архивные задачи нельзя редактировать
        if ((int)$task['archive'] === 1) {
            RestApi::response([
                'success' => false, 
                'errors' => ['task' => 'Нельзя удалять файлы из архивной задачи']
            ], 400);
        }
        
        return FileUpload::delete('task', $task_id, $file_names);
    }

    // Изменение порядка и колонки задачи (с пересчётом order)
    public static function updateOrder($id, $column_id, $to_index) {
    
        // Проверка что задача существует
        $task = self::check_task($id);
        $old_column_id = (int)$task['column_id'];
        $new_column_id = (int)$column_id;
        $archive = (int)$task['archive'];

        // Архивные задачи нельзя перемещать
        if ($archive === 1) {
            RestApi::response([
                'success' => false, 
                'errors' => ['task' => 'Архивные задачи нельзя перемещать']
            ], 400);
        }

        // Получаем id_ready (колонка "Готово") из проекта
        $done_column_id = Project::getReadyColumnId($task['id_project']);

        // Получаем все карточки целевой колонки с тем же статусом архивации (кроме перемещаемой)
        $cards = Database::select('cards_task', ['id', 'order'], [
            'column_id' => $column_id,
            'archive' => $archive,
            'id[!]' => $id,
            'ORDER' => ['order' => 'ASC']
        ]) ?? [];

        // Вставляем перемещаемую карточку в нужную позицию
        array_splice($cards, $to_index, 0, [['id' => $id]]);

        // Пересчитываем order для всех карточек
        foreach ($cards as $index => $card) {
            $update_data = [
                'order' => $index,
                'column_id' => $column_id
            ];

            // Только для перемещаемой карточки обновляем date_closed
            if ($card['id'] == $id && $done_column_id) {
                // Перемещаем В колонку "Готово" — устанавливаем дату закрытия
                if ($new_column_id === $done_column_id && $old_column_id !== $done_column_id) {
                    $update_data['date_closed'] = date('Y-m-d H:i:s');
                }
                // Перемещаем ИЗ колонки "Готово" — обнуляем дату
                elseif ($old_column_id === $done_column_id && $new_column_id !== $done_column_id) {
                    $update_data['date_closed'] = null;
                }
            }

            Database::update('cards_task', $update_data, [
                'id' => $card['id']
            ]);
        }

        return ['success' => true];
    }

    // Получение всех задач проекта
    // $id_project: ID проекта (обязательный)
    // $archive: 0 = неархивные, 1 = архивные, null = все
    public function getAll($id_project, $archive = 0) {
        $where = [
            'id_project' => $id_project
        ];
        if ($archive !== null) {
            $where['archive'] = $archive ? 1 : 0;
        }

        $tasks = Database::select($this->db_name, [
            'id',
            'id_project',
            'id_department',
            'id_label',
            'id_account',
            'create_id_account',
            'order',
            'column_id',
            'date',
            'date_create',
            'date_closed',
            'file_img',
            'title',
            'descript',
            'descript_full',
            'archive'
        ], $where);

        // Получаем количество комментариев для всех задач одним запросом
        $task_ids = array_column($tasks, 'id');
        $comments_counts = [];
        if (!empty($task_ids)) {
            $counts = Database::query(
                "SELECT id_task, COUNT(*) as cnt FROM comments WHERE id_task IN (" . implode(',', $task_ids) . ") GROUP BY id_task"
            )->fetchAll(\PDO::FETCH_ASSOC);
            foreach ($counts as $row) {
                $comments_counts[$row['id_task']] = (int)$row['cnt'];
            }
        }

        // Декодируем JSON и получаем avatar_url из accounts
        return array_map(function($task) use ($comments_counts) {
            $task['file_img'] = $task['file_img'] ? json_decode($task['file_img'], true) : [];
            
            // Получаем avatar_url из accounts по id_account
            if ($task['id_account']) {
                $account = Database::get('accounts', ['avatar_url'], ['id' => $task['id_account']]);
                $task['avatar_img'] = $account['avatar_url'] ?? null;
            } else {
                $task['avatar_img'] = null;
            }
            
            // Количество комментариев
            $task['comments_count'] = $comments_counts[$task['id']] ?? 0;
            
            return $task;
        }, $tasks);
    }

    // Получение колонок проекта
    public function getColumns($id_project) {
        return Database::select('columns', [
            'id',
            'name_columns',
            'color',
            'id_order'
        ], [
            'id_project' => $id_project,
            'ORDER' => ['id_order' => 'ASC']
        ]);
    }

    // Получение отделов проекта
    public function getDepartments($id_project) {
        return Database::select('departments', [
            'id',
            'name_departments',
            'color'
        ], [
            'id_project' => $id_project
        ]);
    }

    // Получение всех меток
    public function getLabels() {
        return Database::select('labels', [
            'id',
            'name_labels',
            'icon',
            'color'
        ]);
    }

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

    // Установка статуса архивации задачи (только для задач в колонке "Готово")
    public static function setArchive($id, $archive = 1) {
        // Проверка что задача существует
        $task = self::check_task($id);

        // Получаем id_ready (колонка "Готово") из проекта
        $done_column_id = Project::getReadyColumnId($task['id_project']);

        // Архивировать можно только задачи в колонке "Готово"
        if ($archive && $done_column_id && (int)$task['column_id'] !== $done_column_id) {
            RestApi::response([
                'success' => false, 
                'errors' => ['column' => 'Архивировать можно только задачи из колонки "Готово"']
            ], 400);
        }

        // Данные для обновления
        $update_data = [
            'archive' => $archive ? 1 : 0
        ];

        // При разархивировании — возвращаем в колонку "Готово"
        if (!$archive && $done_column_id) {
            $update_data['column_id'] = $done_column_id;
        }

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

        return ['success' => true, 'archive' => $archive ? 1 : 0];
    }
}

?>