<?php

namespace Mtc\Modules\B2B\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\DB;
use Mtc\Modules\B2B\Models\TradeCustomer;
use Mtc\Modules\B2B\Services\AccountPaymentService;

class TradeAccountController extends Controller
{
    public function __construct(private AccountPaymentService $paymentService) {}

    /**
     * Show outstanding (unpaid) account orders for the logged-in trade customer.
     */
    public function outstandingOrders(Request $request)
    {
        $tradeCustomer = $this->tradeCustomer($request);

        $orders = $tradeCustomer->accountOrders()
            ->unpaid()
            ->with('order')
            ->orderBy('created_at', 'desc')
            ->get();

        return template('b2b/account_orders.twig', [
            'page_meta'         => ['title' => 'Account Orders'],
            'trade_customer'    => $tradeCustomer,
            'orders'            => $orders,
            'total_outstanding' => $orders->sum('amount_due'),
        ]);
    }

    /**
     * Handle "Pay on Account" at checkout — create order without payment.
     */
    public function payOnAccount(Request $request)
    {
        $tradeCustomer = $this->tradeCustomer($request);

        // Retrieve the existing order created by basket_overview.php
        $orderId = $request->input('order_id');
        if (!$orderId) {
            return redirect('/shop/checkout/basket_overview.php')->with('error', 'Missing order.');
        }

        $order = \Mtc\Shop\Order::find($orderId);
        if (!$order || (int) $order->member !== (int) $tradeCustomer->member_id) {
            return redirect('/shop/checkout/basket_overview.php')->with('error', 'Invalid order.');
        }

        return DB::transaction(function () use ($order, $tradeCustomer) {
            // Create account order with PO number
            $accountOrder = $this->paymentService->createAccountOrder($order, $tradeCustomer);

            // Mark the order as paid so it moves to "Processing" in admin
            $legacyOrder = new \Order($order->id);
            $legacyOrder->markPaid('account');

            // Legacy shop (order_complete.php) reads $_SESSION directly — this is intentional
            $_SESSION['order_id'] = $order->id;

            // Send confirmation emails
            $twig = app('twig');

            $customerHtml = $twig->render('b2b/emails/account_order_placed.twig', [
                'account_order'  => $accountOrder,
                'order'          => $order,
                'trade_customer' => $tradeCustomer,
                'member'         => $tradeCustomer->member,
            ]);
            \email(
                $tradeCustomer->member->email,
                'Order Confirmation - ' . $accountOrder->po_number,
                $customerHtml
            );

            $adminHtml = $twig->render('b2b/emails/account_order_placed_admin.twig', [
                'account_order'  => $accountOrder,
                'order'          => $order,
                'trade_customer' => $tradeCustomer,
                'member'         => $tradeCustomer->member,
            ]);
            \email(
                config('site.from_email'),
                'New Account Order - ' . $accountOrder->po_number,
                $adminHtml
            );

            // Legacy basket clearing — shop/checkout/basket_overview.php reads $_SESSION['basket_id']
            $_SESSION['basket_id'] = '';

            return redirect('/shop/checkout/order_complete.php');
        });
    }

    /**
     * Initiate payment for selected outstanding orders.
     */
    public function payOrders(Request $request)
    {
        $tradeCustomer = $this->tradeCustomer($request);

        $orderIds = $request->input('order_ids', []);
        if (empty($orderIds)) {
            return redirect('/trade/account/orders')->with('error', 'Please select at least one order to pay.');
        }

        // Validate all submitted IDs belong to this customer
        $validIds = $tradeCustomer->accountOrders()
            ->unpaid()
            ->whereIn('id', $orderIds)
            ->pluck('id')
            ->all();

        if (empty($validIds)) {
            return redirect('/trade/account/orders')->with('error', 'Please select at least one order to pay.');
        }

        $total = $this->paymentService->calculateTotal($validIds, $tradeCustomer);

        if ($total <= 0) {
            return redirect('/trade/account/orders')->with('error', 'Invalid order selection.');
        }

        // Store selected order IDs in session for callback
        session(['b2b_paying_order_ids' => $validIds]);
        session(['b2b_paying_total' => $total]);

        return template('b2b/pay_orders.twig', [
            'page_meta'      => ['title' => 'Pay Account Orders'],
            'trade_customer' => $tradeCustomer,
            'order_ids'      => $validIds,
            'total'          => $total,
        ]);
    }

    /**
     * Handle payment gateway redirect callback for account order payments.
     *
     * @todo Implement gateway-specific signature verification before this goes live.
     *       Each gateway (Realex, Judopay, EvoPay) provides a callback hash/signature
     *       that must be validated server-side to confirm the payment is genuine.
     *       Do NOT rely on the browser redirect alone to confirm payment success.
     */
    public function paymentCallback(Request $request)
    {
        $tradeCustomer = $this->tradeCustomer($request);

        $orderIds = session('b2b_paying_order_ids', []);

        if (empty($orderIds)) {
            return redirect('/trade/account/orders')->with('error', 'Payment session expired.');
        }

        if (!$this->verifyGatewayCallback($request)) {
            return redirect('/trade/account/orders')->with('error', 'Payment verification failed. Please contact support.');
        }

        $paymentReference = $request->input('reference', '');
        $success = $this->paymentService->markOrdersPaid($orderIds, $tradeCustomer, $paymentReference);

        session()->forget(['b2b_paying_order_ids', 'b2b_paying_total']);

        if ($success) {
            return redirect('/trade/account/orders')->with('success', 'Payment received. Your orders have been marked as paid.');
        }

        return redirect('/trade/account/orders')->with('error', 'Payment failed. Please try again.');
    }

    /**
     * Verify the payment gateway callback is legitimate.
     *
     * Gateway verification is not yet implemented.
     * This must be replaced with gateway-specific signature/hash verification
     * before the paymentCallback route can be used.
     */
    private function verifyGatewayCallback(Request $request): bool
    {
        return false;
    }

    /**
     * Retrieve the authenticated trade customer set by RequireTradeCustomer middleware.
     */
    private function tradeCustomer(Request $request): TradeCustomer
    {
        return $request->attributes->get('trade_customer');
    }
}
