<?php

namespace App\Repositories\V1\Projects;

use App\Enums\Project\ProjectStatusEnum;
use App\Models\Project;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Collection;
use Infrastructure\Services\Utilities\Utility;

class MysqlProjectRepository implements ProjectRepositoryInterface
{

    public function store(array $data): Project
    {
        return Project::query()->create($data);
    }

    public function first(int $id): ?Project
    {
        return Project::query()
            ->where('id', '=', $id)
            ->first();
    }

    public function update(int $id, array $data): bool
    {
        return Project::where('id', '=', $id)
            ->update($data);
    }
    public function findById(int $id): ?Project
    {
        return Project::find($id);
    }
    
    public function getProfessionalProjects(Utility $utility, int $userId): Collection
    {
        return $utility->applyOnBuilder(Project::query())
            ->with('firstImage')
            ->withCount(['images', 'projectLikes']) 
            ->where('user_id', '=', $userId)
            ->get();
    }

    public function getProjectWithDetails(int $id, array $conditions = []): ?Project
    {
        return Project::query()
            ->with(['images', 'projectType', 'city', 'state', 'user.details.category'])
            ->withCount('projectLikes')
            ->where('id', '=', $id)
            ->where($conditions)
            ->firstOrFail();
    }

    public function getProjects(Utility $utility): LengthAwarePaginator
    {
        return $utility->applyOnBuilder($this->getProjectsBuilder())
            ->paginate(config('general.pagination_limit'));
    }

    public function getSimilarProjectByCategoryId(int $projectId, int $categoryId, int $limit): LengthAwarePaginator
    {
        return $this->getProjectsBuilder()
            ->where('category_id', '=', $categoryId)
            ->where('id', '!=', $projectId)
            ->paginate($limit);
    }

    private function getProjectsBuilder(): Builder
    {
        return Project::query()
            ->with('firstImage', 'user.details')
            ->withCount(['images', 'projectLikes']) 
            ->where('status', '=', ProjectStatusEnum::PUBLISHED->value)
            ->orderByRaw('ISNULL(sort), sort ASC');
    }

    public function findOrFail(int $id, array $conditions = []): Project
    {
        return Project::query()->where($conditions)->findOrFail($id);
    }
}
