<?php

namespace App\Console\Commands;

use App\Models\Order;
use App\Models\OrderCourierShipment;
use App\Services\OrderStatusSmsService;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;

class RetryCourierOutForDeliverySmsCommand extends Command
{
    protected $signature = 'courier:retry-out-for-delivery-sms {--limit=50}';

    protected $description = 'Retry failed courier-confirmed Out for Delivery SMS messages (maximum three attempts).';

    public function handle(OrderStatusSmsService $smsService): int
    {
        $ids = OrderCourierShipment::query()
            ->whereNotNull('out_for_delivery_at')
            ->whereNull('out_for_delivery_sms_sent_at')
            ->where('out_for_delivery_sms_status', 'failed')
            ->where('out_for_delivery_sms_attempts', '<', 3)
            ->where(function ($query) {
                $query->whereNotNull('courier_rider_id')
                    ->orWhereNotNull('courier_rider_name')
                    ->orWhereNotNull('courier_rider_phone');
            })
            ->where(function ($query) {
                $query->whereNull('out_for_delivery_sms_next_retry_at')
                    ->orWhere('out_for_delivery_sms_next_retry_at', '<=', now());
            })
            ->orderBy('id')
            ->limit(max(1, min((int) $this->option('limit'), 500)))
            ->pluck('id');

        foreach ($ids as $id) {
            DB::transaction(function () use ($id, $smsService) {
                $shipment = OrderCourierShipment::query()->lockForUpdate()->find($id);
                if (! $shipment || $shipment->out_for_delivery_sms_sent_at) {
                    return;
                }

                $order = Order::query()->lockForUpdate()->find($shipment->order_id);
                if (! $order || $order->order_status !== 'picked_up') {
                    return;
                }

                $order->setRelation('courierShipment', $shipment);
                $smsService->sendForOrder($order, 'picked_up', 'courier_out_for_delivery');
            });
        }

        $this->info('Processed '.$ids->count().' pending courier Out for Delivery SMS retries.');

        return self::SUCCESS;
    }
}
