<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\MorphMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Spatie\Activitylog\Traits\LogsActivity;
use Spatie\Activitylog\LogOptions;

class FactoryInvoice extends Model
{
    use LogsActivity;

    protected $fillable = [
        'invoice_number',
        'invoice_type_id',
        'customer_account_id',
        'supervising_employee_account_id',
        'total_ordered_amount',
        'total_delivered_amount',
        'discount_amount',
        'discount_percentage',
        'tax_amount',
        'gross_total',
        'net_total',
        'status',
        'remarks',
        'invoice_date',
        'warehouse_picked_at',
        'warehouse_picked_by',
        'delivered_at',
        'delivered_by'
    ];

    protected $casts = [
        'total_ordered_amount' => 'decimal:2',
        'total_delivered_amount' => 'decimal:2',
        'discount_amount' => 'decimal:2',
        'discount_percentage' => 'decimal:2',
        'tax_amount' => 'decimal:2',
        'gross_total' => 'decimal:2',
        'net_total' => 'decimal:2',
        'invoice_date' => 'date',
        'warehouse_picked_at' => 'datetime',
        'delivered_at' => 'datetime'
    ];

    // Status constants
    const STATUS_WAREHOUSE_PENDING = 'warehouse_pending';
    const STATUS_PICKED = 'picked';
    // const STATUS_TRANSPORT = 'transport';
    const STATUS_DELIVERED = 'delivered';
    const STATUS_COMPLETED = 'completed';

    // Relationships
    public function invoiceType(): BelongsTo
    {
        return $this->belongsTo(InvoiceType::class, 'invoice_type_id');
    }

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

    public function supervisingEmployee(): BelongsTo
    {
        return $this->belongsTo(Account::class, 'supervising_employee_account_id');
    }

    public function payments(): MorphMany
    {
        return $this->morphMany(AccountTransaction::class, 'reference');
    }

    public function items(): HasMany
    {
        return $this->hasMany(FactoryInvoiceItem::class);
    }

    public function deliveryReceipts()
    {
        return $this->hasManyThrough(DeliveryReceipt::class, DeliveryReceiptItem::class, 'factory_invoice_id', 'id', 'id', 'delivery_receipt_id');
    }

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

    public function deliveryMan(): BelongsTo
    {
        return $this->belongsTo(Account::class, 'delivered_by');
    }

    // Helper methods
    public function getEffectiveTotalAttribute()
    {
        return $this->total_delivered_amount ?? $this->total_ordered_amount;
    }

    public function isPendingWarehouse()
    {
        return $this->status === self::STATUS_WAREHOUSE_PENDING;
    }

    public function isPicked()
    {
        return $this->status === self::STATUS_PICKED;
    }

    public function isInTransport()
    {
        return $this->status === self::STATUS_TRANSPORT;
    }

    public function isDelivered()
    {
        return $this->status === self::STATUS_DELIVERED;
    }

    public function isCompleted()
    {
        return $this->status === self::STATUS_COMPLETED;
    }

    public function recalculateTotals()
    {
        $items = $this->items;

        $totalOrdered = $items->sum('ordered_total');
        $totalDelivered = $items->sum('delivered_total');

        $this->update([
            'total_ordered_amount' => $totalOrdered,
            'total_delivered_amount' => $totalDelivered,
            'net_total' => $totalDelivered ?: $totalOrdered
        ]);
    }

    public function getActivitylogOptions(): LogOptions
    {
        return LogOptions::defaults()
            ->useLogName('factory_invoice')
            ->logFillable()
            ->logOnlyDirty()
            ->dontSubmitEmptyLogs();
    }
}
