<?php

namespace LaraBB\Forum\Actions\Admin;

use Illuminate\Database\Connection;
use JetBrains\PhpStorm\ArrayShape;
use LaraBB\Forum\Tasks\Forum\StoreTask as StoreForumTask;
use LaraBB\Forum\Tasks\Permission\StoreTask as StoreForumPermissionTask;
use LaraBB\Forum\Tasks\User\StoreTask as StoreForumUserTask;
use LaraBB\Forum\Models\Forum;
use LaraBB\Forum\UI\Web\Requests\Store;
use Ramsey\Uuid\Uuid;
use Throwable;

/**
 * Class StoreAction
 * @package LaraBB\Forum\Actions\Admin
 */
class StoreAction
{
    /**
     * StoreAction constructor.
     * @param StoreForumTask $storeForumTask
     * @param StoreForumPermissionTask $storeForumPermissionTask
     * @param StoreForumUserTask $storeForumUserTask
     * @param Connection $connection
     */
    public function __construct(
        private readonly StoreForumTask $storeForumTask,
        private readonly StoreForumPermissionTask $storeForumPermissionTask,
        private readonly StoreForumUserTask $storeForumUserTask,
        private readonly Connection $connection
    ) {

    }

    /**
     * @param Store $request
     * @return bool
     */
    public function run(Store $request): bool
    {
        try {
            $this->connection->transaction(function() use($request) {
                $forum = $this->storeForumTask->run($this->prepareForumData($request));
                $this->storeForumPermissionTask->run($forum, $this->prepareForumPermissionData($forum, $request));
                $this->storeForumUserTask->run($forum, $this->prepareForumUsersData($request));
            });
        } catch(Throwable $t) {
            return false;
        }

        return true;
    }

    /**
     * @param Store $request
     * @return array
     */
    #[ArrayShape([
        'category_uuid' => "array|null|string",
        'created_uuid'  => "mixed",
        'updated_uuid'  => "mixed",
        'title'         => "array|null|string",
        'description'   => "array|null|string",
        'slug'          => "array|null|string"
    ])]
    private function prepareForumData(Store $request): array
    {
        return [
            'category_uuid' => $request->post('category'),
            'created_uuid'  => $request->user()->uuid,
            'updated_uuid'  => $request->user()->uuid,
            'title'         => $request->post('title'),
            'description'   => $request->post('description'),
            'slug'          => $request->post('slug'),
        ];
    }

    /**
     * @param Forum $forum
     * @param Store $request
     * @return array|false
     */
    private function prepareForumPermissionData(Forum $forum, Store $request): bool|array
    {
        if (!$request->has('permissions')) {
            return [];
        }

        $permissions = [];

        foreach ($request->post('permissions') as $groupUuid => $groupPermissions) {
            $permissions[] = [
                'created_uuid'   => $request->user()->uuid,
                'updated_uuid'   => $request->user()->uuid,
                'group_uuid'     => $groupUuid,
                'forum_uuid'     => $forum->uuid,
                'show_forum'     => $groupPermissions['show_forum'] ?? 0,
                'show_threads'   => $groupPermissions['show_threads'] ?? 0,
                'show_posts'     => $groupPermissions['show_posts'] ?? 0,
                'create_threads' => $groupPermissions['create_threads'] ?? 0,
                'create_posts'   => $groupPermissions['create_posts'] ?? 0,
                'edit_threads'   => $groupPermissions['edit_threads'] ?? 0,
                'edit_posts'     => $groupPermissions['edit_posts'] ?? 0,
                'delete_threads' => $groupPermissions['delete_threads'] ?? 0,
                'delete_posts'   => $groupPermissions['delete_posts'] ?? 0
            ];
        }

        return $permissions;
    }

    private function prepareForumUsersData(Store $request): array
    {
        $return = [];

        foreach($request->post('users') as $user) {
            $return[$user] = [
                'uuid'         => Uuid::uuid4(),
                'created_at'   => now(),
                'created_uuid' => $request->user()->uuid,
                'updated_at'   => now(),
                'updated_uuid' => $request->user()->uuid
            ];
        }

        return $return;
    }
}
