<?php

namespace App\Models;

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

class ItemRequest extends Model
{
    use HasFactory;

    protected $table = 't_item_requests';

    protected $fillable = [
        'spb_number',
        'store_id',
        'stock_opname_id',
        'request_type',
        'request_date',
        'delivery_date',
        'shipment_schedule_id',
        'status',
        'notes',
        'cancelled_at',
        'cancelled_by',
        'cancellation_reason',
        'cancellation_status',
        'csv_generated_at',
        'csv_generated_by',
        'delete_flag',
        'created_by',
        'updated_by',
        'created_at',
        'updated_at',
    ];

    protected $casts = [
        'request_date' => 'date',
        'delivery_date' => 'date',
        'cancelled_at' => 'datetime',
        'csv_generated_at' => 'datetime',
    ];

    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 stockOpname()
    {
        return $this->belongsTo(StockOpname::class, 'stock_opname_id');
    }

    public function ShipmentDelivery()
    {
        return $this->belongsTo(ShipmentDelivery::class, 'shipment_schedule_id');
    }

    public function details()
    {
        return $this->hasMany(ItemRequestDetail::class, 'item_request_id');
    }

    public function cancellations()
    {
        return $this->hasMany(ItemRequestCancellation::class, 'item_request_id');
    }

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

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

    // Status constants
    const STATUS_DRAFT = 'Draft';
    const STATUS_SUBMITTED = 'Submitted';
    const STATUS_APPROVED = 'Approved';
    const STATUS_CANCELLED = 'Cancelled';
    const STATUS_CANCELLATION_REQUESTED = 'Cancellation_Requested';

    // Helper methods
    public function isDraft()
    {
        return $this->status === self::STATUS_DRAFT;
    }

    public function isSubmitted()
    {
        return $this->status === self::STATUS_SUBMITTED;
    }

    public function isApproved()
    {
        return $this->status === self::STATUS_APPROVED;
    }

    public function isCancelled()
    {
        return $this->status === self::STATUS_CANCELLED;
    }

    public function isCancellationRequested()
    {
        return $this->status === self::STATUS_CANCELLATION_REQUESTED;
    }

    public function canBeEdited()
    {
        return in_array($this->status, [self::STATUS_DRAFT]);
    }

    public function canBeCancelled()
    {
        return in_array($this->status, [self::STATUS_SUBMITTED, self::STATUS_APPROVED]);
    }

    // Business rule: Check if Regular SPB already exists for SO
    public static function hasRegularSPBForSO($stockOpnameId)
    {
        return static::where('stock_opname_id', $stockOpnameId)
            ->where('request_type', 'Regular')
            ->where('delete_flag', 0)
            ->whereNotIn('status', [self::STATUS_CANCELLED])
            ->exists();
    }

    // Business rule: Check if daily SO exists for store
    public static function hasDailySOForStore($storeId, $date)
    {
        return \App\Models\StockOpname::where('store_id', $storeId)
            ->whereDate('so_date', $date)
            ->where('delete_flag', 0)
            ->exists();
    }

    protected static function boot()
    {
        parent::boot();

        static::creating(function ($itemRequest) {
            // Generate SPB number using NumberingFormat if not provided
            if (empty($itemRequest->spb_number) && $itemRequest->store_id) {
                try {
                    $itemRequest->spb_number = NumberingFormat::generateNumber(
                        $itemRequest->store_id, 
                        'SPB'
                    );
                } catch (Exception $e) {
                    // Fallback to old method if NumberingFormat fails
                    $today = date('Ymd');
                    $prefix = $itemRequest->request_type == 'Regular' ? 'SPB' : 'SPBT';
                    
                    $lastNumber = static::selectRaw("spb_number")
                        ->where('delete_flag', '0')
                        ->where('spb_number', 'like', "{$prefix}{$today}%")
                        ->orderByRaw("CAST(SUBSTRING(spb_number FROM " . (strlen($prefix) + 9) . ") AS INTEGER) DESC")
                        ->value('spb_number');

                    $lastSeq = $lastNumber ? intval(substr($lastNumber, strlen($prefix) + 8)) : 0;
                    $newSeq = $lastSeq + 1;

                    $itemRequest->spb_number = $prefix . $today . str_pad($newSeq, 4, '0', STR_PAD_LEFT);
                }
            }
        });
    }
}