<?php

namespace Mtc\Plugins\MtcUnioIntegration\Commands;

use Illuminate\Console\Command;
use Mtc\Modules\MtcUnio\Classes\UnioApi;
use Mtc\Plugins\MtcUnioIntegration\Classes\QueueMessageToUnio;
use Illuminate\Support\Facades\App;

/**
 * Examples:
 *    php artisan unioqueue:process_messages_to_unio --dry-run
 *    php artisan unioqueue:process_messages_to_unio --dry-run -- 4 7 18
 *    php artisan unioqueue:process_messages_to_unio
 *    php artisan unioqueue:process_messages_to_unio --limit=10
 *    php artisan unioqueue:process_messages_to_unio -- 7 18
 */


class UnioQueueProcessMessagesToUnio extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'unioqueue:process_messages_to_unio {--dry-run} {--limit=1} {message_id?*}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = '...';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        // TODO: perhaps save the requestId in db as a separate field.
        //
        //$rows = QueueMessageToUnio::query()->where('id', '=', 13)->get();
        //foreach ($rows as $row) {
        //    echo(json_decode(json_decode($row->response)->body)->requestId);
        //    echo "\n";
        //}
        //die;


        $message_ids = $this->argument('message_id');
        $is_dry_run = $this->option('dry-run');
        $limit = $this->option('limit');

        if ($message_ids) {

            foreach ($message_ids as $message_id) {
                $obj = QueueMessageToUnio::find($message_id);
                $this->process($obj, $is_dry_run);
            }

        } else {

            $pending_count = QueueMessageToUnio::pending()->count();
            $remaining = min($pending_count, $limit);
            while ($remaining) {
                $obj = QueueMessageToUnio::dequeue($is_dry_run);

                if (! $obj) {
                    // $this->info("No more pending messages found.");
                    break;
                }

                $this->process($obj, $is_dry_run);
                $remaining--;
                $this->info("{$remaining} message(s) remaining.");
            }

        }

    }


    private function process($obj, $is_dry_run = false)
    {
        $this->info("Processing queue message id:{$obj->id} ({$obj->entity_type}:{$obj->entity_id}) ...");

        if ($is_dry_run) {
            $this->do_dry_run($obj);
        } else {
            $this->do_live_run($obj);
        }

        $this->info(" - done processing message id:{$obj->id} ({$obj->entity_type}:{$obj->entity_id}).");
    }


    private function do_dry_run($obj)
    {
        $payload = $obj->getPayloadData();

        echo json_encode($payload, JSON_UNESCAPED_SLASHES);
    }


    private function do_live_run($obj)
    {
        try {
            $response = UnioApi::init()->makeRequest($obj);
            $obj->saveResponse($response);
            $obj->processResponse();
            $obj->saveStatus(QueueMessageToUnio::STATUS_SUCCESS);

        } catch (\Exception $e) {
            $error_msg = $e->getMessage() . ' at ' . $e->getFile() . ':' . $e->getLine();
            $this->error($error_msg);
            $obj->saveResponse($error_msg);
            $obj->saveStatus(QueueMessageToUnio::STATUS_FAILED);
        }
    }
}
