<?php

namespace App\Services;

use App\Repositories\Contracts\RepositoryInterface;
use App\Services\Contracts\ServiceInterface;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

abstract class BaseService implements ServiceInterface
{
    protected RepositoryInterface $repository;

    public function __construct(RepositoryInterface $repository)
    {
        $this->repository = $repository;
    }

    /**
     * Get all records
     */
    public function getAll(): Collection
    {
        return $this->repository->all();
    }

    /**
     * Get all records with eager loading
     */
    public function getAllWith(array $relations): Collection
    {
        return $this->repository->with($relations)->all();
    }

    /**
     * Find a record by ID
     */
    public function findById(int $id): ?Model
    {
        return $this->repository->find($id);
    }

    /**
     * Find a record by ID or fail
     */
    public function findByIdOrFail(int $id): Model
    {
        return $this->repository->findOrFail($id);
    }

    /**
     * Find a record by ID with relations
     */
    public function findByIdWith(int $id, array $relations): ?Model
    {
        return $this->repository->with($relations)->find($id);
    }

    /**
     * Create a new record
     */
    public function create(array $data): Model
    {
        return DB::transaction(function () use ($data) {
            return $this->repository->create($data);
        });
    }

    /**
     * Update a record by ID
     */
    public function update(int $id, array $data): Model
    {
        return DB::transaction(function () use ($id, $data) {
            return $this->repository->update($id, $data);
        });
    }

    /**
     * Delete a record by ID
     */
    public function delete(int $id): bool
    {
        return DB::transaction(function () use ($id) {
            return $this->repository->delete($id);
        });
    }

    /**
     * Paginate records
     */
    public function paginate(int $perPage = 15): LengthAwarePaginator
    {
        return $this->repository->paginate($perPage);
    }

    /**
     * Get records ordered by a field
     */
    public function getOrdered(string $column, string $direction = 'asc'): Collection
    {
        return $this->repository->orderBy($column, $direction)->all();
    }

    /**
     * Get count of records
     */
    public function count(): int
    {
        return $this->repository->count();
    }

    /**
     * Check if record exists
     */
    public function exists(int $id): bool
    {
        return $this->repository->exists($id);
    }

    /**
     * Get for DataTables (returns query builder)
     */
    public function getForDataTable()
    {
        return $this->repository->getForDataTable();
    }

    /**
     * Log an action
     */
    protected function logAction(string $action, array $context = []): void
    {
        Log::info("{$action}", array_merge([
            'service' => static::class,
            'user_id' => auth()->id(),
        ], $context));
    }
}
