<?php

class ProjectInvite {

    const STATUS_PENDING = 'pending';
    const STATUS_ACCEPTED = 'accepted';
    const STATUS_DECLINED = 'declined';

    // ==================== СОЗДАНИЕ ПРИГЛАШЕНИЯ ====================

    /**
     * Создать приглашение в проект
     */
    public static function create(int $project_id, int $to_user_id, int $from_user_id, bool $is_admin = false, ?array $permissions = null): array {
        // Нельзя пригласить себя
        if ($to_user_id === $from_user_id) {
            return ['success' => false, 'errors' => ['invite' => 'Нельзя пригласить себя в проект']];
        }

        // Проверяем, что пользователь существует
        $user = Database::get('accounts', ['id'], ['id' => $to_user_id]);
        if (!$user) {
            return ['success' => false, 'errors' => ['invite' => 'Пользователь не найден']];
        }

        // Проверяем, что пользователь ещё не участник проекта
        if (ProjectAccess::isMember($project_id, $to_user_id)) {
            return ['success' => false, 'errors' => ['invite' => 'Пользователь уже участник проекта']];
        }

        // Проверяем, нет ли уже pending-приглашения
        if (self::hasPending($project_id, $to_user_id)) {
            return ['success' => false, 'errors' => ['invite' => 'Пользователь уже приглашён, ожидается ответ']];
        }

        // Права по умолчанию
        $perms = $permissions ?? ProjectAccess::DEFAULT_PERMISSIONS;

        // Сохраняем is_admin в permissions для передачи при accept
        $inviteData = [
            'is_admin' => $is_admin,
            'permissions' => $perms
        ];

        Database::insert('project_invites', [
            'id_project' => $project_id,
            'id_from_user' => $from_user_id,
            'id_to_user' => $to_user_id,
            'status' => self::STATUS_PENDING,
            'permissions' => json_encode($inviteData),
            'created_at' => date('Y-m-d H:i:s')
        ]);

        return ['success' => true, 'id' => Database::id()];
    }

    // ==================== ПРОВЕРКИ ====================

    /**
     * Есть ли pending-приглашение для пользователя в проект
     */
    public static function hasPending(int $project_id, int $to_user_id): bool {
        return Database::has('project_invites', [
            'id_project' => $project_id,
            'id_to_user' => $to_user_id,
            'status' => self::STATUS_PENDING
        ]);
    }

    /**
     * Получить количество pending-приглашений для пользователя
     */
    public static function getPendingCount(int $user_id): int {
        return Database::count('project_invites', [
            'id_to_user' => $user_id,
            'status' => self::STATUS_PENDING
        ]);
    }

    // ==================== ПОЛУЧЕНИЕ ПРИГЛАШЕНИЙ ====================

    /**
     * Получить все pending-приглашения для пользователя (входящие)
     */
    public static function getMyPending(int $user_id): array {
        $invites = Database::select('project_invites', [
            '[>]project' => ['id_project' => 'id'],
            '[>]accounts' => ['id_from_user' => 'id']
        ], [
            'project_invites.id',
            'project_invites.id_project',
            'project_invites.created_at',
            'project_invites.permissions',
            'project.name(project_name)',
            'accounts.name(from_user_name)',
            'accounts.username(from_user_username)',
            'accounts.avatar_url(from_user_avatar)'
        ], [
            'project_invites.id_to_user' => $user_id,
            'project_invites.status' => self::STATUS_PENDING,
            'ORDER' => ['project_invites.created_at' => 'DESC']
        ]);

        return array_map(function($invite) {
            $permData = $invite['permissions'] ? json_decode($invite['permissions'], true) : [];
            return [
                'id' => (int)$invite['id'],
                'project_id' => (int)$invite['id_project'],
                'project_name' => $invite['project_name'],
                'from_user' => [
                    'name' => $invite['from_user_name'],
                    'username' => $invite['from_user_username'],
                    'avatar_url' => $invite['from_user_avatar']
                ],
                'is_admin' => $permData['is_admin'] ?? false,
                'created_at' => $invite['created_at']
            ];
        }, $invites);
    }

    /**
     * Получить pending-приглашения для проекта (для админа)
     */
    public static function getProjectPending(int $project_id): array {
        $invites = Database::select('project_invites', [
            '[>]accounts' => ['id_to_user' => 'id']
        ], [
            'project_invites.id',
            'project_invites.id_to_user',
            'project_invites.created_at',
            'project_invites.permissions',
            'accounts.name',
            'accounts.username',
            'accounts.avatar_url'
        ], [
            'project_invites.id_project' => $project_id,
            'project_invites.status' => self::STATUS_PENDING,
            'ORDER' => ['project_invites.created_at' => 'DESC']
        ]);

        return array_map(function($invite) {
            $permData = $invite['permissions'] ? json_decode($invite['permissions'], true) : [];
            return [
                'id' => (int)$invite['id'],
                'id_user' => (int)$invite['id_to_user'],
                'name' => $invite['name'],
                'username' => $invite['username'],
                'avatar_url' => $invite['avatar_url'],
                'is_admin' => $permData['is_admin'] ?? false,
                'created_at' => $invite['created_at'],
                'status' => 'pending'
            ];
        }, $invites);
    }

    // ==================== ОТВЕТ НА ПРИГЛАШЕНИЕ ====================

    /**
     * Принять приглашение
     */
    public static function accept(int $invite_id, int $user_id): array {
        $invite = Database::get('project_invites', '*', [
            'id' => $invite_id,
            'id_to_user' => $user_id,
            'status' => self::STATUS_PENDING
        ]);

        if (!$invite) {
            return ['success' => false, 'errors' => ['invite' => 'Приглашение не найдено или уже обработано']];
        }

        $project_id = (int)$invite['id_project'];
        $permData = $invite['permissions'] ? json_decode($invite['permissions'], true) : [];
        $is_admin = $permData['is_admin'] ?? false;
        $permissions = $permData['permissions'] ?? ProjectAccess::DEFAULT_PERMISSIONS;

        // Добавляем в project_members
        Database::insert('project_members', [
            'id_project' => $project_id,
            'id_user' => $user_id,
            'is_admin' => $is_admin ? 1 : 0,
            'permissions' => json_encode($permissions),
            'created_at' => date('Y-m-d H:i:s')
        ]);

        // Обновляем статус приглашения
        Database::update('project_invites', [
            'status' => self::STATUS_ACCEPTED,
            'responded_at' => date('Y-m-d H:i:s')
        ], ['id' => $invite_id]);

        return ['success' => true, 'project_id' => $project_id];
    }

    /**
     * Отклонить приглашение
     */
    public static function decline(int $invite_id, int $user_id): array {
        $invite = Database::get('project_invites', ['id'], [
            'id' => $invite_id,
            'id_to_user' => $user_id,
            'status' => self::STATUS_PENDING
        ]);

        if (!$invite) {
            return ['success' => false, 'errors' => ['invite' => 'Приглашение не найдено или уже обработано']];
        }

        Database::update('project_invites', [
            'status' => self::STATUS_DECLINED,
            'responded_at' => date('Y-m-d H:i:s')
        ], ['id' => $invite_id]);

        return ['success' => true];
    }

    /**
     * Отменить приглашение (для админа)
     */
    public static function cancel(int $invite_id, int $project_id): array {
        $invite = Database::get('project_invites', ['id'], [
            'id' => $invite_id,
            'id_project' => $project_id,
            'status' => self::STATUS_PENDING
        ]);

        if (!$invite) {
            return ['success' => false, 'errors' => ['invite' => 'Приглашение не найдено']];
        }

        Database::delete('project_invites', ['id' => $invite_id]);

        return ['success' => true];
    }
}

?>
