<?php

namespace App\Models;

use App\Enums\InvoiceStatus;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;

class InvoiceReport extends Model
{
    use HasFactory;

    protected $fillable = [
        'internal_id',
        'customer_id',
        'date_start',
        'date_end',
        'subtotal',
        'with_unpaid',
        'with_partially_paid',
        'with_paid',
        'with_void',
        'pst',
        'gst',
    ];

    protected $appends = [
        'total',
        'balance',
    ];

    protected $casts = [
        'date_start' => 'date',
        'date_end'   => 'date',
    ];

    public static function boot(): void
    {
        parent::boot();

        static::created(function (InvoiceReport $model) {
            $model->attributes['internal_id'] = 'TNR'.str_pad($model->id, 4, '0', STR_PAD_LEFT);

            $invoices = Invoice::whereBetween('date', [$model->date_start, $model->date_end])
                ->where('customer_id', $model->customer_id)
                ->when(! $model->with_unpaid, fn ($query) => $query->whereNot('status', InvoiceStatus::UNPAID))
                ->when(! $model->with_partially_paid, fn ($query) => $query->whereNot('status', InvoiceStatus::PARTIALLY_PAID))
                ->when(! $model->with_paid, fn ($query) => $query->whereNot('status', InvoiceStatus::PAID))
                ->when(! $model->with_void, fn ($query) => $query->whereNot('status', InvoiceStatus::VOID));

            $model->invoices()->sync($invoices->pluck('id')->toArray());

            $model->save();
        });
    }

    public function combinedGstHstSum(): float
    {
        return $this->invoices()->sum('gst_amount') + $this->invoices()->sum('hst_amount');
    }

    public function getTotalAttribute()
    {
        return $this->invoices()->sum('total');
    }

    public function getBalanceAttribute()
    {
        return $this->invoices->sum(fn (Invoice $invoice) => $invoice->remainingBalance());
    }

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

    public function invoices(): BelongsToMany
    {
        return $this->BelongsToMany(Invoice::class);
    }

    public function orders()
    {
        return $this->invoices()->with('orders')->get()->pluck('orders')->flatten()->unique('id');
    }
}