<?php

declare(strict_types=1);

namespace App\Models;

use App\Business\Purchase\Enums\PurchaseRequestStatus;
use App\Models\Concerns\GeneratesDberpCode;
use App\Models\Concerns\HasDberpAuditTrail;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Validation\ValidationException;

class DberpPurchaseRequest extends Model
{
    use GeneratesDberpCode;
    use HasDberpAuditTrail;

    protected $table = 'dberp_purchase_requests';

    /**
     * @var list<string>
     */
    protected $fillable = [
        'code',
        'request_time',
        'source_type',
        'source_system',
        'source_id',
        'source_reference_no',
        'external_reference_id',
        'source_snapshot',
        'department_name',
        'applicant_employee_id',
        'suggested_supplier_id',
        'urgency_level',
        'expected_arrival_date',
        'request_reason',
        'status',
        'total_quantity',
        'converted_quantity',
        'remaining_quantity',
        'submitted_at',
        'last_converted_at',
        'closed_at',
        'voided_at',
        'remark',
    ];

    protected static function booted(): void
    {
        static::deleting(function (self $request): void {
            if ($request->status !== PurchaseRequestStatus::Draft->value) {
                throw ValidationException::withMessages([
                    'status' => __('dberp.errors.purchase_request_delete_only_draft'),
                ]);
            }
        });
    }

    protected function casts(): array
    {
        return [
            'request_time' => 'datetime',
            'source_id' => 'integer',
            'source_snapshot' => 'array',
            'applicant_employee_id' => 'integer',
            'suggested_supplier_id' => 'integer',
            'expected_arrival_date' => 'date',
            'total_quantity' => 'decimal:4',
            'converted_quantity' => 'decimal:4',
            'remaining_quantity' => 'decimal:4',
            'submitted_at' => 'datetime',
            'last_converted_at' => 'datetime',
            'closed_at' => 'datetime',
            'voided_at' => 'datetime',
        ];
    }

    public function getDberpNumberScope(): string
    {
        return 'purchase_request';
    }

    public function getDberpAuditActionPrefix(): string
    {
        return 'dberp.purchase_request';
    }

    /**
     * @return list<string>
     */
    public function getDberpAuditFields(): array
    {
        return $this->getFillable();
    }

    public function applicantEmployee(): BelongsTo
    {
        return $this->belongsTo(DberpEmployee::class, 'applicant_employee_id');
    }

    public function suggestedSupplier(): BelongsTo
    {
        return $this->belongsTo(DberpSupplier::class, 'suggested_supplier_id');
    }

    public function items(): HasMany
    {
        return $this->hasMany(DberpPurchaseRequestItem::class, 'request_id');
    }

    public function purchaseOrders(): HasMany
    {
        return $this->hasMany(DberpPurchaseOrder::class, 'purchase_request_id');
    }

    public function purchaseInquiries(): HasMany
    {
        return $this->hasMany(DberpPurchaseInquiry::class, 'purchase_request_id');
    }
}
