<?php

declare(strict_types=1);

namespace App\Models;

use App\Business\Sales\Enums\SalesQuoteStatus;
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;

class DberpSalesQuote extends Model
{
    use GeneratesDberpCode;
    use HasDberpAuditTrail;

    protected $table = 'dberp_sales_quotes';

    /**
     * @var list<string>
     */
    protected $fillable = [
        'code',
        'customer_id',
        'handler_employee_id',
        'quote_date',
        'valid_from',
        'valid_until',
        'status',
        'suggested_payment_term_days',
        'total_quantity',
        'total_amount',
        'discount_amount',
        'final_amount',
        'converted_sales_order_id',
        'converted_sales_order_no',
        'converted_at',
        'source_system',
        'external_reference_id',
        'remark',
    ];

    protected function casts(): array
    {
        return [
            'customer_id' => 'integer',
            'handler_employee_id' => 'integer',
            'quote_date' => 'date',
            'valid_from' => 'date',
            'valid_until' => 'date',
            'suggested_payment_term_days' => 'integer',
            'total_quantity' => 'decimal:4',
            'total_amount' => 'decimal:4',
            'discount_amount' => 'decimal:4',
            'final_amount' => 'decimal:4',
            'converted_sales_order_id' => 'integer',
            'converted_at' => 'datetime',
        ];
    }

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

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

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

    public function customer(): BelongsTo
    {
        return $this->belongsTo(DberpCustomer::class, 'customer_id');
    }

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

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

    public function convertedSalesOrder(): BelongsTo
    {
        return $this->belongsTo(DberpSalesOrder::class, 'converted_sales_order_id');
    }

    public function currentStatus(): SalesQuoteStatus
    {
        $status = SalesQuoteStatus::tryFrom((string) $this->status) ?? SalesQuoteStatus::Draft;
        $today = now()->toDateString();
        $validFrom = $this->valid_from === null ? null : substr((string) $this->valid_from, 0, 10);
        $validUntil = $this->valid_until === null ? null : substr((string) $this->valid_until, 0, 10);

        if (in_array($status, [SalesQuoteStatus::Draft, SalesQuoteStatus::Converted, SalesQuoteStatus::Voided], true)) {
            return $status;
        }

        if ($validFrom !== null && $validFrom > $today) {
            return SalesQuoteStatus::PendingEffective;
        }

        if ($validUntil !== null && $validUntil < $today) {
            return SalesQuoteStatus::Expired;
        }

        return SalesQuoteStatus::Effective;
    }
}