<?php

namespace App\Http\Controllers;

use App\Models\Payment;
use App\Models\Plan;
use App\Models\Subscription;
use App\Models\AffiliateSetting;
use App\Services\AffiliateService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Midtrans\Config;
use Midtrans\Snap;

class PaymentController extends Controller
{
    public function __construct()
    {
        // Set Midtrans configuration
        Config::$serverKey = config('services.midtrans.server_key');
        Config::$isProduction = config('services.midtrans.is_production', false);
        Config::$isSanitized = true;
        Config::$is3ds = true;
    }

    public function createPayment(Request $request)
    {
        $request->validate([
            'plan_id' => 'required|exists:plans,id',
            'referral_code' => 'nullable|string|max:255',
        ]);

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

        // Check if user already has active subscription
        $existingSubscription = $user->subscriptions()->where('status', 'active')->first();
        if ($existingSubscription) {
            return response()->json(['message' => 'User already has an active subscription'], 400);
        }

        // Handle referral code
        $transactionReferrerId = null;
        $referrer = null;
        $affiliateSettings = AffiliateSetting::getSettings();
        if ($request->referral_code) {
            $referrer = \App\Models\User::where('affiliate_code', $request->referral_code)->first();
            if (!$referrer) {
                return response()->json(['error' => 'Invalid referral code'], 400);
            }
            if (!$referrer->is_affiliate) {
                return response()->json(['error' => 'Referral code is not from an active affiliate'], 400);
            }

            // Prevent user from using their own referral code
            if ($referrer->id === $user->id) {
                return response()->json(['error' => 'Anda tidak bisa menggunakan kode referral Anda sendiri'], 400);
            }

            // Set referrer_id if not already set
            if (!$user->referrer_id) {
                $user->referrer_id = $referrer->id;
                $user->save();
            }
            $transactionReferrerId = $referrer->id;
        }

        // Apply affiliate discount if applicable (based on provided referral code or existing)
        $amount = $plan->discounted_price ?? $plan->price;
        $appliedReferrer = $referrer ?? ($user->referrer_id ? $user->referrer : null);
        if ($appliedReferrer && $appliedReferrer->is_affiliate && $affiliateSettings) {
            $discountPercentage = $affiliateSettings->discount_percentage;
            $amount = $amount * (1 - ($discountPercentage / 100));
        }

        // Create subscription
        $subscription = Subscription::create([
            'user_id' => $user->id,
            'plan_id' => $plan->id,
            'status' => 'pending', // Set to pending until payment is successful
            'start_date' => now(),
            'end_date' => now()->addMonth(), // Assuming monthly subscription
        ]);

        // Create payment record
        $payment = Payment::create([
            'user_id' => $user->id,
            'subscription_id' => $subscription->id,
            'midtrans_transaction_id' => 'temp-' . time() . '-' . $user->id,
            'amount' => $amount,
            'status' => 'pending',
        ]);

        // Prepare Midtrans transaction data
        $transactionDetails = [
            'order_id' => $payment->midtrans_transaction_id,
            'gross_amount' => $payment->amount,
        ];

        $customerDetails = [
            'first_name' => $user->name,
            'email' => $user->email,
        ];

        $itemDetails = [
            [
                'id' => $plan->id,
                'price' => $payment->amount,
                'quantity' => 1,
                'name' => $plan->name,
            ],
        ];

        $transaction = [
            'transaction_details' => $transactionDetails,
            'customer_details' => $customerDetails,
            'item_details' => $itemDetails,
        ];

        try {
            $snapToken = Snap::getSnapToken($transaction);

            // Update payment with real transaction id
            $payment->update(['midtrans_transaction_id' => $transactionDetails['order_id']]);

            return response()->json([
                'snap_token' => $snapToken,
                'payment_id' => $payment->id,
            ]);
        } catch (\Exception $e) {
            Log::error('Midtrans error: ' . $e->getMessage());
            $payment->update(['status' => 'failed']);
            return response()->json(['message' => 'Payment creation failed'], 500);
        }
    }

    public function handleWebhook(Request $request)
    {
        $payload = $request->all();

        Log::info('Midtrans Webhook', $payload);

        $orderId = $payload['order_id'];
        $transactionStatus = $payload['transaction_status'];
        $fraudStatus = $payload['fraud_status'] ?? null;

        $payment = Payment::where('midtrans_transaction_id', $orderId)->first();

        if (!$payment) {
            Log::error('Payment not found for order_id: ' . $orderId);
            return response()->json(['message' => 'Payment not found'], 404);
        }

        // Update payment status based on transaction status
        if ($transactionStatus == 'capture') {
            if ($fraudStatus == 'challenge') {
                $payment->update(['status' => 'pending']);
            } else if ($fraudStatus == 'accept') {
                $payment->update(['status' => 'success']);
                // Activate subscription if not already
                if ($payment->subscription) {
                    try {
                        $payment->subscription->update(['status' => 'active']);
                        Log::info('Subscription activated for payment ID: ' . $payment->id);
                    } catch (\Exception $e) {
                        Log::error('Failed to activate subscription for payment ID: ' . $payment->id . ' - ' . $e->getMessage());
                    }
                } else {
                    Log::error('Subscription not found for payment ID: ' . $payment->id);
                }

                // Credit affiliate commission
                \App\Services\AffiliateService::processSubscriptionCommission($payment);
            }
        } else if ($transactionStatus == 'settlement') {
            $payment->update(['status' => 'success']);
            if ($payment->subscription) {
                try {
                    $payment->subscription->update(['status' => 'active']);
                    Log::info('Subscription activated for payment ID: ' . $payment->id);
                } catch (\Exception $e) {
                    Log::error('Failed to activate subscription for payment ID: ' . $payment->id . ' - ' . $e->getMessage());
                }
            } else {
                Log::error('Subscription not found for payment ID: ' . $payment->id);
            }

            // Credit affiliate commission
            \App\Services\AffiliateService::processSubscriptionCommission($payment);
        } else if ($transactionStatus == 'deny' || $transactionStatus == 'expire' || $transactionStatus == 'cancel') {
            $payment->update(['status' => 'failed']);
            if ($payment->subscription) {
                try {
                    $payment->subscription->update(['status' => 'canceled']);
                    Log::info('Subscription canceled for payment ID: ' . $payment->id);
                } catch (\Exception $e) {
                    Log::error('Failed to cancel subscription for payment ID: ' . $payment->id . ' - ' . $e->getMessage());
                }
            } else {
                Log::error('Subscription not found for payment ID: ' . $payment->id);
            }
        }

        return response()->json(['message' => 'Webhook processed']);
    }

    public function getPlans()
    {
        $plans = Plan::all();
        return response()->json($plans);
    }

    public function checkStatus(Request $request, $paymentId)
    {
        $payment = Payment::findOrFail($paymentId);

        // Ensure user owns this payment
        if ($payment->user_id !== auth()->id()) {
            return response()->json(['message' => 'Unauthorized'], 403);
        }

        try {
            // Get status from Midtrans
            $status = \Midtrans\Transaction::status($payment->midtrans_transaction_id);

            // Update payment status based on Midtrans response
            $transactionStatus = $status->transaction_status ?? 'unknown';

            if ($transactionStatus == 'capture' || $transactionStatus == 'settlement') {
                if ($payment->status !== 'success') {
                    $payment->update(['status' => 'success']);
                    // Activate subscription if not already
                    if ($payment->subscription) {
                        $payment->subscription->update(['status' => 'active']);
                        Log::info('Subscription activated via polling for payment ID: ' . $payment->id);
                    }

                    // Credit affiliate commission
                    \App\Services\AffiliateService::processSubscriptionCommission($payment);
                }
            } elseif ($transactionStatus == 'deny' || $transactionStatus == 'expire' || $transactionStatus == 'cancel') {
                if ($payment->status !== 'failed') {
                    $payment->update(['status' => 'failed']);
                    if ($payment->subscription) {
                        $payment->subscription->update(['status' => 'canceled']);
                        Log::info('Subscription canceled via polling for payment ID: ' . $payment->id);
                    }
                }
            } elseif ($transactionStatus == 'pending') {
                $payment->update(['status' => 'pending']);
            }

            return response()->json([
                'status' => $payment->status,
                'midtrans_status' => $transactionStatus,
                'payment' => $payment
            ]);

        } catch (\Exception $e) {
            Log::error('Midtrans status check error: ' . $e->getMessage());

            // Jika Midtrans API mengembalikan error (misal transaksi tidak ditemukan),
            // kembalikan status pembayaran saat ini tanpa error 500
            return response()->json([
                'status' => $payment->status,
                'midtrans_status' => 'unknown',
                'payment' => $payment,
                'error' => $e->getMessage()
            ]);
        }
    }

    public function getSubscriptions()
    {
        $user = auth()->user();
        $subscriptions = $user->subscriptions()->with('plan')->get();
        return response()->json($subscriptions);
    }

    public function validateReferral(Request $request)
    {
        $request->validate([
            'plan_id' => 'required|exists:plans,id',
            'referral_code' => 'required|string|max:255',
        ]);

        $user = auth()->user();
        $plan = Plan::findOrFail($request->plan_id);
        $referrer = \App\Models\User::where('affiliate_code', $request->referral_code)->first();

        if (!$referrer || !$referrer->is_affiliate) {
            return response()->json([
                'valid' => false,
                'message' => 'Invalid referral code'
            ], 400);
        }

        // Prevent user from using their own referral code
        if ($referrer->id === $user->id) {
            return response()->json([
                'valid' => false,
                'message' => 'Anda tidak bisa menggunakan kode referral Anda sendiri'
            ], 400);
        }

        $affiliateSettings = AffiliateSetting::getSettings();
        $originalPrice = $plan->discounted_price ?? $plan->price;
        $discountPercentage = $affiliateSettings->discount_percentage;
        $discountedPrice = $originalPrice * (1 - ($discountPercentage / 100));

        return response()->json([
            'valid' => true,
            'original_price' => $originalPrice,
            'discounted_price' => $discountedPrice,
            'discount_percentage' => $discountPercentage,
        ]);
    }


}
