<?php

namespace Modules\Inventory\Models;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Modules\Accounts\Models\Traits\HasAccount;
use Modules\Accounts\Models\Traits\HasAccountVouchar;
use Modules\Accounts\Models\Traits\HasFiscalYear;
use Modules\Approval\Contracts\ApprovableDocumentInterface;
use Modules\Approval\Contracts\ApprovalSearchableInterface;
use Modules\Approval\Models\ApprovalWorkflow;
use Modules\Approval\Traits\Approvable;
use Modules\Core\Enums\PaymentStatusEnum;
use Modules\Core\Traits\AuditableTrait;
use Modules\Inventory\Models\Traits\HasPurchaseInvoice;
use Modules\Inventory\Services\ApprovalHandlers\PurchasePaymentApprovalHandler;

class PurchasePayment extends Model implements ApprovableDocumentInterface, ApprovalSearchableInterface
{
    use Approvable,
        HasPurchaseInvoice,
        HasAccountVouchar,
        AuditableTrait,
        HasAccount,
        HasFiscalYear,
        SoftDeletes;

    protected $fillable = [
        'fiscal_year_id',
        'accounting_period_id',
        'purchase_invoice_id',
        'voucher_id',
        'account_id',
        'payment_date',
        'amount',
        'payment_method',
        'reference',
        'note',
        'is_posted',
        'status',
        'submitted_at',
        'approved_at',
        'rejected_at',
        'posted_at',
        'posted_by',
        'created_by',
        'reversal_date',
        'reversed_at',
        'reversed_by',
        'reversal_voucher_id',
        'reversal_reason',
    ];

    protected $casts = [
        'payment_date' => 'date',
        'amount' => 'decimal:2',
        'is_posted' => 'boolean',
        'submitted_at' => 'datetime',
        'approved_at' => 'datetime',
        'rejected_at' => 'datetime',
        'posted_at' => 'datetime',
        'reversal_date' => 'date',
        'reversed_at' => 'datetime',
    ];

    public static function approvalWorkflowCode(): string
    {
        return ApprovalWorkflow::PURCHASE_PAYMENT;
    }

    public function approvalDocumentNumber(): string
    {
        return 'PAY-' . str_pad($this->id, 6, '0', STR_PAD_LEFT);
    }

    public function approvalDocumentDate(): ?string
    {
        return $this->payment_date;
    }

    public function approvalDocumentAmount(): ?string
    {
        return $this->amount;
    }

    public function approvalApiEndpoint(): string
    {
        return route('api.inventory-management.purchase.payments.show', [
            'purchase' => $this->purchase_invoice_id,
            'payment'  => $this->id,
        ]);
    }

    public function approvalFrontendRoute(): string
    {
        $format = config('core.frontend_paths.purchase_payment_show');

        return '/' . sprintf($format, $this->purchase_invoice_id, $this->id);
    }

    public function approvalHandler(): string
    {
        return PurchasePaymentApprovalHandler::class;
    }

    public function isEligibleForPosting(): bool
    {
        return $this->status === PaymentStatusEnum::APPROVED->value && !$this->is_posted && $this->voucher_id === null;
    }

    public function scopeFilterStatus(Builder $query, ?PaymentStatusEnum $status): Builder
    {
        return $query->when($status,
            fn ($q) => $q->where('status', $status->value)
        );
    }

    public function scopeApprovalSearch(Builder $query, string $search): Builder
    {
        return $query->where(function (Builder $subQuery) use ($search) {
            $like = "%{$search}%";

            $subQuery->where('amount', 'like', $like);
        });
    }
}
