<?php

declare(strict_types=1);

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;

class Invoice extends Model
{
    protected $guarded = ['id', 'created_at', 'updated_at'];

    protected $casts = [
        'total' => 'decimal:0',
        'commission_percent' => 'decimal:2',
        'late_fee_amount' => 'decimal:0',
        'issued_at' => 'date',
        'due_at' => 'date',
        'meta' => 'array',
    ];

    public const TYPE_INCOME = 'income';
    public const TYPE_EXPENSE = 'expense';

    public const STATUS_DRAFT = 'draft';
    public const STATUS_PENDING = 'pending';
    public const STATUS_PAID = 'paid';
    public const STATUS_UNPAID = 'unpaid';
    public const STATUS_APPROVED = 'approved';
    public const STATUS_REJECTED = 'rejected';
    public const STATUS_NEEDS_EDIT = 'needs_edit';

    public const PAYMENT_CASH = 'cash';
    public const PAYMENT_CHECK = 'check';

    public function project(): BelongsTo
    {
        return $this->belongsTo(Project::class);
    }

    public function user(): BelongsTo
    {
        return $this->belongsTo(User::class);
    }

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

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

    public function payableAmount(): int
    {
        return (int) $this->total + (int) $this->late_fee_amount;
    }

    public function isEditable(): bool
    {
        return in_array($this->status, [
            self::STATUS_DRAFT,
            self::STATUS_NEEDS_EDIT,
            self::STATUS_REJECTED,
        ], true);
    }

    public function isPayable(): bool
    {
        return in_array($this->status, [
            self::STATUS_UNPAID,
            self::STATUS_APPROVED,
        ], true) && $this->type === self::TYPE_EXPENSE;
    }
}
