<?php

namespace App\Models;

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

class Order extends Model
{
    public const STATUS_PENDING = 'pending';
    public const STATUS_PAID = 'paid';
    public const STATUS_PREPARING = 'preparing';
    public const STATUS_SHIPPED = 'shipped';
    public const STATUS_DELIVERED = 'delivered';
    public const STATUS_CANCELLED = 'cancelled';

    public const PAYMENT_PENDING = 'pending';
    public const PAYMENT_PAID = 'paid';
    public const PAYMENT_FAILED = 'failed';
    public const PAYMENT_REFUNDED = 'refunded';

    public const DELIVERY_PENDING = 'pending';
    public const DELIVERY_ASSIGNED = 'assigned';
    public const DELIVERY_ACCEPTED = 'accepted';
    public const DELIVERY_PICKED_UP = 'picked_up';
    public const DELIVERY_IN_TRANSIT = 'in_transit';
    public const DELIVERY_DELIVERED = 'delivered';
    public const DELIVERY_FAILED = 'failed';

    protected $fillable = [
        'number',
        'invoice_number',
        'user_id',
        'address_id',
        'livreur_id',
        'subtotal',
        'delivery_fee',
        'total',
        'status',
        'payment_status',
        'payment_reference',
        'paid_at',
        'delivery_status',
        'delivery_assigned_at',
        'delivered_at',
        'delivery_proof_path',
    ];

    protected function casts(): array
    {
        return [
            'subtotal' => 'decimal:2',
            'delivery_fee' => 'decimal:2',
            'total' => 'decimal:2',
            'paid_at' => 'datetime',
            'delivery_assigned_at' => 'datetime',
            'delivered_at' => 'datetime',
        ];
    }

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

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

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

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

    public static function generateNumber(): string
    {
        $year = now()->format('Y');
        $count = static::whereYear('created_at', $year)->count();

        return sprintf('CMD-%s-%05d', $year, $count + 1);
    }

    public function generateInvoiceNumber(): string
    {
        $year = $this->created_at?->format('Y') ?? now()->format('Y');

        return sprintf('FAC-%s-%06d', $year, (int) $this->id);
    }

    public function ensureInvoiceNumber(): string
    {
        if (filled($this->invoice_number)) {
            return (string) $this->invoice_number;
        }

        $this->invoice_number = $this->generateInvoiceNumber();
        $this->saveQuietly();

        return (string) $this->invoice_number;
    }
}
