<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class Product extends Model
{
    use HasFactory, SoftDeletes;

    protected $fillable = [
        'product_code', 'sku', 'barcode', 'name_en', 'name_ar',
        'short_name_en', 'short_name_ar', 'category_id', 'subcategory_id', 'brand_id',
        'product_type', 'base_unit_id', 'purchase_unit_id', 'sales_unit_id',
        'pcs_per_carton', 'pack_size', 'weight', 'volume', 'packing_desc_en', 'packing_desc_ar',
        'vat_applicable', 'vat_rate', 'vat_category',
        'cost_price', 'avg_cost', 'last_purchase_cost', 'sale_price',
        'wholesale_price', 'min_sale_price', 'retail_price', 'price_mode',
        'track_stock', 'allow_negative_stock', 'min_stock', 'max_stock',
        'reorder_level', 'reorder_qty', 'track_batch', 'track_expiry', 'track_serial',
        'default_warehouse_id', 'rack_number', 'shelf_number',
        'image_path', 'notes', 'status', 'created_by',
    ];

    protected $casts = [
        'cost_price'         => 'decimal:4',
        'avg_cost'           => 'decimal:4',
        'last_purchase_cost' => 'decimal:4',
        'sale_price'         => 'decimal:2',
        'wholesale_price'    => 'decimal:2',
        'min_sale_price'     => 'decimal:2',
        'retail_price'       => 'decimal:2',
        'vat_rate'           => 'decimal:2',
        'min_stock'          => 'decimal:4',
        'max_stock'          => 'decimal:4',
        'reorder_level'      => 'decimal:4',
        'reorder_qty'        => 'decimal:4',
        'vat_applicable'     => 'boolean',
        'track_stock'        => 'boolean',
        'allow_negative_stock'=> 'boolean',
        'track_batch'        => 'boolean',
        'track_expiry'       => 'boolean',
        'track_serial'       => 'boolean',
    ];

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

    public function subcategory()
    {
        return $this->belongsTo(Category::class, 'subcategory_id');
    }

    public function brand()
    {
        return $this->belongsTo(Brand::class);
    }

    public function baseUnit()
    {
        return $this->belongsTo(Unit::class, 'base_unit_id');
    }

    public function purchaseUnit()
    {
        return $this->belongsTo(Unit::class, 'purchase_unit_id');
    }

    public function salesUnit()
    {
        return $this->belongsTo(Unit::class, 'sales_unit_id');
    }

    public function defaultWarehouse()
    {
        return $this->belongsTo(Warehouse::class, 'default_warehouse_id');
    }

    public function productUnits()
    {
        return $this->hasMany(ProductUnit::class);
    }

    public function barcodes()
    {
        return $this->hasMany(ProductBarcode::class);
    }

    public function primaryBarcode()
    {
        return $this->hasOne(ProductBarcode::class)->where('is_primary', true);
    }

    public function priceHistories()
    {
        return $this->hasMany(ProductPriceHistory::class);
    }

    public function customerPrices()
    {
        return $this->hasMany(CustomerProductPrice::class);
    }

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

    public function stockLedgers()
    {
        return $this->hasMany(StockLedger::class);
    }

    /**
     * Get total stock across all warehouses.
     */
    public function getTotalStockAttribute()
    {
        return $this->warehouseStocks()->sum('qty');
    }

    /**
     * Get stock value = total qty * avg_cost.
     */
    public function getStockValueAttribute()
    {
        return $this->warehouseStocks()->selectRaw('SUM(qty * avg_cost) as total_value')->value('total_value') ?? 0;
    }

    /**
     * Check if this product is low stock.
     */
    public function getIsLowStockAttribute()
    {
        if (!$this->track_stock || $this->reorder_level <= 0) return false;
        return $this->total_stock <= $this->reorder_level;
    }

    /**
     * Stock status label.
     */
    public function getStockStatusAttribute()
    {
        $qty = $this->total_stock;
        if ($qty < 0) return 'negative';
        if ($qty == 0) return 'out_of_stock';
        if ($this->reorder_level > 0 && $qty <= $this->reorder_level) return 'low';
        return 'in_stock';
    }

    /**
     * Get conversion factor for a specific unit relative to base unit.
     */
    public function getConversionFactor(int $unitId): float
    {
        $pu = $this->productUnits()->where('unit_id', $unitId)->first();
        return $pu ? (float) $pu->conversion_factor : 1.0;
    }

    /**
     * Convert a quantity in given unit to base qty.
     */
    public function toBaseQty(float $qty, int $unitId): float
    {
        return $qty * $this->getConversionFactor($unitId);
    }
}
