<?php
/**
 * Command to Update Ryft payment data for active subscriptions by retrieving customer_id and payment_id from Ryft sessions
 * @author Ashok Basnet <ashok.basnet@mtc.co.uk>
 * @package MtcPharmacy\Subscriptions\Console\Commands
 * @date 19/03/2025
 */

namespace MtcPharmacy\Subscriptions\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Mtc\Plugins\RyftPay\Classes\RyftPay;
use Mtc\Plugins\RyftPay\Classes\RyftPayment;
use MtcPharmacy\Subscriptions\Classes\Subscription;

class UpdateRyftPaymentDataCommand extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'subscriptions:update-ryft-payment-data {--dry-run : Run without making changes}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Update Ryft payment data for subscriptions by retrieving customer_id and payment_id from Ryft sessions';

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

    /**
     * Execute the console command.
     *
     * @return int
     */
    public function handle()
    {
        $this->info('Starting to update Ryft payment data for active subscriptions...');

        $isDryRun = $this->option('dry-run');
        if ($isDryRun) {
            $this->warn('DRY RUN MODE: No database changes will be made');
        }

        // Get active subscriptions with previous_payment_id that need updating
        $subscriptions = Subscription::where('status', 'active')
            ->whereNotNull('previous_payment_id')
            ->get();

        $this->info("Found {$subscriptions->count()} active subscriptions with previous_payment_id");

        $updatedCount = 0;
        $skippedCount = 0;
        $errorCount = 0;

        foreach ($subscriptions as $subscription) {
            try {
                $this->info("Processing subscription #{$subscription->id}");

                // Check if there's already a Ryft payment record for this order
                $existingPayment = RyftPayment::where('remote_id', $subscription->previous_payment_id)
                    ->where('status', RyftPayment::STATUS_PAID)->first();

                if ($existingPayment) {
                    // Check if the payment record needs updating
                    if ($existingPayment->payment_method_id || $existingPayment->customer_id) {
                        $this->info("Payment record for subscription #{$subscription->id} already has payment data, skipping");
                        $skippedCount++;
                        continue;
                    }

                    // We have a payment record but it's missing data
                    $this->info("Updating existing payment record for subscription #{$subscription->id}");

                    $ryftPay = new RyftPay();
                    $paymentData = $ryftPay->getPaymentSession($existingPayment);

                    if (!$paymentData) {
                        $this->warn("Could not retrieve payment data for payment ID {$subscription->previous_payment_id}, skipping");
                        $skippedCount++;
                        continue;
                    }

                    if (!$isDryRun) {
                        $existingPayment->customer_id = $paymentData['customerDetails']['id'] ?? null;
                        $existingPayment->payment_method_id = $paymentData['paymentMethod']['tokenizedDetails']['id'] ?? null;
                        $existingPayment->save();

                        $this->info("Updated payment record for subscription #{$subscription->id} with customer_id: " . ($paymentData['customerDetails']['id'] ?? 'N/A') . ", payment_method_id: " . ($paymentData['paymentMethod']['tokenizedDetails']['id'] ?? 'N/A'));
                        $updatedCount++;
                    } else {
                        $this->info("[DRY RUN] Would update payment record for payment #{$existingPayment->remote_id} for subscription #{$subscription->id} with customer_id: " . ($paymentData['customerDetails']['id'] ?? 'N/A') . ", payment_method_id: " . ($paymentData['paymentMethod']['tokenizedDetails']['id'] ?? 'N/A'));
                        $updatedCount++;
                    }

                } else {
                    $this->info("No payment record found for subscription #{$subscription->id}, skipping");
                    $skippedCount++;
                }

            } catch (\Exception $e) {
                $this->error("Error processing subscription #{$subscription->id}: " . $e->getMessage());
                Log::error("Error in UpdateRyftPaymentDataCommand for subscription #{$subscription->id}: " . $e->getMessage());
                $errorCount++;
            }
        }

        $this->info("Completed processing {$subscriptions->count()} subscriptions");
        $this->info("Updated: $updatedCount, Skipped: $skippedCount, Errors: $errorCount");

        return 0;
    }

    /**
     * Retrieve payment data from Ryft session by payment ID
     *
     * @param string $paymentId
     * @return array|null
     */
    private function retrievePaymentDataFromRyftSession($paymentId)
    {
        try {
            // Query the Ryft API or database to retrieve session information
            $ryftSession = DB::table('ryft_sessions')
                ->where('payment_id', $paymentId)
                ->first();

            if (!$ryftSession) {
                return null;
            }

            return [
                'customer_id' => $ryftSession->customer_id ?? null,
                'payment_method_id' => $ryftSession->payment_method_id ?? null,
            ];

        } catch (\Exception $e) {
            Log::error("Error retrieving Ryft session data: " . $e->getMessage());
            return null;
        }
    }
}