<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;
use App\Models\Concerns\LogsActivity;

class Order extends Model
{
    use LogsActivity;

    public function getActivityLogDescription(string $action): string
    {
        if ($action === 'updated') {
            $changes = [];
            if ($this->isDirty('status') || $this->wasChanged('status')) {
                $changes[] = 'status to ' . ucfirst($this->status);
            }
            if ($this->isDirty('payment_status') || $this->wasChanged('payment_status')) {
                $changes[] = 'payment status to ' . ucfirst($this->payment_status);
            }
            
            if (!empty($changes)) {
                return sprintf('Order #%s updated: %s', $this->order_number, implode(', ', $changes));
            }
        }

        return sprintf('Order #%s %s', $this->order_number, $action);
    }


    protected $fillable = [
        'order_number',
        'user_id',
        'customer_name',
        'customer_email',
        'customer_phone',
        'shipping_address',
        'billing_address',
        'subtotal',
        'shipping_cost',
        'tax',
        'discount_type',
        'discount_value',
        'discount',
        'grand_total',
        'payment_method',
        'payment_status',
        'status',
        'coupon_code',
        'notes',
        'staff_notes',
        'currency',
        'country',
        'street_address',
        'city',
        'state',
        'zip',
        'shipping_method_id',
        'is_exchange',
        'parent_order_id',
        'is_reseller_order',
        'reseller_id',
        'total_reseller_price',
        'total_reseller_profit',
    ];

    protected $casts = [
        'subtotal' => 'decimal:2',
        'shipping_cost' => 'decimal:2',
        'tax' => 'decimal:2',
        'discount_type' => 'string',
        'discount_value' => 'decimal:2',
        'discount' => 'decimal:2',
        'grand_total' => 'decimal:2',
        'is_exchange' => 'boolean',
        'is_reseller_order' => 'boolean',
        'total_reseller_price' => 'decimal:2',
        'total_reseller_profit' => 'decimal:2',
    ];

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

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

    public function parentOrder(): BelongsTo
    {
        return $this->belongsTo(Order::class, 'parent_order_id');
    }

    public function childOrders(): HasMany
    {
        return $this->hasMany(Order::class, 'parent_order_id');
    }

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

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

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

    public function courierBooking(): HasOne
    {
        return $this->hasOne(CourierBooking::class);
    }

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

    protected static function boot()
    {
        parent::boot();

        static::creating(function ($order) {
            if (empty($order->order_number)) {
                $order->order_number = 'SB-' . strtoupper(\Illuminate\Support\Str::random(3)) . '-' . date('ymdHis');
            }
        });

        static::saving(function ($order) {
            if ($order->user_id) {
                $user = User::find($order->user_id);
                if ($user) {
                    if (blank($order->customer_name)) {
                        $order->customer_name = $user->name;
                    }
                    if (blank($order->customer_phone)) {
                        $order->customer_phone = $user->phone ?? '01700000000';
                    }
                    if (blank($order->customer_email)) {
                        $order->customer_email = $user->email;
                    }
                }
            }

            $order->customer_name = $order->customer_name ?? '';
            $order->customer_phone = $order->customer_phone ?? '';
            $order->shipping_address = $order->shipping_address ?? '';
        });

        static::saved(function ($order) {
            if ($order->is_reseller_order) {
                // Only recalculate if order already has items saved.
                // On initial creation, items don't exist yet — skip to avoid zeroing prices.
                $itemCount = $order->items()->count();
                if ($itemCount === 0) return;

                $totalResellerPrice = 0;
                $totalResellerProfit = 0;
                $subtotal = 0;

                foreach ($order->items as $item) {
                    $product = $item->product;
                    if ($product && ($item->reseller_price == 0 || $item->reseller_profit == 0)) {
                        $item->reseller_price = $product->reseller_price;
                        $item->reseller_profit = max(0, ($item->price - $product->reseller_price) * $item->quantity);
                        $item->saveQuietly();
                    }
                    $totalResellerPrice += $item->reseller_price * $item->quantity;
                    $totalResellerProfit += $item->reseller_profit;
                    $subtotal += $item->price * $item->quantity;
                }

                $grandTotal = $subtotal + $order->shipping_cost - $order->discount;

                $order->updateQuietly([
                    'total_reseller_price'  => $totalResellerPrice,
                    'total_reseller_profit' => $totalResellerProfit,
                    'subtotal'              => $subtotal,
                    'grand_total'           => $grandTotal,
                ]);
            }

            if ($order->is_exchange) {
                $returnRequest = \App\Models\ReturnRequest::where('exchange_order_id', $order->id)->first();
                if ($returnRequest) {
                    $refundAmount = max(0, (float) $order->discount - (float) $order->subtotal - (float) $order->shipping_cost);
                    $returnRequest->update([
                        'refund_amount' => $refundAmount,
                    ]);
                }
            }

            if ($order->wasChanged('payment_status') && $order->payment_status === 'paid') {
                $exists = $order->transactions()->where('status', 'success')->exists();
                if (!$exists) {
                    $provider = in_array($order->payment_method, ['stripe', 'paypal', 'sslcommerz', 'bkash', 'nagad', 'cod'])
                        ? $order->payment_method
                        : 'cod';
                    
                    $method = match ($order->payment_method) {
                        'sslcommerz', 'stripe', 'paypal' => 'credit_card',
                        'bkash', 'nagad' => 'mobile_banking',
                        default => 'cash',
                    };

                    $order->transactions()->create([
                        'transaction_id' => 'TXN-' . strtoupper(\Illuminate\Support\Str::random(10)),
                        'payment_method' => $method,
                        'amount' => $order->grand_total,
                        'status' => 'success',
                        'provider' => $provider,
                    ]);
                }
            }
        });

        static::updated(function ($order) {
            if ($order->wasChanged('status')) {
                $oldStatus = $order->getOriginal('status');
                $newStatus = $order->status;

                // Handle Reseller profit wallet credit
                if ($order->is_reseller_order && $order->reseller_id) {
                    if ($newStatus === 'delivered' && $oldStatus !== 'delivered') {
                        // Credit reseller profit to wallet
                        ResellerWalletTransaction::create([
                            'user_id' => $order->reseller_id,
                            'amount' => $order->total_reseller_profit,
                            'type' => 'credit',
                            'status' => 'completed',
                            'description' => "Profit earned from order #{$order->order_number}",
                            'order_id' => $order->id,
                        ]);
                    } elseif ($oldStatus === 'delivered' && $newStatus !== 'delivered') {
                        // Reverse profit (debit) if order shifts away from delivered
                        ResellerWalletTransaction::create([
                            'user_id' => $order->reseller_id,
                            'amount' => $order->total_reseller_profit,
                            'type' => 'debit',
                            'status' => 'completed',
                            'description' => "Reverse profit from order #{$order->order_number} due to status change from delivered to {$newStatus}",
                            'order_id' => $order->id,
                        ]);
                    }
                }
            }
        });
    }

    /**
     * Scope a query to filter orders by status.
     */
    public function scopeByStatus($query, string $status)
    {
        return $query->where('status', $status);
    }

    /**
     * Scope a query to filter orders between a date range.
     */
    public function scopeByDateRange($query, $start, $end)
    {
        return $query->whereBetween('created_at', [$start, $end]);
    }

    /**
     * Get the badge color CSS class representing the order status.
     */
    public function getStatusColorAttribute(): string
    {
        return match ($this->status) {
            'pending' => 'bg-yellow-100 text-yellow-800 border-yellow-200',
            'processing' => 'bg-blue-100 text-blue-800 border-blue-200',
            'shipped' => 'bg-indigo-100 text-indigo-800 border-indigo-200',
            'delivered' => 'bg-green-100 text-green-800 border-green-200',
            'cancelled' => 'bg-red-100 text-red-800 border-red-200',
            'returned' => 'bg-purple-100 text-purple-800 border-purple-200',
            default => 'bg-gray-100 text-gray-800 border-gray-200',
        };
    }
}
