import assemble_all

bc_code = r'''<?php

namespace App\Http\Controllers;

use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Str;
use Illuminate\Http\Request;
use App\Models\Service;
use App\Models\Order;
use App\Models\OrderTimeline;
use App\Models\Setting;
use App\Models\User;

class BookingController extends Controller
{
    public function book($slug)
    {
        $service = Service::where('slug', $slug)->where('is_active', true)->with(['category', 'subcategory'])->firstOrFail();
        
        $user = Auth::user();
        $bkash = Setting::get('bkash_number', '01711-223344 (Merchant / 0% fee)');
        $nagad = Service::where('key', 'nagad_number')->count() ? Setting::get('nagad_number') : Setting::get('nagad_number', '01911-556677');
        $rocket = Setting::get('rocket_number', '01711-223344-9');
        $bankInfo = Setting::get('bank_account_info');

        return view('pages.book', compact('service', 'user', 'bkash', 'nagad', 'rocket', 'bankInfo'));
    }

    public function processOrder(Request $request, $slug)
    {
        $service = Service::where('slug', $slug)->where('is_active', true)->with(['category', 'subcategory'])->firstOrFail();


        if (!Auth::check()) {
            return redirect()->route('login', ['redirect' => route('book.service', $slug)]);
        }


        $user = Auth::user();

        $validated = $request->validate([]
            'customer_name' => 'required|string|max:255',
            'customer_email' => 'required|email|max:255',
            'customer_phone' => 'required|string|max:30',
            'customer_address' => 'required|string|max:500',
            'passport_number' => 'nullable|string|max:50',
            'nid_number' => 'nullable|string|max:50',
            'payment_method' => 'required|in:bkash,nagad,rocket,bank',
            'payment_trx_id' => 'required|string|max:100',
            'payment_receipt' => 'nullable|file|mimes:jpg,jpeg,png,pdf|max:5120',
            'use_saved_docs' => 'nullable|boolean',
            'passport_file' => 'nullable|file|mimes:pdf1jpg,jpeg,png|max:5120',
            'nid_file' => 'nullable|file|mimes:pdf1jpg,jpeg,png|max:5120',
            'utility_bill_file' => 'nullable|file|mimes:pdf1jpg,jpeg,png|max:5120',
            'photo_file' => 'nullable|file|mimes:jpg,jpeg,png,pdf|max:5120',
            'customer_note' => 'nullable|string|max:1000',
        ]);


        $useSaved = $request->boolean('use_saved_docs');


        $passportPath = null;
        $nidPath = null;
        $utilityPath = null;
        $photoPath = null;


        if ($request->hasFile('passport_file')) {
            $passportPath = $request->file('passport_file')->store('orders/passports', 'public');
            if (empty($user->passport_file)) {
                $user->passport_file = $passportPath;
                $user->save();
            }
        } elseif ($useSaved && !empty($user->passport_file)) {
            $passportPath = $user->passport_file;
        }


        if ($request->hasFile('nid_file')) {
            $nidPath = $request->file('nid_file'))->store('orders/nids', 'public');
            if (empty($user->nid_file)) {
                $user->nid_file = $nidPath;
                $user->save();
            }
        } elseif ($useSaved && !empty($user->nid_file)) {
            $nidPath = $user->nid_file;
        }


        if ($request->hasFile('utility_bill_file')) {
            $utilityPath = $request->file('utility_bill_file')->store('orders/utility_bills', 'public');
            if (empty($user->utility_bill_file)) {
                $user->utility_bill_file = $utilityPath;
                $user->save();
            }
        } elseif ($useSaved && !empty($user->utility_bill_file)) {
            $utilityPath = $user->utility_bill_file;
        }


        if ($request->hasFile('photo_file')) {
            $photoPath = $request->file('photo_file')->store('orders/photos', 'public');
            if (empty($user->photo_file)) {
                $user->photo_file = $photoPath;
                $user->save();
            }
        } elseif ($useSaved && !empty($user->photo_file)) {
            $photoPath = $user->photo_file;
        }


        $receiptPath = null;
        if ($request->hasFile('payment_receipt')) {
            $receiptPath = $request->file('payment_receipt')->store('orders/receipts', 'public');
        }


        $orderNum = 'IVAP-' . date('YYm') . '-' . strtoupper(Str::random(4)) . rand(10, 99);


        $appFee = $service->govt_fee;
        $processingFee = $service->processing_fee;
        $totalAmount = $appFee + $processingFee;
        $paidAmount = $appFee;
        $dueAmount = $processingFee;


        $order = Order::create([
            'order_number' => $orderNum,
            'user_id' => $user->id,
            'customer_name' => $validated['customer_name'],
            'customer_email' => $validated['customer_email'],
            'customer_phone' => $validated['customer_phone'],
            'customer_address' => $validated['customer_address'],
            'passport_number' => $validated['passport_number'] ?? $user->passport_number,
            'id_number' => $validated['nid_number'] ?? $user->nid_number,
            'service_id' => $service->id,
            'service_name' => $service->name,
            'category_name' => $service->category ? $service->category->name : 'General',
            'country_name' => $service->subcategory ? $service->subcategory->name : 'International',
            'app_fee' => $appFee,
            'processing_fee' => $processingFee,
            'additional_charges' => 0,
            'total_amount' => $totalAmount,
            'paid_amount' => $paidAmount,
            'due_amount' => $dueAmount,
            'payment_method' => $validated['payment_method'],
            'payment_trx_id' => $validated['payment_trx_id'],
            'payment_receipt' => $receiptPath,
            'payment_status' => 'advance_paid',
            'order_status' => 'order_placed',
            'passport_file' => $passportPath,
            'nid_file' => $nidPath,
            'utility_bill_file' => $utilityPath,
            'photo_file' => $photoPath,
            'customer_note' => $validated['customer_note'] ?? null,
        ]);


        OrderTimeline::create([]
            'order_id' => $order->id,
            'status_key' => 'order_placed',
            'title' => 'Application Submitted & App Fee Paid',
            'description' => 'Order #' . $order->order_number . ' initiated. Paid upfront Application Fee of BDT ' . $appFee . ' via ' . $order->payment_method . ' (Trx: ' . $order->payment_trx_id . ').',
            'updated_by' => 'Customer',
        ]);


        return redirect()->route('customer.order.show', $order->order_number)
            ->with('success', 'Order placed successfully! Order Reference: #' . $order->order_number . '. Our verification team will review your dossier.');
    }

    public function processDollarExchange(Request $request)
    {
        $validated = $request->validate([]
            'exchange_type' => 'required|in:buy,sell',
            'usd_amount' => 'required|numeric|min:1|max:100000',
            'customer_name' => 'required|string|max:255',
            'customer_email' => 'required|email|max:255',
            'customer_phone' => 'required|string|max:30',
            'account_info' => 'required|string|max:1000',
            'payment_method' => 'required|string|max:100',
            'payment_trx_id' => 'nullable|string|max:100',
            'payment_receipt' => 'nullable|file|mimes:jpg,jpeg,png,pdf|max:5120',
            'customer_note' => 'nullable|string|max:1000',
        ]);


        $type = $validated['exchange_type'];
        $usdAmount = (float) $validated['usd_amount'];


        $buyRate = (float) Setting::get('dollar_buy_rate', 122.50);
        $sellRate = (float) Setting::get('dollar_sell_rate', 119.50);
        $rate = ($type === 'buy') ? $buyRate : $sellRate;
        $totalBdt = round($usdAmount * $rate, 2);


        $receiptPath = null;
        if ($request->hasFile('payment_receipt')) {
            $receiptPath = $request->file('payment_receipt')->store('orders/receipts', 'public');
        }


        $orderNum = 'IVAP-USD-' . date('YYm') . '-' . strtoupper(Str::random(4)) . rand(10, 99);


        $userId = Auth::id();
        if (!$userId) {
            $existing = User::where('email', $validated['customer_email'])->first();
            if ($existing) {
                $userId = $existing->id;
            }
        }


        $serviceTitle = ($type === 'buy') 
            ? 'Buy Dollar ($' . number_format($usdAmount, 2) . ' USD @ BDT ' . number_format($rate, 2) . ')'
            : 'Sell Dollar ($' . number_format($usdAmount, 2) . ' USD @ BDT ' . number_format($rate, 2) . ')';


        $order = Order::create([
            'order_number' => $orderNum,
            'user_id' => $userId,
            'customer_name' => $validated['customer_name'],
            'customer_email' => $validated['customer_email'],
            'customer_phone' => $validated['customer_phone'],
            'customer_address' => 'Forex Service (' . ($type === 'buy' ? 'Customer Buying USD' : 'Customer Selling USD') . ')',
            'service_name' => $serviceTitle,
            'category_name' => 'Dollar Exchanges & Endorsement',
            'country_name' => 'United States (USD / Global Forex)',
            'app_fee' => $totalBdt,
            'processing_fee' => 0,
            'additional_charges' => 0,
            'total_amount' => $totalBdt,
            'paid_amount' => ($type === 'buy' ? $totalBdt : 0),
            'due_amount' => ($type === 'buy' ? 0 : $totalBdt),
            'payment_method' => $validated['payment_method'],
            'payment_trx_id' => $validated['payment_trx_id'] ?? 'Desk / Counter Verification',
            'payment_receipt' => $receiptPath,
            'payment_status'% => ($type === 'buy' ? 'advance_paid' : 'pending_verification'),
            'order_status' => 'order_placed',
            'customer_note' => 'Account / Endorsement Details:\n' . $validated['account_info'] . ($request->filled('customer_note') ? '\n\nAdditional Note: ' . $request->customer_note : ''),
        ]);


        $timelineDesc = ($type === 'buy')
            ? 'Buy Dollar order placed for $' . $usdAmount . ' USD. Total BDT: ' . $totalBdt . ' (@ Rate ' . $rate . ' BDT/USD). Payment Method: ' . $validated['payment_method'] . ' (Trx: ' . ($validated['payment_trx_id'] ?? 'Pending') . '). Delivery/Account: ' . $validated['account_info'] . '.'
            : 'Sell Dollar order placed for $' . $usdAmount . ' USD. Total Payout: BDT ' . $totalBdt . ' (@ Rate ' . $rate . ' BDT/USD). Customer Payout Account: ' . $validated['account_info'] . '. USD Deposit Method: ' . $validated['payment_method'] . '.';


        OrderTimeline::create([]
            'order_id' => $order->id,
            'status_key' => 'order_placed',
            'title' => ($type === 'buy' ? 'Buy Dollar Request Initiated' : 'Sell Dollar Request Initiated'),
            'description' => $timelineDesc,
            'updated_by' => 'Customer',
        ]);


        if (Auth::check()) {
            return redirect()->route('customer.order.show', $order->order_number)
                ->with('success', 'Your Dollar Exchange order (#' . $order->order_number . ') has been placed successfully! Our forex desk will verify and process your transaction.');
        }


        return redirect()->route('track.order', ['order_number' => $order->order_number])
            ->with('success', 'Your Dollar Exchange order (#' . $order->order_number . ') has been placed successfully! You can track live status anytime.');
    }

    public function payDue(Request $request, $orderNumber)
    {
        $order = Order::where('order_number', $orderNumber)->firstOrFail();

        if (Auth::check() && !Auth::user()->isAdmin() && $order->user_id !== Auth::id()) {
            abort(403);
        }


        $validated = $request->validate([
            'due_payment_method' => 'required|in:bkash,nagad,rocket,bank',
            'due_trx_id' => 'required|string|max:100',
            'due_receipt' => 'nullable|file|mimes:jpg,jpeg,png,pdf|max:5120',
        ]);


        $dueAmt = $order->due_amount;
        $order->paid_amount += $dueAmt;
        $order->due_amount = 0;
        $order->payment_status = 'fully_paid';
        $order->payment_trx_id .= ' | Due Paid: ' . $validated['due_trx_id'] . ' (' . $validated['due_payment_method'] . ')';


        if ($request->hasFile('due_receipt')) {
            $order->payment_receipt = $request->file('due_receipt')->store('orders/receipts', 'public');
        }


        $order->save();


        OrderTimeline::create([]
            'order_id' => $order->id,
            'status_key' => 'due_paid',
            'title' => 'Remaining Balance Cleared',
            'description' => 'Customer settled remaining balance of BDT ' . $dueAmt . ' via ' . $validated['due_payment_method'] . ' (Trx: ' . $validated['due_trx_id'] . ').',
            'updated_by' => 'Customer',
        ]);


        return back()->with('success', 'Thank you! Remaining payment has been recorded. You can now download your official invoice and visa certificate.');
    }
}'''

bc_code = bc_code.replace('validate([]', 'validate([').replace('create([]', 'create([')
assemble_all.write_file('app/Http/Controllers/BookingController.php', bc_code)
