<?php

namespace App\Repositories\Admin;

use Exception;
use Throwable;
use App\Models\Post;
use App\Enums\DeletedType;
use App\Enums\NotificationType;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use App\Repositories\General\NotificationRepository;

class PostRepository
{
    protected $notificationRepository;

    public function __construct(NotificationRepository $notificationRepository)
    {
        $this->notificationRepository = $notificationRepository;
    }

    public function getAll()
    {
        $posts = Post::with([
            'images',
            'user.image',
            'group.images',
        ])
            // TODO: Add or not restore
            // ->withTrashed()
            ->filter(request([
                'search',
            ]))
            ->latest('updated_at')
            ->paginate(12)
            ->withQueryString();

        return compact('posts');
    }

    public function show($id)
    {
        $post = Post::with([
            'images',
            'user.image',
            'group.images',
        ])
            ->withTrashed()
            ->find($id);

        return compact('post');
    }

    public function destroy(Post $post)
    {
        try {
            DB::beginTransaction();

            $this->notificationRepository->add(
                userId: $post->user_id,
                content: 'Admin decided to remove your post.',
                imageUrl: auth()->user()->image?->url,
                type: NotificationType::ADMIN->value,
                redirectLink: '',
            );

            $post->update([
                'deleted_type' => DeletedType::ADMIN,
            ]);
            $post->delete();

            DB::commit();
        } catch (Throwable $e) {
            DB::rollBack();

            Log::error(__CLASS__ . '::' . __FUNCTION__ . '[line: ' . __LINE__ . ']Message: ' . $e->getMessage());

            throw new Exception('Post deleted failed.');
        }
    }

    public function restore($id)
    {
        try {
            DB::beginTransaction();

            $post = Post::onlyTrashed()->findOrFail($id);

            $post->update([
                'deleted_type' => null,
            ]);
            $post->restore();

            DB::commit();
        } catch (Throwable $e) {
            DB::rollBack();

            Log::error(__CLASS__ . '::' . __FUNCTION__ . '[line: ' . __LINE__ . ']Message: ' . $e->getMessage());

            throw new Exception('Post restored failed.');
        }
    }
}
