<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\User;
use App\Models\Product;
use App\Models\Payment;
use App\Models\Orders;
use App\Models\Notification;
use App\Models\ShippingDetails;
use App\Models\CodPaymentRequest;
use App\Jobs\SendBuyerCODProductPurchaseEmail;
use App\Jobs\SendAdminCODProductPurchaseEmail;
use GuzzleHttp\Client;
use Illuminate\Http\Request;
use Yajra\DataTables\Facades\DataTables;
use Illuminate\Support\Facades\Gate;
use Symfony\Component\HttpFoundation\Response;

class PaymentProcessController extends Controller
{
    public function processToBuyProduct(Request $request, $user_id, $product_sku){
        if (! request()->hasValidSignature()) {
            abort(403, 'Link expired or invalid');
        }

        $orders = Orders::select('payment_id')->where('user_id', $user_id)->where('product_sku', $product_sku)->first();
        
        if(isset($orders) && !empty($orders)){
            $payment = Payment::where('id', $orders->payment_id)->first();
            
            if (isset($payment) && $payment->payment_status === 'capture') {
                return view('errors.payment-message', [
                    'message' => 'This payment link has already been used.',
                ]);
            }
        }
       
        return view('payment.payment_load',compact('user_id', 'product_sku'));
    }

    public function processToPayment(Request $request){
        $buyer_id = $request->user_id; 

        $user = User::select('first_name', 'last_name', 'email', 'country_id', 'phone')->where('id', $buyer_id)->first();
        $product = Product::select('sku', 'user_id', 'price', 'highest_bid_amount', 'commission_percentage', 'is_sell')->where('sku', $request->product_sku)->first();

        $country_details = getCountrydetailsById($user->country_id);
        $phone_code = $country_details->phone_code;

        $shipping_details = ShippingDetails::select('id', 'shipping_fee')->where(['product_sku' => $product->sku])->first();

        $client = new Client();
        $paymentData = [
            'amount' => $product->highest_bid_amount != '' ? $product->highest_bid_amount + $shipping_details->shipping_fee : $product->price + $shipping_details->shipping_fee,
            'currency' => 'BHD', 
            //'currency' => $user->user_currancy,// Change to your currency as needed
            'description' => 'Payment for Order',
            'customer' => [
                'first_name' => $user->first_name.' '.$user->last_name,
                'email' => $user->email,
            ],
            'metadata' => [ // Using metadata to store additional information
                'product_sku' => $product->sku,
                'user_id' => $request->user_id,
                'phone' => $user->phone,
                'phone_code' => $phone_code,
                'commission_percentage' => $product->commission_percentage,
                'shipping_id' => $shipping_details->id
            ],
            'source' => [
                'id' => 'src_all', // Use 'src_all' to allow all payment methods
            ],
            'redirect' => [
                'url' => route('payment.auction_payment_callback_api'), // Callback URL
            ],
        ];

        try {
            // Send the request to Tap's API
            // $api_tap_company = env('API_TAP_COMPANY');
            $environment_data = getEnvironmentData();

            $response = $client->post('https://api.tap.company/v2/charges', [
                'headers' => [
                    'Authorization' => $environment_data['API_TAP_COMPANY'],
                    'Content-Type' => 'application/json',
                ],
                'json' => $paymentData,
            ]);

            $responseBody = json_decode($response->getBody(), true);

            // Check if the response contains a payment URL
            if (isset($responseBody['transaction']['url'])) {
                $data['status'] = 1;
                $data['url'] =  $responseBody['transaction']['url'];
            }
        } catch (\Exception $e) {
            $data['status'] = 0;
        }
        
        echo json_encode($data);
    }

    public function paymentSuccess(Request $request)
    {
        return view('payment.success');
    }

    public function paymentFailed(Request $request)
    {
        return view('payment.failed');
    }

    public function transactionList(Request $request)
    {
        abort_if(Gate::denies('transaction_access'), Response::HTTP_FORBIDDEN, '403 Forbidden');

        $type = $request->type;

        if ($request->ajax()) {
            $query = Payment::query()
                ->leftJoin('users', 'users.id', '=', 'payment.user_id')
                ->leftJoin('products', 'products.sku', '=', 'payment.product_sku')
                ->select([
                    'payment.*',
                    'users.first_name',
                    'users.last_name',
                    'users.country_id',
                    'users.phone',
                    'products.name as product_name'
                ])
                ->when($type === 'online-payment', function ($q) {
                    return $q->where('payment.payment_status', 'capture');
                })
                ->when($type === 'cash-payment-requested', function ($q) {
                    return $q->where('payment.payment_status', 'pending');
                })
                ->when($type === 'cash-payment', function ($q) {
                    return $q->where('payment.payment_status', 'cash_payment')
                        ->orWhere('payment.payment_status', 'paid_on_delivery');
                })
                ->when($type === 'cash-payment-rejected', function ($q) {
                    return $q->where('payment.payment_status', 'rejected');
                });
            
            $table = Datatables::of($query);

            $table->addColumn('actions', '&nbsp;');

            $table->addColumn('actions', function ($row) use ($request) {
                $type = $request->type ?? 'online-payment';

                $status = '';
                if($type === 'cash-payment'){
                    $status = $row->payment_status;
                }

                $viewGate      = 'transaction_show';
                $editGate      = '';
                $deleteGate    = '';
                $crudRoutePart = 'transaction';

                return view('partials.datatablesActions', compact(
                    'viewGate',
                    'editGate',
                    'deleteGate',
                    'crudRoutePart',
                    'row',
                    'type',
                    'status'
                ));
            });

            $table->addColumn('id', fn($row) => $row->id ?? '');

            $table->addColumn('buyer_name', function ($row) {
                return trim(($row->first_name ?? '') . ' ' . ($row->last_name ?? ''));
            });

            $table->addColumn('mobile_number', function ($row) {
                $country_details = getCountrydetailsById($row->country_id);
                
                $mobile_number = '';
                if(isset($country_details->top_level_domain)){
                    $mobile_number = '<span class="d-flex" style="width: max-content;">';
                        $mobile_number .= sprintf('<img src="%s/uploads/flags/%s.png"> %s (+%s)', env('app_url'), $country_details->top_level_domain, '&nbsp;', $country_details->phone_code).' '.$row->phone;
                    $mobile_number .= '</span>';
                }

                return $mobile_number;
            });

            $table->addColumn('order_id', fn($row) => $row->order_id ?? '');
            $table->addColumn('amount', fn($row) => 'BHD '.number_format($row->amount, 2) ?? '');
            
            $table->addColumn('payment_status', function ($row) {
                return match ($row->payment_status) {
                    'paid_on_delivery' => 'Paid on Delivery',
                    'cash_payment'     => 'Cash Payment',
                    default            => ucfirst(str_replace('_', ' ', $row->payment_status ?? '')),
                };
            });
            
            // $table->addColumn('payment_status', fn($row) => $row->payment_status ?? '');
            // $table->addColumn('order_status', fn($row) => $row->order_status ?? '');
            $table->addColumn('note', fn($row) => $row->note ?? '');

            $table->addColumn('created_at', function ($row) {
                return $row->created_at ? date('d-m-Y H:i', strtotime($row->created_at)) : '';
            });

            // Fix: Make search work for buyer_name
            $table->filter(function ($query) use ($request) {
                if ($request->search['value']) {
                    $search = strtolower($request->search['value']);
                    $query->where(function ($q) use ($search) {
                        $q->whereRaw('LOWER(payment.id) LIKE ?', ["%{$search}%"])
                        ->orWhereRaw('LOWER(users.first_name) LIKE ?', ["%{$search}%"])
                        ->orWhereRaw('LOWER(users.last_name) LIKE ?', ["%{$search}%"])
                        ->orWhereRaw('LOWER(CONCAT(users.first_name, " ", users.last_name)) LIKE ?', ["%{$search}%"])
                        ->orWhereRaw('LOWER(payment.order_id) LIKE ?', ["%{$search}%"])
                        ->orWhereRaw('LOWER(payment.amount) LIKE ?', ["%{$search}%"])
                        ->orWhereRaw('LOWER(payment.payment_status) LIKE ?', ["%{$search}%"])
                        ->orWhereRaw('LOWER(payment.order_status) LIKE ?', ["%{$search}%"])
                        ->orWhereRaw('LOWER(payment.created_at) LIKE ?', ["%{$search}%"]);
                    });
                }
            });

            $table->rawColumns(['actions', 'mobile_number']);

            return $table->make(true);
        }

        return view('admin.transaction.index', compact('type'));
    }

    public function updatePaidOnDelivery(Request $request)
    {
        $payment = Payment::find($request->payment_id);
        $payment->payment_status = $request->status;
        $payment->note = $request->note;
        $payment->save();

        if($request->status == 'cash_payment' || $request->status == 'paid_on_delivery'){
            $message = "Your payment for the product purchased via '".ucwords($request->status)."' has been successfully received. Thank you for completing the transaction.";
        } else {
            $message = "We regret to inform you that your payment for the product has been rejected. Please contact our support team for further assistance or try an alternative payment method.";

            // Get all orders for this payment
            $orders = Orders::where('payment_id', $request->payment_id)->get();

            foreach ($orders as $order) {
                // Lock product row for safety
                $product = Product::where('sku', $order->product_sku)->lockForUpdate()->first();

                if (!$product) {
                    continue;
                }

                /* ================= AUCTION PRODUCT ================= */
                if ($product->product_type == 1) {
                    $product->is_sell = 1;
                    $product->save();

                    $shippingDetails = ShippingDetails::select('id', 'shipping_fee')->where(['product_sku' => $product->sku])->first();

                    $shippingFee = floatval($shippingDetails->shipping_fee ?? 0);
                    $baseAmount = $product->highest_bid_amount != ''
                                ? floatval($product->highest_bid_amount)
                                : floatval($product->price);

                    $amount = $baseAmount + $shippingFee;

                    // Commission
                    $commissionPercentage = floatval($product->commission_percentage ?? 0);
                    $commissionAmount = ($amount * $commissionPercentage) / 100;
                    $walletAmount = $amount - $commissionAmount;

                    // Seller
                    $seller = User::lockForUpdate()->find($product->user_id);

                    if (!$seller) {
                        return;
                    }

                    // REVERSE THE AMOUNT
                    $seller->pending_balance = max(0, $seller->pending_balance - $walletAmount);
                    $seller->total_earnings = max(0, $seller->total_earnings - $walletAmount);

                    $seller->save();
                }

                /* ================= SELL PRODUCT ================= */
                if ($product->product_type == 2) {
                    $remainingQty = $product->product_quantity + $order->quantity;
                    $product->product_quantity = max(0, $remainingQty);
                    $product->save();

                    // Commission & price
                    $commission_percentage = floatval($product->commission_percentage ?? 0);
                    $price = floatval($product->price ?? 0);

                    // Wallet calculation
                    $wallet_amount = $price - (($price * $commission_percentage) / 100);

                    // Seller
                    $seller = User::find($product->user_id);

                    if ($seller) {
                        $seller->pending_balance = $seller->pending_balance + $wallet_amount;
                        $seller->total_earnings = $seller->total_earnings + $wallet_amount;
                        $seller->save();
                    }
                }

                if($request->status == 'cash_payment' || $request->status == 'paid_on_delivery'){
                    $seller_message = "Payment ".ucwords($request->status)." has been completed for {$product->name}. Kindly prepare and upload the shipment receipt to proceed with delivery.";
                } else {
                    $seller_message = "The buyer’s payment for the product {$product->name} has been rejected. Please wait for the buyer to retry the payment or for further updates from the admin.";
                }

                Notification::create([
                    'user_id' => $product->user_id,
                    'title' => "Payment Rejected",
                    'message' => $seller_message,
                ]);

                pushNotification($product->user_id, $seller_message);
            }
        }

        Notification::create([
            'user_id' => $payment->user_id,
            'title' => "Payment Received",
            'message' => $message,
        ]);
        
        pushNotification($payment->user_id, $message);

        return response()->json(['status' => 'success', 'message' => 'Payment status updated successfully.']);
    }

    public function show(Request $request, $id)
    {
        abort_if(Gate::denies('transaction_show'), Response::HTTP_FORBIDDEN, '403 Forbidden');

        return view('admin.transaction.show');
    }

    public function orderDetailsShow(Request $request, $id)
    {
        if ($request->ajax()) {
            $query = Orders::with(['user:id,address,new_address', 'product', 'shippingDetails'])->where('payment_id', $id);
            $table = Datatables::of($query);

            $table->addColumn('id', function ($row) {
                return $row->id ? $row->id : '';
            });

            $table->addColumn('product_name', function ($row) {
                return $row->product ? $row->product->name : '';
            });
        
            $table->addColumn('product_sku', function ($row) {
                return $row->product_sku ? $row->product_sku : '';
            });

            $table->addColumn('price', function ($row) {
                return $row->price ? 'BHD '.number_format($row->price, 2) : '';
            });

            $table->addColumn('shipping_country', function ($row) {
                if(isset($row->shippingDetails)){
                    $country_details = getCountrydetailsById($row->shippingDetails->country_id);
                    
                    if(isset($country_details->top_level_domain)){
                        return sprintf('<span class="d-flex"><img src="%s/uploads/flags/%s.png"> %s </span>', env('app_url'), $country_details->top_level_domain, '&nbsp;'.$country_details->country_name);
                    } else {
                        return;
                    }
                } else {
                    return;
                }
            });

            $table->addColumn('shipping_duration_day', function ($row) {
                return $row->shippingDetails ? $row->shippingDetails->duration_day : '';
            });

            $table->addColumn('shipping_fee', function ($row) {
                return $row->shippingDetails ? $row->shippingDetails->shipping_fee : '';
            });

            $table->addColumn('shipping_address', function ($row) {
                if (!empty($row->user)) {
                    return !empty($row->user->new_address)
                        ? $row->user->new_address
                        : ($row->user->address ?? '');
                }

                return;
            });

            $table->addColumn('created_at', function ($row) {
                return isset($row->created_at) ? $row->created_at->format('d-m-Y H:i') : ' ';
            });

            $table->rawColumns(['shipping_country']);

            return $table->make(true);
        }

        return view('admin.transaction.show');
    }

    public function transactionDestroy(Request $request, $id){
        abort_if(Gate::denies('transaction_delete'), Response::HTTP_FORBIDDEN, '403 Forbidden');
        
        Orders::where('payment_id', $id)->delete();
        Payment::where('id', $id)->delete();
        
        return back()->with('success', trans('global.transaction_delete'));
    }
}