<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;

class Product extends Model
{
    use HasFactory, SoftDeletes;

    protected $fillable = [
        'sku', 'name', 'category_id', 'unit',
        'current_stock', 'min_stock',
        'buy_price', 'sell_price',
        'barcode', 'image_path', 'description', 'is_active',
    ];

    protected $appends = ['image_url', 'category_name'];

    /**
     * Get the absolute URL of the product image, built from APP_URL so it
     * still resolves correctly when the frontend is served from a different
     * domain than the backend (e.g. gembira.eisvibe.com vs api.gembira.eisvibe.com).
     * Built from config directly (not the Storage facade) so it never touches
     * the filesystem adapter — just string concatenation, same as
     * config/filesystems.php's 'public' disk URL resolution.
     */
    public function getImageUrlAttribute(): ?string
    {
        if (!$this->image_path) {
            return null;
        }

        return rtrim(config('app.url'), '/') . '/storage/' . ltrim($this->image_path, '/');
    }

    /**
     * Get the category name from the related category.
     */
    public function getCategoryNameAttribute(): ?string
    {
        return $this->category?->name;
    }

    protected function casts(): array
    {
        return [
            'current_stock' => 'integer',
            'min_stock'     => 'integer',
            'buy_price'     => 'integer',
            'sell_price'    => 'integer',
            'is_active'     => 'boolean',
        ];
    }

    // Relationships
    public function category(): BelongsTo
    {
        return $this->belongsTo(Category::class);
    }

    public function saleItems()
    {
        return $this->hasMany(SaleItem::class);
    }

    public function purchaseItems()
    {
        return $this->hasMany(PurchaseItem::class);
    }

    public function stockMovements()
    {
        return $this->hasMany(StockMovement::class);
    }

    public function opnameItems()
    {
        return $this->hasMany(OpnameItem::class);
    }

    public function warehouseStock(): HasMany
    {
        return $this->hasMany(WarehouseStock::class);
    }

    public function channelPrices(): HasMany
    {
        return $this->hasMany(ProductChannelPrice::class);
    }

    public function warehouses(): BelongsToMany
    {
        return $this->belongsToMany(Warehouse::class, 'warehouse_stock')
                    ->withPivot('current_stock', 'min_stock', 'sell_price')
                    ->withTimestamps();
    }

    /**
     * Get stock level for a specific warehouse.
     */
    public function stockInWarehouse(int $warehouseId): int
    {
        return $this->warehouseStock()
            ->where('warehouse_id', $warehouseId)
            ->value('current_stock') ?? 0;
    }

    /**
     * Get sell price for a specific warehouse (fallback to product default).
     */
    public function sellPriceInWarehouse(int $warehouseId): int
    {
        $warehousePrice = $this->warehouseStock()
            ->where('warehouse_id', $warehouseId)
            ->value('sell_price');

        return $warehousePrice ?? $this->sell_price;
    }

    // Scopes
    public function scopeActive($query)
    {
        return $query->where('is_active', true);
    }

    public function scopeLowStock($query)
    {
        return $query->whereColumn('current_stock', '<=', 'min_stock');
    }

    public function scopeSearch($query, ?string $term)
    {
        if (!$term) {
            return $query;
        }

        return $query->where(function ($q) use ($term) {
            $q->where('name', 'like', "%{$term}%")
              ->orWhere('sku', 'like', "%{$term}%")
              ->orWhere('barcode', 'like', "%{$term}%")
              ->orWhereHas('category', fn($cq) => $cq->where('name', 'like', "%{$term}%"));
        });
    }
}
