<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Order extends Model
{
    use HasFactory;

    public const STATUS_AWAITING_PAYMENT = 'awaiting_payment';
    public const STATUS_PLACED = 'placed';
    public const STATUS_CONFIRMED = 'confirmed';
    public const STATUS_PACKED = 'packed';
    public const STATUS_AWAITING_PICKUP = 'awaiting_pickup';
    public const STATUS_SHIPPED = 'shipped';
    public const STATUS_DELIVERED = 'delivered';
    public const STATUS_CANCELLED = 'cancelled';
    public const STATUS_RETURNED = 'returned';

    public const PAYMENT_PENDING = 'pending';
    public const PAYMENT_PAID = 'paid';
    public const PAYMENT_FAILED = 'failed';
    public const PAYMENT_REFUNDED = 'refunded';

    protected $fillable = [
        'user_id',
        'staff_id',
        'source',
        'address_snapshot',
        'coupon_id',
        'subtotal',
        'discount_total',
        'tax_total',
        'shipping_total',
        'customization_charges',
        'total_payable',
        'payment_status',
        'payment_method',
        'cash_amount',
        'card_amount',
        'change_amount',
        'payment_screenshot_path',
        'status',
        'razorpay_order_id',
        'razorpay_payment_id',
        'razorpay_signature',
        'delhivery_awb',
        'delhivery_label_url',
        'placed_at',
    ];

    protected function casts(): array
    {
        return [
            'address_snapshot' => 'array',
            'subtotal' => 'decimal:2',
            'discount_total' => 'decimal:2',
            'tax_total' => 'decimal:2',
            'shipping_total' => 'decimal:2',
            'customization_charges' => 'decimal:2',
            'total_payable' => 'decimal:2',
            'cash_amount' => 'decimal:2',
            'card_amount' => 'decimal:2',
            'change_amount' => 'decimal:2',
            'placed_at' => 'datetime',
        ];
    }

    public function user()
    {
        return $this->belongsTo(User::class);
    }

    public function staff()
    {
        return $this->belongsTo(User::class, 'staff_id');
    }

    public function items()
    {
        return $this->hasMany(OrderItem::class);
    }

    public function coupon()
    {
        return $this->belongsTo(Coupon::class);
    }

    public function shipments()
    {
        return $this->hasMany(Shipment::class);
    }

    public function tickets()
    {
        return $this->hasMany(Ticket::class);
    }

    public function scopeByStatus($query, string $status)
    {
        if ($status === 'all') {
            return $query;
        }
        
        if ($status === 'processing') {
            return $query->whereIn('status', [self::STATUS_CONFIRMED, self::STATUS_PACKED]);
        }
        
        return $query->where('status', $status);
    }

    /**
     * Get status label for display
     */
    public function getStatusLabelAttribute(): string
    {
        return match($this->status) {
            self::STATUS_AWAITING_PAYMENT => 'Awaiting Payment',
            self::STATUS_PLACED => 'Placed',
            self::STATUS_CONFIRMED => 'Confirmed',
            self::STATUS_PACKED => 'Packed',
            self::STATUS_AWAITING_PICKUP => 'Awaiting Pickup',
            self::STATUS_SHIPPED => 'Shipped',
            self::STATUS_DELIVERED => 'Delivered',
            self::STATUS_CANCELLED => 'Cancelled',
            self::STATUS_RETURNED => 'Returned',
            default => ucfirst($this->status),
        };
    }

    /**
     * Get badge class for status
     */
    public function getStatusBadgeClassAttribute(): string
    {
        return match($this->status) {
            self::STATUS_AWAITING_PAYMENT => 'admin-badge-secondary',
            self::STATUS_PLACED => 'admin-badge-warning',
            self::STATUS_CONFIRMED, self::STATUS_PACKED => 'admin-badge-info',
            self::STATUS_AWAITING_PICKUP => 'admin-badge-info',
            self::STATUS_SHIPPED => 'admin-badge-primary',
            self::STATUS_DELIVERED => 'admin-badge-success',
            self::STATUS_CANCELLED, self::STATUS_RETURNED => 'admin-badge-danger',
            default => 'admin-badge-secondary',
        };
    }

    public function scopePaid($query)
    {
        return $query->where('payment_status', self::PAYMENT_PAID);
    }

    public function scopeOnline($query)
    {
        return $query->where('source', 'online');
    }

    public function scopePos($query)
    {
        return $query->whereIn('source', ['pos', 'pos_to_online']);
    }

    public function scopePosToOnline($query)
    {
        return $query->where('source', 'pos_to_online');
    }

    public function scopeByPaymentMethod($query, string $paymentMethod)
    {
        return $query->where('payment_method', $paymentMethod);
    }

    /**
     * Check if this is a COD order
     */
    public function isCodOrder(): bool
    {
        return $this->payment_method === 'cod';
    }

    /**
     * Check if this is an abandoned online payment (started but never completed)
     */
    public function isAbandonedPayment(): bool
    {
        return $this->payment_method === 'online' 
            && $this->payment_status === self::PAYMENT_PENDING
            && !empty($this->razorpay_order_id)
            && empty($this->razorpay_payment_id)
            && $this->items()->count() === 0;
    }

    /**
     * Check if this order has split payment (both cash and card amounts)
     */
    public function isSplitPayment(): bool
    {
        return !is_null($this->cash_amount) && !is_null($this->card_amount) 
            && $this->cash_amount > 0 && $this->card_amount > 0;
    }

    /**
     * Get human-readable payment type label
     */
    public function getPaymentTypeLabel(): string
    {
        if ($this->isCodOrder()) {
            return 'Cash on Delivery';
        }

        // Check for split payment
        if ($this->isSplitPayment()) {
            return 'Split Payment (Cash + Card/UPI)';
        }

        return match($this->payment_method) {
            'online' => 'Online Payment',
            'offline' => 'Offline Payment',
            'cash' => 'Cash',
            'card' => 'Card',
            'digital_wallet' => 'Digital Wallet',
            default => ucfirst($this->payment_method ?? 'Unknown'),
        };
    }

    /**
     * Get payment method display with split payment breakdown
     */
    public function getPaymentMethodDisplay(): string
    {
        if ($this->isSplitPayment()) {
            $cash = number_format($this->cash_amount, 2);
            $card = number_format($this->card_amount, 2);
            return "Split Payment - Cash: ₹{$cash}, Card/UPI: ₹{$card}";
        }

        return $this->getPaymentTypeLabel();
    }

    /**
     * Get payment status display text considering payment method
     */
    public function getPaymentStatusDisplay(): string
    {
        // COD orders
        if ($this->isCodOrder()) {
            return match($this->payment_status) {
                self::PAYMENT_PENDING => 'COD - Pay on Delivery',
                self::PAYMENT_PAID => 'Paid on Delivery',
                default => 'COD - ' . ucfirst($this->payment_status),
            };
        }

        // Online payments
        if ($this->payment_method === 'online') {
            if ($this->isAbandonedPayment()) {
                return 'Payment Cancelled';
            }

            return match($this->payment_status) {
                self::PAYMENT_PENDING => 'Payment Pending',
                self::PAYMENT_PAID => 'Payment Successful',
                self::PAYMENT_FAILED => 'Payment Failed',
                self::PAYMENT_REFUNDED => 'Payment Refunded',
                default => ucfirst($this->payment_status),
            };
        }

        // Other payment methods
        return match($this->payment_status) {
            self::PAYMENT_PENDING => 'Payment Pending',
            self::PAYMENT_PAID => 'Paid',
            self::PAYMENT_FAILED => 'Payment Failed',
            self::PAYMENT_REFUNDED => 'Refunded',
            default => ucfirst($this->payment_status),
        };
    }

    /**
     * Get payment status badge class for display
     */
    public function getPaymentStatusBadgeClass(): string
    {
        // COD orders
        if ($this->isCodOrder()) {
            return match($this->payment_status) {
                self::PAYMENT_PENDING => 'payment-cod',
                self::PAYMENT_PAID => 'payment-paid',
                default => 'payment-pending',
            };
        }

        // Online payments
        if ($this->payment_method === 'online') {
            if ($this->isAbandonedPayment()) {
                return 'payment-cancelled';
            }

            return match($this->payment_status) {
                self::PAYMENT_PENDING => 'payment-pending-online',
                self::PAYMENT_PAID => 'payment-paid',
                self::PAYMENT_FAILED => 'payment-failed',
                self::PAYMENT_REFUNDED => 'payment-refunded',
                default => 'payment-pending',
            };
        }

        // Default
        return 'payment-' . $this->payment_status;
    }

    /**
     * Scope: Filter COD orders
     */
    public function scopeCod($query)
    {
        return $query->where('payment_method', 'cod');
    }

    /**
     * Scope: Filter abandoned online payments
     */
    public function scopeAbandonedPayments($query)
    {
        return $query->where('payment_method', 'online')
            ->where('payment_status', self::PAYMENT_PENDING)
            ->whereNotNull('razorpay_order_id')
            ->whereNull('razorpay_payment_id')
            ->whereDoesntHave('items');
    }

    /**
     * Scope: Filter failed online payments
     */
    public function scopeFailedPayments($query)
    {
        return $query->where('payment_status', self::PAYMENT_FAILED);
    }

    /**
     * Scope: Filter pending online payments (not COD)
     */
    public function scopePendingOnlinePayments($query)
    {
        return $query->where('payment_method', 'online')
            ->where('payment_status', self::PAYMENT_PENDING);
    }
}
