<?php

namespace App\Http\Controllers;

use App\Models\Admin\Pricing;
use App\Models\Customers;
use App\Models\CustomersPlans;
use App\Models\CustomersPlansTransactions;
use App\Services\InvoiceService;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Crypt;
use Razorpay\Api\Api;

class CustomersPaymentsController extends Controller
{
    public function createOrder(Request $request)
    {
        $request->validate([
            'customer_id' => 'required|string',
            'plan_id' => 'required|string',
        ]);

        try {
            $customer_id = Crypt::decrypt($request->customer_id);
            $plan_id = Crypt::decrypt($request->plan_id);
        } catch (\Exception $e) {
            return response()->json(['error' => 'Invalid customer or plan ID.'], 400);
        }

        $plan = Pricing::find($plan_id);
        if (!$plan) {
            return response()->json(['error' => 'Plan not found.'], 404);
        }

        $api = new Api(env('RAZORPAY_KEY'), env('RAZORPAY_SECRET'));

        // Create Razorpay order
        $order = $api->order->create([
            'amount' => $plan->plan_price * 100,
            'currency' => 'INR',
            'payment_capture' => 1,
            'notes' => [
                'customer_id' => $customer_id,
                'plan_id'     => $plan_id,
            ]
        ]);

        // Save transaction in DB (only transaction, not plan yet)
        CustomersPlansTransactions::create([
            'customer_id'       => $customer_id,
            'plan_id'           => $plan_id,
            'payment_gateway'   => 'RAZOR_PAY',
            'transaction_status' => 'created',
            'gateway_order_id'  => $order['id'],
            'amount'            => $plan->plan_price,
            'currency'          => 'INR',
        ]);

        return response()->json([
            'order_id' => $order['id'],
            'amount'   => $order['amount'],
            'currency' => $order['currency'],
            'key'      => env('RAZORPAY_KEY'),
        ]);
    }

    public function verifyPayment(Request $request)
    {
        $request->validate([
            'razorpay_payment_id' => 'required|string',
            'razorpay_order_id'   => 'required|string',
            'razorpay_signature'  => 'required|string',
            'customer_id'         => 'required|string',
            'plan_id'             => 'required|string',
        ]);

        try {
            $customer_id = Crypt::decrypt($request->customer_id);
            $plan_id     = Crypt::decrypt($request->plan_id);
        } catch (\Exception $e) {
            return response()->json(['status' => 'error', 'message' => 'Invalid customer or plan ID.'], 400);
        }

        $api = new Api(env('RAZORPAY_KEY'), env('RAZORPAY_SECRET'));

        try {
            // Verify signature
            $attributes = [
                'razorpay_order_id'   => $request->razorpay_order_id,
                'razorpay_payment_id' => $request->razorpay_payment_id,
                'razorpay_signature'  => $request->razorpay_signature
            ];

            $api->utility->verifyPaymentSignature($attributes);

            // Find transaction
            $transaction = CustomersPlansTransactions::where('gateway_order_id', $request->razorpay_order_id)->first();

            if (!$transaction) {
                return response()->json([
                    'status'  => 'error',
                    'message' => 'Transaction not found.'
                ], 404);
            }

            // Update transaction
            $transaction->update([
                'transaction_status' => 'success',
                'gateway_payment_id' => $request->razorpay_payment_id,
                'gateway_signature'  => $request->razorpay_signature,
            ]);

            // Plan validity (e.g., 1 month from today)
            $start_date  = Carbon::today();
            $expiry_date = $start_date->copy()->addMonth();

            $invoice = InvoiceService::generateAndSend($transaction, $customer_id, $plan_id);

            // Create / Update customer plan
            $customerPlan = CustomersPlans::updateOrCreate(
                [
                    'customer_id' => $customer_id,
                    'plan_id'     => $plan_id,
                ],
                [
                    'transaction_id' => $transaction->id,
                    'invoice_id' => $invoice->id,
                    'plan_status'    => 'active',
                    'start_date'     => $start_date,
                    'expiry_date'    => $expiry_date,
                    'auto_renew'     => false,
                ]
            );

            $plan = Pricing::find($plan_id);
            if ($plan) {
                $sanitizedPlanName = preg_replace('/[^A-Za-z0-9_]/', '', str_replace(' ', '_', $plan->plan_name));
                Customers::where('id', $customer_id)->update([
                    'active_plan_id' => $plan_id,
                    'plan'           => $sanitizedPlanName,
                ]);
            }

            return response()->json([
                'status'       => 'success',
                'message'      => 'Payment verified successfully and invoice sent.',
                'customerPlan' => $customerPlan,
                'invoice_id'    => $invoice->enc_id,
                'invoice_link'  => route('invoice.download', $invoice->enc_id),
            ]);
        } catch (\Exception $e) {
            // Mark transaction failed if exists
            $transaction = CustomersPlansTransactions::where('gateway_order_id', $request->razorpay_order_id)->first();
            if ($transaction) {
                $transaction->update(['transaction_status' => 'failed']);
            }

            return response()->json([
                'status'  => 'error',
                'message' => 'Payment verification failed.',
                'error'   => $e->getMessage()
            ], 400);
        }
    }
}
