<?php

namespace App\Models;

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

class Order extends Model
{
    use HasFactory;

    const STATUS_PENDING = 'pending';
    const STATUS_PENDING_SUPPLIER = 'pending_supplier';
    const STATUS_ORDERED_FROM_SUPPLIER = 'ordered_from_supplier';
    const STATUS_RECEIVED_FROM_SUPPLIER = 'received_from_supplier';
    const STATUS_PROCESSING = 'processing';
    const STATUS_SHIPPING = 'shipping';
    const STATUS_DELIVERED = 'delivered';
    const STATUS_RETURNED = 'returned';

    protected $fillable = [
        'user_id',
        'status',
        'payment_method',
        'payment_method_id',
        'payment_fee',
        'payment_receipt',
        'payment_status',
        'subtotal',
        'points_redeemed',
        'discount_from_points',
        'shipping_cost',
        'extra_charges',
        'total',
        'total_profit',
        'points_earned',
        'notes',
        'shipping_address_id',
        'shipping_governorate',
        'shipping_address_snapshot',
    ];

    protected function casts(): array
    {
        return [
            'subtotal' => 'decimal:2',
            'discount_from_points' => 'decimal:2',
            'shipping_cost' => 'decimal:2',
            'payment_fee' => 'decimal:2',
            'extra_charges' => 'decimal:2',
            'total' => 'decimal:2',
            'total_profit' => 'decimal:2',
            'points_redeemed' => 'integer',
            'points_earned' => 'integer',
        ];
    }

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

    public function shippingAddress(): BelongsTo
    {
        return $this->belongsTo(UserAddress::class, 'shipping_address_id');
    }

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

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

    /**
     * عناصر الطلب مجمعة حسب المنتج الأب (للعرض في الفاتورة).
     * كل سطر: اسم المنتج، إجمالي الكمية، سعر الوحدة (المتوسط المرجح)، إجمالي السطر.
     */
    public function getItemsGroupedByProduct(): array
    {
        $this->loadMissing(['items.variant.product']);

        $groups = [];
        foreach ($this->items as $item) {
            $productId = $item->variant?->product_id ?? 'orphan-' . $item->id;
            $productName = $item->variant?->product?->name ?? 'منتج';

            if (! isset($groups[$productId])) {
                $groups[$productId] = [
                    'product_name' => $productName,
                    'total_quantity' => 0,
                    'total_line_amount' => 0,
                ];
            }

            $lineAmount = (float) $item->quantity * (float) $item->unit_price;
            $groups[$productId]['total_quantity'] += $item->quantity;
            $groups[$productId]['total_line_amount'] += $lineAmount;
        }

        foreach ($groups as &$g) {
            $g['unit_price'] = $g['total_quantity'] > 0
                ? round($g['total_line_amount'] / $g['total_quantity'], 2)
                : 0;
        }

        return array_values($groups);
    }

    /**
     * إجمالي عدد القطع في الطلب (مجموع كل النقشات).
     */
    public function getTotalPiecesCount(): int
    {
        return (int) $this->items()->sum('quantity');
    }

    /**
     * أوامر الشراء المرتبطة بهذا الطلب (واحد لكل مورد).
     */
    public function purchaseOrders(): HasMany
    {
        return $this->hasMany(PurchaseOrder::class, 'source_order_id');
    }

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

    public function hasOnDemandItems(): bool
    {
        return $this->items()
            ->whereHas('variant.product', fn ($q) => $q->where('fulfillment_type', 'on_demand'))
            ->exists();
    }

    public function recalculateTotal(): void
    {
        $this->total = round(
            (float) $this->subtotal
            - (float) $this->discount_from_points
            + (float) $this->shipping_cost
            + (float) $this->payment_fee
            + (float) $this->extra_charges,
            2
        );
    }

    /**
     * هل طريقة الدفع نقداً عند الاستلام (لا تتطلب اعتماد إيصال)؟
     */
    public function isPaymentCod(): bool
    {
        $slug = $this->payment_method ?? $this->paymentMethod?->slug ?? '';

        return strtolower($slug) === 'cash';
    }

    /**
     * هل يمكن تغيير حالة الطلب للشحن؟ (يتطلب اعتماد الدفع للطرق غير النقدية)
     */
    public function canProgressToShipping(): bool
    {
        if ($this->isPaymentCod()) {
            return true;
        }

        return $this->payment_status === 'confirmed';
    }

    public static function getPaymentStatusLabels(): array
    {
        return [
            'pending' => 'قيد المراجعة',
            'confirmed' => 'مؤكد',
            'rejected' => 'مرفوض',
        ];
    }

    public static function getStatusLabels(): array
    {
        return [
            self::STATUS_PENDING => 'قيد الانتظار',
            self::STATUS_PENDING_SUPPLIER => 'بانتظار المورد',
            self::STATUS_ORDERED_FROM_SUPPLIER => 'تم الطلب من المورد',
            self::STATUS_RECEIVED_FROM_SUPPLIER => 'تم الاستلام من المورد',
            self::STATUS_PROCESSING => 'جاري التجهيز',
            self::STATUS_SHIPPING => 'جاري الشحن',
            self::STATUS_DELIVERED => 'تم التسليم',
            self::STATUS_RETURNED => 'مرتجع',
        ];
    }
}
