<?php

namespace App\Models;

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

class MexcoInvoice extends Model
{
    public const STATUS_DRAFT = 'draft';

    public const STATUS_PENDING = 'pending';

    public const STATUS_PAID = 'paid';

    public const STATUS_FAILED = 'failed';

    public const STATUS_REFUNDED = 'refunded';

    public const STATUS_CANCELLED = 'cancelled';

    protected $table = 'mexco_invoices';

    protected $fillable = [
        'invoice_number',
        'organisation_id',
        'event_id',
        'event_license_id',
        'subtotal_cents',
        'discount_cents',
        'tax_cents',
        'total_cents',
        'currency',
        'status',
        'issued_at',
        'due_at',
        'paid_at',
        'promo_code_id',
        'metadata',
    ];

    protected function casts(): array
    {
        return [
            'issued_at' => 'datetime',
            'due_at' => 'datetime',
            'paid_at' => 'datetime',
            'metadata' => 'array',
        ];
    }

    public function organisation(): BelongsTo
    {
        return $this->belongsTo(MexcoOrganisation::class, 'organisation_id');
    }

    public function event(): BelongsTo
    {
        return $this->belongsTo(MeetupEvent::class, 'event_id');
    }

    public function license(): BelongsTo
    {
        return $this->belongsTo(MexcoEventLicense::class, 'event_license_id');
    }

    public function promoCode(): BelongsTo
    {
        return $this->belongsTo(MexcoPromoCode::class, 'promo_code_id');
    }

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

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

    public static function statuses(): array
    {
        return [
            self::STATUS_DRAFT => 'Draft',
            self::STATUS_PENDING => 'Pending payment',
            self::STATUS_PAID => 'Paid',
            self::STATUS_FAILED => 'Failed',
            self::STATUS_REFUNDED => 'Refunded',
            self::STATUS_CANCELLED => 'Cancelled',
        ];
    }

    public function statusLabel(): string
    {
        return self::statuses()[$this->status] ?? ucfirst($this->status);
    }

    public function formattedTotal(): string
    {
        return $this->currency.' '.number_format($this->total_cents / 100, 2);
    }

    public function amountPaidCents(): int
    {
        return (int) $this->payments()
            ->where('status', MexcoPayment::STATUS_PAID)
            ->sum('amount_cents');
    }

    public function amountDueCents(): int
    {
        return max(0, $this->total_cents - $this->amountPaidCents());
    }
}
