<?php

namespace App\Models\Traits;

use Illuminate\Database\Eloquent\Builder;

/**
 * Common Query Scopes Trait
 *
 * Provides reusable query scopes for filtering data across models.
 * Models using this trait gain access to common filtering methods.
 */
trait HasScopes
{
    /**
     * Filter by active status
     */
    public function scopeActive(Builder $query): Builder
    {
        $column = $this->getStatusColumn();
        return $query->where($column, 'active');
    }

    /**
     * Filter by inactive status
     */
    public function scopeInactive(Builder $query): Builder
    {
        $column = $this->getStatusColumn();
        return $query->where($column, 'inactive');
    }

    /**
     * Filter by pending status
     */
    public function scopePending(Builder $query): Builder
    {
        $column = $this->getStatusColumn();
        return $query->where($column, 'pending');
    }

    /**
     * Filter by approved status
     */
    public function scopeApproved(Builder $query): Builder
    {
        $column = $this->getStatusColumn();
        return $query->where($column, 'approved');
    }

    /**
     * Filter by rejected status
     */
    public function scopeRejected(Builder $query): Builder
    {
        $column = $this->getStatusColumn();
        return $query->where($column, 'rejected');
    }

    /**
     * Filter by date range on a specific column
     */
    public function scopeDateRange(Builder $query, string $from, string $to, ?string $column = null): Builder
    {
        $column = $column ?? $this->getDateColumn();
        return $query->whereBetween($column, [$from, $to]);
    }

    /**
     * Filter by single date
     */
    public function scopeOnDate(Builder $query, string $date, ?string $column = null): Builder
    {
        $column = $column ?? $this->getDateColumn();
        return $query->whereDate($column, $date);
    }

    /**
     * Filter by this month
     */
    public function scopeThisMonth(Builder $query, ?string $column = null): Builder
    {
        $column = $column ?? $this->getDateColumn();
        return $query->whereMonth($column, now()->month)
                     ->whereYear($column, now()->year);
    }

    /**
     * Filter by this year
     */
    public function scopeThisYear(Builder $query, ?string $column = null): Builder
    {
        $column = $column ?? $this->getDateColumn();
        return $query->whereYear($column, now()->year);
    }

    /**
     * Filter by last N days
     */
    public function scopeLastDays(Builder $query, int $days, ?string $column = null): Builder
    {
        $column = $column ?? $this->getDateColumn();
        return $query->where($column, '>=', now()->subDays($days));
    }

    /**
     * Order by latest (most recent first)
     */
    public function scopeLatestFirst(Builder $query, ?string $column = null): Builder
    {
        $column = $column ?? $this->getDateColumn();
        return $query->orderBy($column, 'desc');
    }

    /**
     * Order by oldest first
     */
    public function scopeOldestFirst(Builder $query, ?string $column = null): Builder
    {
        $column = $column ?? $this->getDateColumn();
        return $query->orderBy($column, 'asc');
    }

    /**
     * Search in multiple columns
     */
    public function scopeSearch(Builder $query, string $term, array $columns): Builder
    {
        return $query->where(function ($q) use ($term, $columns) {
            foreach ($columns as $column) {
                $q->orWhere($column, 'LIKE', "%{$term}%");
            }
        });
    }

    /**
     * Filter by company/customer ID
     */
    public function scopeForCompany(Builder $query, int $companyId): Builder
    {
        $column = $this->getCompanyColumn();
        return $query->where($column, $companyId);
    }

    /**
     * Get status column name (override in model if different)
     */
    protected function getStatusColumn(): string
    {
        return property_exists($this, 'statusColumn') ? $this->statusColumn : 'status';
    }

    /**
     * Get date column name (override in model if different)
     */
    protected function getDateColumn(): string
    {
        return property_exists($this, 'dateColumn') ? $this->dateColumn : 'created_at';
    }

    /**
     * Get company column name (override in model if different)
     */
    protected function getCompanyColumn(): string
    {
        return property_exists($this, 'companyColumn') ? $this->companyColumn : 'company_id';
    }
}
