<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Services\StripeService;
use App\Models\Transaction;
use App\Models\UserPlan;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Exception;

class PaymentController extends Controller
{
    protected $stripeService;

    public function __construct(StripeService $stripeService)
    {
        $this->stripeService = $stripeService;
    }

    /**
     * Create payment intent
     */
    public function createPaymentIntent(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'amount' => 'required|numeric|min:1',
                'currency' => 'required|string|max:3',
                'plan_id' => 'sometimes|exists:user_plans,id',
            ]);

            if ($validator->fails()) {
                return response()->json([
                    'success' => false,
                    'message' => 'Validation error',
                    'errors' => $validator->errors(),
                ], 422);
            }

            $user = auth()->user();
            $metadata = [];

            if ($request->has('plan_id')) {
                $plan = UserPlan::findOrFail($request->plan_id);
                $metadata['plan_id'] = $plan->id;
                $metadata['plan_name'] = $plan->name;
            }

            $paymentIntent = $this->stripeService->createPaymentIntent(
                $request->amount,
                $request->currency,
                $user,
                $metadata
            );

            // Create transaction record
            $transaction = Transaction::create([
                'transaction_id' => 'txn_' . uniqid(),
                'order_id' => 'ord_' . uniqid(),
                'gateway_payment_id' => $paymentIntent->id,
                'user_id' => $user->id,
                'entity_type' => $request->has('plan_id') ? 'subscription' : 'payment',
                'entity_id' => $request->plan_id ?? null,
                'gateway_slug' => 'stripe',
                'amount' => $request->amount,
                'currency' => strtoupper($request->currency),
                'status' => 'pending',
                'payment_status' => $paymentIntent->status,
                'metadata' => $metadata,
            ]);

            return response()->json([
                'success' => true,
                'data' => [
                    'payment_intent' => [
                        'id' => $paymentIntent->id,
                        'client_secret' => $paymentIntent->client_secret,
                        'amount' => $paymentIntent->amount / 100,
                        'currency' => $paymentIntent->currency,
                        'status' => $paymentIntent->status,
                    ],
                    'transaction_id' => $transaction->transaction_id,
                ],
            ]);
        } catch (Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Error creating payment intent',
                'error' => $e->getMessage(),
            ], 500);
        }
    }

    /**
     * Create subscription
     */
    public function createSubscription(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'plan_id' => 'required|exists:user_plans,id',
                'payment_method_id' => 'sometimes|string',
            ]);

            if ($validator->fails()) {
                return response()->json([
                    'success' => false,
                    'message' => 'Validation error',
                    'errors' => $validator->errors(),
                ], 422);
            }

            $user = auth()->user();
            $plan = UserPlan::findOrFail($request->plan_id);

            $result = $this->stripeService->createSubscription(
                $user,
                $plan,
                $request->payment_method_id
            );

            return response()->json([
                'success' => true,
                'message' => 'Subscription created successfully',
                'data' => [
                    'subscription' => $result['local_subscription'],
                    'stripe_subscription_id' => $result['stripe_subscription']->id,
                    'status' => $result['stripe_subscription']->status,
                ],
            ]);
        } catch (Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Error creating subscription',
                'error' => $e->getMessage(),
            ], 500);
        }
    }

    /**
     * Get transaction history
     */
    public function getTransactions(Request $request)
    {
        try {
            $user = auth()->user();

            $transactions = Transaction::where('user_id', $user->id)
                ->with(['gateway', 'paymentMethod'])
                ->orderBy('created_at', 'desc')
                ->paginate($request->per_page ?? 20);

            return response()->json([
                'success' => true,
                'data' => $transactions,
            ]);
        } catch (Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Error fetching transactions',
                'error' => $e->getMessage(),
            ], 500);
        }
    }

    /**
     * Get single transaction
     */
    public function getTransaction($transactionId)
    {
        try {
            $user = auth()->user();

            $transaction = Transaction::where('user_id', $user->id)
                ->where('transaction_id', $transactionId)
                ->with(['gateway', 'paymentMethod'])
                ->firstOrFail();

            return response()->json([
                'success' => true,
                'data' => $transaction,
            ]);
        } catch (Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Transaction not found',
                'error' => $e->getMessage(),
            ], 404);
        }
    }

    /**
     * Request refund
     */
    public function requestRefund(Request $request, $transactionId)
    {
        try {
            $user = auth()->user();

            $transaction = Transaction::where('user_id', $user->id)
                ->where('transaction_id', $transactionId)
                ->firstOrFail();

            if (!$transaction->canBeRefunded()) {
                return response()->json([
                    'success' => false,
                    'message' => 'Transaction cannot be refunded',
                ], 400);
            }

            $refund = $this->stripeService->createRefund(
                $transaction->gateway_payment_id,
                $request->amount ?? null
            );

            $transaction->update([
                'refund_status' => $request->amount ? 'partial' : 'full',
                'refunded_at' => now(),
            ]);

            return response()->json([
                'success' => true,
                'message' => 'Refund processed successfully',
                'data' => [
                    'refund_id' => $refund->id,
                    'amount' => $refund->amount / 100,
                    'status' => $refund->status,
                ],
            ]);
        } catch (Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Error processing refund',
                'error' => $e->getMessage(),
            ], 500);
        }
    }
}
