<?php

namespace Modules\MembershipApplication\Repositories;

use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Modules\MembershipApplication\Entities\MembershipApplication;
use Modules\MembershipApplication\Repositories\Contracts\MembershipApplicationRepositoryInterface;

class MembershipApplicationRepository implements MembershipApplicationRepositoryInterface
{
    public function create(array $data): MembershipApplication
    {
        return MembershipApplication::create($data);
    }

    public function findById(string $id): ?MembershipApplication
    {
        return MembershipApplication::find($id);
    }

    public function findByIdWithRelations(string $id): ?MembershipApplication
    {
        return MembershipApplication::with([
            'applicant',
            'heirs',
            'references.member:id,name,ic_number',
            'documents',
            'reviews.reviewer:id,name',
        ])->find($id);
    }

    public function getAllPaginated(
        int $perPage = 10,
        string $search = '',
        ?string $status = null,
        string $sortBy = 'submitted_at',
        string $sortOrder = 'desc'
    ): LengthAwarePaginator {
        $allowedSortColumns = [
            'application_number',
            'status',
            'submitted_at',
            'created_at',
        ];
        $sortBy = in_array($sortBy, $allowedSortColumns, true) ? $sortBy : 'submitted_at';
        $sortOrder = strtolower($sortOrder) === 'asc' ? 'asc' : 'desc';

        $query = MembershipApplication::query()
            ->with(['applicant:id,membership_application_id,name,email,ic_number'])
            ->orderBy($sortBy, $sortOrder);

        if ($status !== null && $status !== '') {
            $query->where('status', $status);
        }

        if ($search !== '') {
            $query->where(function ($q) use ($search) {
                $q->where('application_number', 'ILIKE', "%{$search}%")
                    ->orWhereHas('applicant', function ($applicantQuery) use ($search) {
                        $applicantQuery->where('name', 'ILIKE', "%{$search}%")
                            ->orWhere('email', 'ILIKE', "%{$search}%")
                            ->orWhere('ic_number', 'ILIKE', "%{$search}%");
                    });
            });
        }

        return $query->paginate($perPage);
    }
}
