<?php

namespace App\Repositories;

use App\Models\RawMaterial;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Collection;

class RawMaterialRepository extends BaseRepository
{
    protected function resolveModel(): Model
    {
        return new RawMaterial();
    }

    /**
     * Get all materials with product type
     */
    public function getWithType(): Collection
    {
        return $this->with(['productType', 'files'])
            ->orderBy('name', 'asc')
            ->all();
    }

    /**
     * Get materials by product type
     */
    public function getByType(int $typeId): Collection
    {
        return $this->where('product_type_id', $typeId)
            ->orderBy('name', 'asc')
            ->all();
    }

    /**
     * Get active materials
     */
    public function getActive(): Collection
    {
        return $this->where('status', RawMaterial::STATUS_ACTIVE)
            ->orderBy('name', 'asc')
            ->all();
    }

    /**
     * Search materials by name, code, or grade
     */
    public function search(string $term): Collection
    {
        $query = $this->getQuery();
        $query->where(function ($q) use ($term) {
            $q->where('name', 'like', "%{$term}%")
                ->orWhere('code', 'like', "%{$term}%")
                ->orWhere('rm_grade', 'like', "%{$term}%");
        });
        $result = $query->get();
        $this->resetQuery();
        return $result;
    }

    /**
     * Get low stock materials
     */
    public function getLowStock(int $threshold = 10): Collection
    {
        $query = $this->getQuery();
        $query->where(function ($q) use ($threshold) {
            $q->whereColumn('quantity', '<=', 'min_stock')
                ->orWhere('quantity', '<=', $threshold);
        })->where('status', RawMaterial::STATUS_ACTIVE)
            ->orderBy('quantity', 'asc');
        $result = $query->get();
        $this->resetQuery();
        return $result;
    }

    /**
     * Get materials with files
     */
    public function getWithFiles(): Collection
    {
        return $this->with(['files'])
            ->orderBy('name', 'asc')
            ->all();
    }

    /**
     * Get material by code
     */
    public function findByCode(string $code): ?RawMaterial
    {
        $query = $this->getQuery();
        $result = $query->where('code', $code)->first();
        $this->resetQuery();
        return $result;
    }
}
