<?php

declare(strict_types=1);

namespace App\Models;

use App\Models\Concerns\HasDberpAuditTrail;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Support\Str;

class DberpPurchaseException extends Model
{
    use HasDberpAuditTrail;

    protected $table = 'dberp_purchase_exceptions';

    /** @var list<string> */
    protected $fillable = [
        'code',
        'purchase_order_id',
        'purchase_order_code',
        'purchase_order_item_id',
        'purchase_receipt_order_id',
        'purchase_receipt_code',
        'purchase_receipt_item_id',
        'supplier_id',
        'product_id',
        'exception_type',
        'status',
        'resolution_result',
        'arrival_quantity',
        'received_quantity',
        'rejected_quantity',
        'difference_quantity',
        'pending_quantity',
        'reason_detail',
        'handling_suggestion',
        'resolution_remark',
        'handled_by',
        'occurred_at',
        'handled_at',
        'closed_at',
        'context_snapshot',
        'sort_order',
    ];

    protected static function booted(): void
    {
        static::creating(function (self $exception): void {
            if (($exception->code ?? '') !== '') {
                return;
            }

            $exception->setAttribute('code', 'PEX'.strtoupper(Str::ulid()->toBase32()));
        });
    }

    protected function casts(): array
    {
        return [
            'purchase_order_id' => 'integer',
            'purchase_order_item_id' => 'integer',
            'purchase_receipt_order_id' => 'integer',
            'purchase_receipt_item_id' => 'integer',
            'supplier_id' => 'integer',
            'product_id' => 'integer',
            'arrival_quantity' => 'decimal:4',
            'received_quantity' => 'decimal:4',
            'rejected_quantity' => 'decimal:4',
            'difference_quantity' => 'decimal:4',
            'pending_quantity' => 'decimal:4',
            'handled_by' => 'integer',
            'occurred_at' => 'datetime',
            'handled_at' => 'datetime',
            'closed_at' => 'datetime',
            'context_snapshot' => 'array',
            'sort_order' => 'integer',
        ];
    }

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

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

    public function purchaseOrder(): BelongsTo
    {
        return $this->belongsTo(DberpPurchaseOrder::class, 'purchase_order_id');
    }

    public function purchaseOrderItem(): BelongsTo
    {
        return $this->belongsTo(DberpPurchaseOrderItem::class, 'purchase_order_item_id');
    }

    public function purchaseReceiptOrder(): BelongsTo
    {
        return $this->belongsTo(DberpPurchaseReceiptOrder::class, 'purchase_receipt_order_id');
    }

    public function purchaseReceiptItem(): BelongsTo
    {
        return $this->belongsTo(DberpPurchaseReceiptOrderItem::class, 'purchase_receipt_item_id');
    }

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

    public function product(): BelongsTo
    {
        return $this->belongsTo(DberpProduct::class, 'product_id');
    }

    public function handler(): BelongsTo
    {
        return $this->belongsTo(User::class, 'handled_by');
    }
}