<?php

namespace App\Livewire;

use App\Enums\OrderStatus;
use App\Models\Campaign;
use App\Models\Order;
use App\Models\Price;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Rule;
use Livewire\Attributes\Computed;
use Livewire\Attributes\On;
use Livewire\Component;

class ShowCampaign extends Component
{
    public Campaign $campaign;

    public $prices = [];

    public $currentStep = 1;

    public $totalSteps = 4;

    // Step 1 data
    public $selectedPriceId;

    // Step 2 data
    public $firstName = '';
    public $lastName = '';

    public $email = '';

    // Step 3 & 4 data
    public $paymentMethod = 'paypal';

    public $isProcessing = false;

    public $orderId;

    public $errorMessage = '';

    public $redirectUrl = null;

    public function mount(): void
    {
        $this->prices = $this->campaign->priceActives;

        $this->selectedPriceId = $this->prices->where('is_default', 1)->first()?->id ?? $this->prices->first()?->id;
    }

    // Step Navigation
    public function nextStep()
    {
        if ($this->currentStep === 1) {
            $this->validate([
                'selectedPriceId' => [
                    'required',
                    Rule::exists('prices', 'id')
                        ->where('is_active', true)
                        ->where('campaign_id', $this->campaign->id),
                ],
            ]);
        }

        if ($this->currentStep === 2) {
            $this->validate([
                'firstName' => 'required|min:3|max:100',
                'lastName' => 'required|min:3|max:100',
                'email' => 'required|email|max:100',
            ]);
        }

        if ($this->currentStep < $this->totalSteps) {
            $this->currentStep++;
        }
    }

    public function prevStep()
    {
        if ($this->currentStep > 1) {
            $this->currentStep--;
        }
    }

    #[Computed]
    public function selectedPrice(): Price
    {
        return Price::find($this->selectedPriceId);
    }

    #[Computed]
    public function amount(): int
    {
        return $this->selectedPrice->amount;
    }

    #[Computed]
    public function stepPercentage()
    {
        return ($this->currentStep / $this->totalSteps) * 100;
    }

    public function initializePayment(): void
    {
        $this->validate([
            'name' => 'required|string|min:3|max:255',
            'email' => 'required|email|max:255',
            'selectedPriceId' => 'required|exists:prices,id',
        ]);

        try {
            $this->isProcessing = true;

            $order = Order::create([
                'price_id' => $this->selectedPriceId,
                'name' => $this->name,
                'email' => $this->email,
                'status' => OrderStatus::PENDING,
                'amount' => (int) $this->selectedPrice->amount,
                'currency' => $this->selectedPrice->currency,
            ]);

            $this->orderId = $order->id;

            $this->dispatch('init-paypal', [
                'orderId' => $order->id,
                'amount' => $order->amount,
                'itemName' => $this->selectedPrice->name,
                'userName' => $this->name,
                'userEmail' => $this->email,
            ]);
        } catch (\Exception $e) {
            Log::error('Error creating order: ' . $e->getMessage());
            $this->addError('payment', 'Failed to initialize payment. Please try again.');
            $this->isProcessing = false;
        }
    }

    #[On('capture-paypal-payment')]
    public function capturePayPalPayment($data)
    {
        try {
            $this->isProcessing = true;

            $order = Order::create([
                'price_id' => $this->selectedPriceId,
                'name' => $this->firstName . ' ' . $this->lastName,
                'email' => $this->email,
                'status' => OrderStatus::PENDING,
                'amount' => (int) $this->selectedPrice->amount,
                'currency' => $this->selectedPrice->currency,
            ]);

            $transactions = collect();
            $successfulCapture = false;

            foreach ($data['purchase_units'] ?? [] as $purchaseUnit) {
                foreach ($purchaseUnit['payments']['captures'] ?? [] as $capture) {
                    $isSuccessful = $capture['status'] === 'COMPLETED';
                    $transactions->push([
                        'success' => $isSuccessful,
                        'type' => 'capture',
                        'method' => 'paypal',
                        'amount' => (int) ($capture['amount']['value'] * 100), // Convert to cents
                        'reference' => $capture['id'],
                        'status' => $capture['status'],
                        'card_type' => 'paypal',
                        'captured_at' => now()->parse($capture['create_time']),
                        'meta' => $capture,
                    ]);

                    if ($isSuccessful) {
                        $successfulCapture = true;
                    }
                }
            }

            if ($transactions->isNotEmpty()) {
                $order->transactions()->createMany($transactions->toArray());
            }

            $status = $successfulCapture ? OrderStatus::COMPLETED : OrderStatus::FAILED;
            $order->update(['status' => $status]);

            $this->isProcessing = false;

            $url = $order->price->campaign->redirect_url ?? '/';

            return redirect($url);

        } catch (\Exception $e) {
            Log::error('Error capturing PayPal payment: ' . $e->getMessage());
            $this->isProcessing = false;
            $this->addError('payment', 'Failed to process payment. Please try again.');

            if (isset($order)) {
                $order->update(['status' => OrderStatus::FAILED]);
            }
        }
    }

    public function render()
    {
        if ($this->redirectUrl) {
            return view('livewire.show-campaign')
                ->with('redirectScript', true)
                ->with('redirectUrl', $this->redirectUrl);
        }

        return view('livewire.show-campaign')
            ->layoutData([
                'title' => $this->campaign->data_attribute['name'],
                'description' => $this->campaign->data_attribute['description'],
            ])
            ->layout('components.layouts.rapro');
    }
}
