<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;

class Product extends Model
{
    use HasFactory;

    protected $fillable = [
        'name', 'sku', 'barcode', 'description', 'category_id', 
        'purchase_price', 'selling_price', 'stock', 'min_stock', 
        'image', 'is_active', 'tax_id'
    ];

    protected $casts = [
        'is_active' => 'boolean',
        'purchase_price' => 'decimal:2',
        'selling_price' => 'decimal:2',
    ];

    // Get current average cost price
    public function getAverageCostAttribute()
    {
        $totalCost = $this->batches()->sum(DB::raw('remaining_quantity * purchase_price'));
        $totalQuantity = $this->batches()->sum('remaining_quantity');
        
        if ($totalQuantity > 0) {
            return $totalCost / $totalQuantity;
        }
        
        return $this->purchase_price;
    }
    
    // Get FIFO batches for selling
    public function getFifoBatches()
    {
        return $this->batches()
            ->where('remaining_quantity', '>', 0)
            ->orderBy('purchase_date', 'asc')
            ->orderBy('id', 'asc')
            ->get();
    }
    
    // Deduct stock using FIFO method
    public function deductStockFIFO($quantity)
    {
        $batches = $this->getFifoBatches();
        $remainingToDeduct = $quantity;
        $costDetails = [];
        
        foreach ($batches as $batch) {
            if ($remainingToDeduct <= 0) break;
            
            $deductFromBatch = min($batch->remaining_quantity, $remainingToDeduct);
            $batch->remaining_quantity -= $deductFromBatch;
            $batch->save();
            
            $costDetails[] = [
                'batch_id' => $batch->id,
                'quantity' => $deductFromBatch,
                'cost_price' => (float)$batch->purchase_price,
                'total_cost' => $deductFromBatch * $batch->purchase_price
            ];
            
            $remainingToDeduct -= $deductFromBatch;
        }
        
        // Update total stock
        $this->stock -= $quantity;
        $this->save();
        
        return $costDetails;
    }
    
    // Add stock with new batch
    public function addStockBatch($quantity, $purchasePrice, $purchaseId = null)
    {
        $batch = InventoryBatch::create([
            'product_id' => $this->id,
            'purchase_id' => $purchaseId,
            'batch_no' => 'BATCH-' . date('YmdHis') . '-' . rand(100, 999),
            'purchase_price' => $purchasePrice,
            'quantity' => $quantity,
            'remaining_quantity' => $quantity,
            'purchase_date' => now()
        ]);
        
        // Update total stock
        $this->stock += $quantity;
        $this->purchase_price = $this->getAverageCostAttribute(); // Update average cost
        $this->save();
        
        return $batch;
    }

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

    public function batches()
    {
        return $this->hasMany(InventoryBatch::class);
    }

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

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

    public function tax()
    {
        return $this->belongsTo(Tax::class);
    }

    public function reduceStock($quantity)
    {
        $this->decrement('stock', $quantity);
    }

    public function increaseStock($quantity)
    {
        $this->stock = $this->stock + $quantity;
        $this->save();
    }

    public function decreaseStock($quantity)
    {
        $this->stock = $this->stock - $quantity;
        $this->save();
    }
}