<?php

namespace App\Models;

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

class StoreRawMaterial extends Model
{
    use HasFactory;

    protected $table = 'm_store_raw_materials';

    protected $fillable = [
        'store_id',
        'raw_material_id',
        'tipe_dokumen',
        'lsm_flag',
        'spb_flag',
        'inv_matrix_flag',
        'period_id',
        'is_active',
        'min_stock',
        'max_stock',
        'reorder_point',
        'notes',
        'created_by',
        'updated_by',
        'created_at',
        'updated_at',
    ];

    protected $casts = [
        'lsm_flag' => 'boolean',
        'spb_flag' => 'boolean',
        'inv_matrix_flag' => 'boolean',
        'is_active' => 'boolean',
        'min_stock' => 'decimal:2',
        'max_stock' => 'decimal:2',
        'reorder_point' => 'decimal:2',
    ];

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

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

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

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

    // Relationship with period
    public function period()
    {
        return $this->belongsTo(Period::class, 'period_id');
    }

    // Scope untuk filter active mappings
    public function scopeActive($query)
    {
        return $query->where('is_active', true);
    }

    // Scope untuk filter by store
    public function scopeForStore($query, $storeId)
    {
        return $query->where('store_id', $storeId);
    }

    // Get raw materials for specific store (LSM enabled only)
    public static function getRawMaterialsForStore($storeId, $lsmOnly = true)
    {
        $query = static::active()
            ->forStore($storeId)
            ->with('rawMaterial.activeConversion') // Load activeConversion relationship
            ->whereHas('rawMaterial', function($q) {
                // Filter only non-deleted raw materials
                $q->where('delete_flag', false);
            });
            
        // Filter by LSM flag from mapping table (not from raw_materials)
        if ($lsmOnly) {
            $query->where('lsm_flag', true);
        }
            
        return $query->get()->pluck('rawMaterial');
    }

    // Get raw materials for SPB (SPB enabled only)
    public static function getRawMaterialsForSPB($storeId)
    {
        return static::active()
            ->forStore($storeId)
            ->with('rawMaterial.activeConversion') // Load activeConversion relationship
            ->where('spb_flag', true) // Read from mapping table
            ->whereHas('rawMaterial', function($q) {
                $q->where('delete_flag', false);
            })
            ->get()
            ->pluck('rawMaterial');
    }

    // Get raw materials by document type
    public static function getRawMaterialsByDocType($storeId, $docType = 'DO')
    {
        return static::active()
            ->forStore($storeId)
            ->with('rawMaterial')
            ->where('tipe_dokumen', $docType) // Now read from mapping table
            ->whereHas('rawMaterial', function($q) {
                $q->where('delete_flag', false);
            })
            ->get()
            ->pluck('rawMaterial');
    }

    // Get raw materials by order period (using period relationship from mapping)
    public static function getRawMaterialsByPeriod($storeId, $periodCode = 'HARIAN')
    {
        return static::active()
            ->forStore($storeId)
            ->with(['rawMaterial', 'period'])
            ->whereHas('rawMaterial', function($q) {
                $q->where('delete_flag', false);
            })
            ->whereHas('period', function($q) use ($periodCode) {
                $q->where('code', $periodCode);
            })
            ->get()
            ->pluck('rawMaterial');
    }

    // Get raw materials by period ID (from mapping table)
    public static function getRawMaterialsByPeriodId($storeId, $periodId)
    {
        return static::active()
            ->forStore($storeId)
            ->with(['rawMaterial', 'period'])
            ->where('period_id', $periodId) // Read from mapping table
            ->whereHas('rawMaterial', function($q) {
                $q->where('delete_flag', false);
            })
            ->get()
            ->pluck('rawMaterial');
    }

    // Check if this mapping uses DO (Delivery Order) process
    public function isDeliveryOrder()
    {
        return $this->tipe_dokumen === 'DO';
    }

    // Check if this mapping uses PO (Purchase Order) process
    public function isPurchaseOrder()
    {
        return $this->tipe_dokumen === 'PO';
    }

    // Check if this mapping uses PR (Purchase Request) process
    public function isPurchaseRequest()
    {
        return $this->tipe_dokumen === 'PR';
    }

    // Get document type display name
    public function getDocumentTypeDisplayAttribute()
    {
        switch ($this->tipe_dokumen) {
            case 'DO':
                return 'Delivery Order';
            case 'PO':
                return 'Purchase Order';
            case 'PR':
                return 'Purchase Request';
            default:
                return $this->tipe_dokumen;
        }
    }

    // Check if this mapping has inventory matrix adjustments
    public function hasInventoryMatrix()
    {
        return $this->inv_matrix_flag == true;
    }

    // Check if this material appears in LSM (Stock Opname) for this store
    public function isLsmEnabled()
    {
        return $this->lsm_flag == true;
    }

    // Check if this material can be requested in SPB for this store
    public function isSpbEnabled()
    {
        return $this->spb_flag == true;
    }

    // Get tipe_dokumen for specific store and raw material
    public static function getTipeDocumen($storeId, $rawMaterialId)
    {
        $mapping = static::active()
            ->where('store_id', $storeId)
            ->where('raw_material_id', $rawMaterialId)
            ->first();
        
        return $mapping ? $mapping->tipe_dokumen : 'DO'; // Default to DO
    }

    // Get mapping for specific store and raw material
    public static function getMapping($storeId, $rawMaterialId)
    {
        return static::active()
            ->where('store_id', $storeId)
            ->where('raw_material_id', $rawMaterialId)
            ->first();
    }
}