<?php

namespace App\Models;

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

class CurrentStock extends Model
{
    use HasFactory;

    protected $table = 't_current_stocks';

    protected $fillable = [
        'store_id',
        'raw_material_id',
        'qty_utuh',
        'qty_pakai',
        'qty_total_converted',
        'uom_utuh',
        'uom_pakai',
        'conversion_factor',
        'last_updated_date',
        'last_movement_time',
        'last_updated_by',
        'delete_flag'
    ];

    protected $casts = [
        'qty_utuh' => 'decimal:2',
        'qty_pakai' => 'decimal:2',
        'qty_total_converted' => 'decimal:2',
        'conversion_factor' => 'decimal:2',
        'last_updated_date' => 'date',
        'last_movement_time' => 'datetime',
        'delete_flag' => 'boolean'
    ];

    // Relationships
    public function store()
    {
        return $this->belongsTo(Store::class, 'store_id');
    }

    public function rawMaterial()
    {
        return $this->belongsTo(RawMaterial::class, 'raw_material_id');
    }

    public function lastUpdatedBy()
    {
        return $this->belongsTo(User::class, 'last_updated_by');
    }

    // Get current stock for a specific item
    public static function getCurrentStock($storeId, $rawMaterialId)
    {
        return static::where('store_id', $storeId)
            ->where('raw_material_id', $rawMaterialId)
            ->where('delete_flag', 0)
            ->first();
    }

    // Get all current stocks for a store
    public static function getStoreStocks($storeId, $activeOnly = true)
    {
        $query = static::where('store_id', $storeId)
            ->where('delete_flag', 0)
            ->with(['rawMaterial']);

        if ($activeOnly) {
            $query->whereHas('rawMaterial', function($q) {
                $q->where('delete_flag', 0);
            });
        }

        return $query->orderBy('raw_material_id')->get();
    }

    // Update stock (used by StockMovement)
    public static function updateStock($storeId, $rawMaterialId, $newQtyTotal, $userId = null)
    {
        $userId = $userId ?? auth()->id() ?? 1;
        
        // Get raw material info for conversion
        $rawMaterial = RawMaterial::find($rawMaterialId);
        if (!$rawMaterial) return false;

        $conversionFactor = $rawMaterial->conversion_factor ?? 1;
        
        // Calculate qty_utuh and qty_pakai from total
        // This is a simplified calculation - you may need to adjust based on business rules
        $qtyUtuh = floor($newQtyTotal / $conversionFactor);
        $qtyPakai = $newQtyTotal - ($qtyUtuh * $conversionFactor);

        return static::updateOrCreate(
            [
                'store_id' => $storeId,
                'raw_material_id' => $rawMaterialId
            ],
            [
                'qty_utuh' => $qtyUtuh,
                'qty_pakai' => $qtyPakai,
                'qty_total_converted' => $newQtyTotal,
                'uom_utuh' => $rawMaterial->uom ?? 'PCS',
                'uom_pakai' => $rawMaterial->uom_pakai ?? 'GR',
                'conversion_factor' => $conversionFactor,
                'last_updated_date' => Carbon::now()->toDateString(),
                'last_movement_time' => Carbon::now(),
                'last_updated_by' => $userId,
                'delete_flag' => false
            ]
        );
    }

    // Initialize stock from Stock Opname
    public static function initializeFromStockOpname($stockOpnameId)
    {
        $stockOpname = StockOpname::with('details.rawMaterial')->find($stockOpnameId);
        if (!$stockOpname) return false;

        foreach ($stockOpname->details as $detail) {
            $rawMaterial = $detail->rawMaterial;
            $conversionFactor = $rawMaterial->conversion_factor ?? 1;
            
            // Calculate total converted quantity
            $qtyTotalConverted = ($detail->qty_utuh * $conversionFactor) + $detail->qty_pakai;

            static::updateOrCreate(
                [
                    'store_id' => $stockOpname->store_id,
                    'raw_material_id' => $detail->raw_material_id
                ],
                [
                    'qty_utuh' => $detail->qty_utuh,
                    'qty_pakai' => $detail->qty_pakai,
                    'qty_total_converted' => $qtyTotalConverted,
                    'uom_utuh' => $rawMaterial->uom ?? 'PCS',
                    'uom_pakai' => $rawMaterial->uom_pakai ?? 'GR',
                    'conversion_factor' => $conversionFactor,
                    'last_updated_date' => $stockOpname->so_date,
                    'last_movement_time' => $stockOpname->updated_at ?? $stockOpname->created_at,
                    'last_updated_by' => $stockOpname->updated_by ?? $stockOpname->created_by,
                    'delete_flag' => false
                ]
            );

            // Record stock movement
            StockMovement::recordMovement(
                $stockOpname->store_id,
                $detail->raw_material_id,
                'ADJUSTMENT',
                $qtyTotalConverted,
                $rawMaterial->uom_pakai ?? 'GR',
                'SO',
                $stockOpnameId,
                'Stock adjustment from Stock Opname: ' . $stockOpname->so_number,
                $stockOpname->updated_by ?? $stockOpname->created_by
            );
        }

        return true;
    }

    // Get stock status (Normal, Low, Critical, Overstock)
    public function getStockStatus()
    {
        $storeRawMaterial = StoreRawMaterial::where('store_id', $this->store_id)
            ->where('raw_material_id', $this->raw_material_id)
            ->first();

        if (!$storeRawMaterial) return 'Unknown';

        $currentQty = $this->qty_total_converted;
        $minStock = $storeRawMaterial->min_stock ?? 0;
        $maxStock = $storeRawMaterial->max_stock ?? 999999;
        $reorderPoint = $storeRawMaterial->reorder_point ?? 0;

        if ($currentQty <= 0) return 'Out of Stock';
        if ($currentQty <= $reorderPoint) return 'Critical';
        if ($currentQty <= $minStock) return 'Low';
        if ($currentQty >= $maxStock) return 'Overstock';
        
        return 'Normal';
    }

    // Get stock status color for UI
    public function getStatusColor()
    {
        switch ($this->getStockStatus()) {
            case 'Out of Stock': return 'danger';
            case 'Critical': return 'danger';
            case 'Low': return 'warning';
            case 'Overstock': return 'info';
            case 'Normal': return 'success';
            default: return 'secondary';
        }
    }
}