<?php

namespace App\Console\Commands;

use App\Http\Controllers\Api\PayFastCallbackController;
use App\Models\AccountCreditDeposit;
use App\Models\PayFastPayment;
use Illuminate\Console\Command;
use Illuminate\Http\Request;
use Symfony\Component\Console\Command\Command as CommandStatus;

class RecoverPayFastCallback extends Command
{
    protected $signature = 'payfast:recover-callback {basket_id : The exact PayFast basket ID} {--force : Process without an interactive confirmation}';

    protected $description = 'Safely re-verify and process a stored PayFast callback that previously failed before WHMCS synchronization';

    public function handle(PayFastCallbackController $controller): int
    {
        $basketId = trim((string) $this->argument('basket_id'));

        $record = PayFastPayment::query()->where('basket_id', $basketId)->first();
        $type = 'invoice payment';

        if (! $record) {
            $record = AccountCreditDeposit::query()->where('basket_id', $basketId)->first();
            $type = 'account credit deposit';
        }

        if (! $record) {
            $this->error('No PayFast invoice payment or credit deposit exists for basket '.$basketId.'.');

            return CommandStatus::FAILURE;
        }

        if ($record->status === 'completed') {
            $this->info('This '.$type.' is already completed. Nothing was changed.');

            return CommandStatus::SUCCESS;
        }

        $payload = $record->callback_payload;
        if (! is_array($payload) || $payload === [] || isset($payload['_truncated'])) {
            $this->error('The original callback payload is missing or truncated. Do not recover it from incomplete data.');

            return CommandStatus::FAILURE;
        }

        $this->table(
            ['Field', 'Value'],
            [
                ['Type', $type],
                ['Basket ID', $basketId],
                ['Current status', (string) $record->status],
                ['Expected amount', number_format((float) $record->expected_amount, 2, '.', '')],
                ['Expected currency', (string) $record->expected_currency],
                ['Callback transaction amount', (string) ($record->callback_amount ?? '')],
                ['Callback merchant amount', (string) ($record->merchant_amount ?? '')],
                ['PayFast transaction ID', (string) ($record->transaction_id ?: ($payload['transaction_id'] ?? $payload['TRANSACTION_ID'] ?? ''))],
                ['PayFast error code', (string) ($record->payfast_error_code ?? '')],
                ['Previous error', (string) ($record->last_error ?? '')],
            ]
        );

        if (! $this->option('force') && ! $this->confirm('Re-run the stored callback through the full verification and WHMCS synchronization flow?')) {
            $this->warn('No changes were made.');

            return CommandStatus::SUCCESS;
        }

        $request = Request::create('/api/payfast/callback', 'POST', $payload);
        $response = $controller($request);
        $body = json_decode((string) $response->getContent(), true);

        $this->line('HTTP '.$response->getStatusCode());
        $this->line(json_encode($body, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) ?: (string) $response->getContent());

        return $response->isSuccessful() ? CommandStatus::SUCCESS : CommandStatus::FAILURE;
    }
}
