<?php

namespace App\Http\Controllers;

use App\Models\Sale;
use App\Models\SaleItem;
use App\Models\Payment;
use App\Models\PaymentMethod;
use App\Models\Product;
use App\Models\Customer;
use App\Models\MpesaTransaction;
use App\Models\HoldSale;
use App\Models\UnifiedNumberSequence;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Str;
use Carbon\Carbon;

class PaymentController extends Controller
{
    // ==================== MAIN PAYMENT PROCESSING ====================
    
    /**
     * Process payment from POS (main method)
     */
    public function process(Request $request)
    {
        DB::beginTransaction();
        
        try {
            Log::info('Payment request received:', $request->all());
            
            // Validate the request
            $validated = $this->validatePaymentRequest($request);
            
            // Calculate totals with proper VAT per product
            $result = $this->calculateCartTotals($validated['cart']);
            
            // Use provided totals if available, otherwise use calculated ones
            $subtotal = $validated['subtotal'] ?? $result['subtotal'];
            $taxTotal = max(0, $validated['vat_amount'] ?? $result['taxTotal']);
            $taxableAmount = $validated['taxable_amount'] ?? $result['taxableAmount'];
            $nonTaxableAmount = $validated['non_taxable_amount'] ?? $result['nonTaxableAmount'];
            
            // Apply discount
            $discount = $validated['discount'] ?? 0;
            $discountedSubtotal = max(0, $subtotal - $discount);
            
            // Calculate grand total
            $grandTotal = $discountedSubtotal + $taxTotal;
            
            // Validate amount matches calculated total
            $this->validateAmount($validated['amount'], $grandTotal);
            
            // Generate receipt and invoice numbers
            $receiptNumber = $this->generateReceiptNumber();
            $invoiceNumber = $validated['invoice_no'] ?? $this->generateInvoiceNumber();
            
            // Get current user (cashier)
            $user = auth()->user();
            
            // Determine payment status
            $paymentStatus = 'paid';
            if ($validated['payment_method'] === 'credit') {
                $paymentStatus = 'partial';
            }
            
            // Get payment method from database if exists
            $paymentMethod = PaymentMethod::where('code', $validated['payment_method'])->first();
            $paymentMethodId = $paymentMethod ? $paymentMethod->id : null;
            
            // Calculate method-specific amounts
            $cashReceived = 0;
            $changeAmount = 0;
            $mpesaReceived = 0;
            $cardReceived = 0;
            $bankReceived = 0;
            $creditAmount = 0;
            
            switch ($validated['payment_method']) {
                case 'cash':
                    $cashReceived = $validated['cash_received'] ?? $grandTotal;
                    $changeAmount = $validated['change'] ?? max(0, $cashReceived - $grandTotal);
                    break;
                case 'mpesa':
                    $mpesaReceived = $grandTotal;
                    break;
                case 'card':
                    $cardReceived = $grandTotal;
                    break;
                case 'bank':
                    $bankReceived = $grandTotal;
                    break;
                case 'credit':
                    $creditAmount = $grandTotal;
                    break;
                case 'multiple':
                    // For split payments
                    $splitPayments = $validated['split_payments'] ?? [];
                    break;
            }
            
            // Create sale record

            // In PaymentController::process() method
            $sale = Sale::create([
                'invoice_no' => $validated['invoice_no'] ?? $validated['unified_number'] ?? $invoiceNumber,
                'receipt_no' => $validated['receipt_no'] ?? $validated['unified_number'] ?? $receiptNumber,
                'unified_number' => $validated['unified_number'] ?? $invoiceNumber, // CRITICAL: Use the frontend's unified number
                'customer_id' => $validated['customer_id'] ?? null,
                'user_id' => $user->id,
                'subtotal' => $subtotal,
                'tax_total' => round($taxTotal, 2),
                'discount' => $discount,
                'grand_total' => $grandTotal,
                'status' => 'completed',
                'payment_status' => $paymentStatus,
                'is_vat_applied' => $result['hasVatApplied'] ? 1 : 0,
                'payment_method' => $validated['payment_method'],
                'transaction_id' => $validated['transaction_id'] ?? $this->generateTransactionId(),
                'cash_received' => $cashReceived,
                'mpesa_received' => $mpesaReceived,
                'card_received' => $cardReceived,
                'bank_received' => $bankReceived,
                'credit_amount' => $creditAmount,
                'customer_change' => $changeAmount,
                'sale_date' => Carbon::now(),
                'created_at' => Carbon::now(),
                'updated_at' => Carbon::now(),
                'notes' => $validated['notes'] ?? null,
                
                // VAT breakdown fields - add these
                'vat_amount' => $taxTotal,
                'taxable_amount' => $taxableAmount,
                'non_taxable_amount' => $nonTaxableAmount,
                'zero_rated_amount' => $result['zeroRatedAmount'] ?? 0,
                'exempted_amount' => $result['exemptedAmount'] ?? 0,
                'zero_rated' => $result['isZeroRated'] ? 1 : 0,
                'exempted' => $result['isExempted'] ? 1 : 0,
            ]);
            
            // Create sale items

            foreach ($result['items'] as $itemData) {
                $product = $itemData['product'];
                
                SaleItem::create([
                    'sale_id' => $sale->id,
                    'product_id' => $product->id,
                    'qty' => $itemData['qty'],
                    'price' => $itemData['price'],
                    'price_ex_tax' => $itemData['price_ex_tax'],
                    'tax_rate' => $itemData['tax_rate'],
                    'tax_amount' => $itemData['tax_amount'],
                    'tax' => $itemData['tax_amount'],
                    'total' => $itemData['total'],
                    'created_at' => Carbon::now(),
                    'updated_at' => Carbon::now(),
                ]);
                
                // Update product stock
                if ($product->track_inventory) {
                    $product->decrement('stock', $itemData['qty']);
                    
                    // Update stock status
                    if ($product->stock <= 0) {
                        $product->stock_status = 'out_of_stock';
                    } elseif ($product->stock <= $product->minimum_stock) {
                        $product->stock_status = 'low_stock';
                    } else {
                        $product->stock_status = 'in_stock';
                    }
                    
                    $product->save();
                }
            }
            
            // In PaymentController process() method, update the payment creation:

            $paymentMethod = PaymentMethod::where('code', $validated['payment_method'])->first();
            $paymentMethodId = $paymentMethod ? $paymentMethod->id : null;

            // Create payment record
            $payment = Payment::create([
                'sale_id' => $sale->id,
                'payment_method_id' => $paymentMethodId,
                'amount' => $grandTotal,
                'reference' => $this->generatePaymentReference($validated['payment_method']),
                'status' => 'completed',
                'meta' => $this->getPaymentDetails($validated), // Already returns array
                'paid_at' => Carbon::now(),
                'received_by' => $user->id,
                'notes' => $validated['notes'] ?? null,
                'created_at' => Carbon::now(),
                'updated_at' => Carbon::now(),
            ]);
            
            // Handle method-specific records
            $this->handlePaymentMethodRecords($validated['payment_method'], $sale, $validated, $payment);
            
            // Update customer if exists
            if ($validated['customer_id']) {
                $this->updateCustomerPurchase($validated['customer_id'], $grandTotal);
            }
            
            // Delete hold sale if exists
            if (!empty($validated['hold_sale_id'])) {
                HoldSale::where('id', $validated['hold_sale_id'])->delete();
            }
            
            DB::commit();
            
            Log::info('Payment processed successfully', [
                'sale_id' => $sale->id,
                'invoice_no' => $invoiceNumber,
                'receipt_no' => $receiptNumber,
                'grand_total' => $grandTotal,
            ]);
            
            return response()->json([
                'success' => true,
                'message' => 'Payment processed successfully',
                'sale' => [
                    'id' => $sale->id,
                    'invoice_no' => $invoiceNumber,
                    'receipt_no' => $receiptNumber,
                    'grand_total' => $grandTotal,
                    'date' => $sale->created_at->format('Y-m-d H:i:s'),
                ],
                'payment' => [
                    'method' => $sale->payment_method,
                    'transaction_id' => $sale->transaction_id,
                ],
                'receipt_data' => $this->generateReceiptData($sale),
            ]);
            
        } catch (\Illuminate\Validation\ValidationException $e) {
            DB::rollBack();
            Log::error('Payment validation error:', $e->errors());
            return response()->json([
                'success' => false,
                'message' => 'Validation failed',
                'errors' => $e->errors(),
            ], 422);
            
        } catch (\Exception $e) {
            DB::rollBack();
            Log::error('Payment processing error: ' . $e->getMessage());
            Log::error('Stack trace: ' . $e->getTraceAsString());
            
            return response()->json([
                'success' => false,
                'message' => 'Payment failed: ' . $e->getMessage(),
            ], 500);
        }
    }
    
    // ==================== SPECIALIZED PAYMENT METHODS ====================
    
    /**
     * Process cash payment (quick method)
     */
    public function processCash(Request $request)
    {
        $request->merge(['payment_method' => 'cash']);
        return $this->process($request);
    }
    
    /**
     * Process M-Pesa payment
     */
    public function processMpesa(Request $request)
    {
        $request->merge(['payment_method' => 'mpesa']);
        
        // If STK push
        if ($request->has('stk_push') && $request->stk_push) {
            return $this->stkPush($request);
        }
        
        // Manual M-Pesa entry
        return $this->process($request);
    }
    
    /**
     * Process M-Pesa STK Push
     */
    public function stkPush(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'amount' => 'required|numeric|min:1|max:150000',
            'phone' => 'required|string|min:9|max:12',
            'reference' => 'nullable|string',
            'description' => 'nullable|string',
            'customer_vat_status' => 'nullable|string|in:vatable,exempted,zero_rated',
            'taxable_amount' => 'nullable|numeric|min:0',
            'non_taxable_amount' => 'nullable|numeric|min:0',
            'exempted_amount' => 'nullable|numeric|min:0',
            'zero_rated_amount' => 'nullable|numeric|min:0',
            'is_vat_applied' => 'nullable|boolean',
            'zero_rated' => 'nullable|boolean',
            'exempted' => 'nullable|boolean',
        ]);
        
        if ($validator->fails()) {
            return response()->json([
                'success' => false,
                'message' => 'Validation failed',
                'errors' => $validator->errors()
            ], 422);
        }
        
        $data = $validator->validated();
        
        try {
            // Format phone
            $phone = $this->formatPhone($data['phone']);
            
            // In production, call Daraja API here
            // For now, simulate STK push
            
            $checkoutRequestId = 'STK_' . Str::random(20);
            
            return response()->json([
                'success' => true,
                'message' => 'STK Push initiated',
                'checkout_request_id' => $checkoutRequestId,
                'phone' => $phone,
                'amount' => $data['amount'],
                'instructions' => 'Customer should check their phone for STK prompt'
            ]);
            
        } catch (\Exception $e) {
            Log::error('STK Push error: ' . $e->getMessage());
            return response()->json([
                'success' => false,
                'message' => 'STK Push failed: ' . $e->getMessage()
            ], 500);
        }
    }
    
    /**
     * Manual M-Pesa entry
     */
    public function manualMpesa(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'amount' => 'required|numeric|min:0.01',
            'phone' => 'required|string',
            'transaction_id' => 'required|string',
            'receipt_no' => 'nullable|string',
            'transaction_date' => 'nullable|date',
        ]);
        
        if ($validator->fails()) {
            return response()->json([
                'success' => false,
                'message' => 'Validation failed',
                'errors' => $validator->errors()
            ], 422);
        }
        
        $data = $validator->validated();
        
        try {
            // Check if transaction already exists
            $existing = MpesaTransaction::where('transaction_id', $data['transaction_id'])
                ->where('status', 'completed')
                ->first();
            
            if ($existing) {
                return response()->json([
                    'success' => false,
                    'message' => 'Transaction ID already used'
                ], 400);
            }
            
            // Create M-Pesa transaction record
            $mpesa = MpesaTransaction::create([
                'transaction_id' => $data['transaction_id'],
                'receipt_no' => $data['receipt_no'] ?? null,
                'amount' => $data['amount'],
                'phone' => $this->formatPhone($data['phone']),
                'transaction_date' => $data['transaction_date'] ?? now(),
                'status' => 'completed',
                'type' => 'manual',
                'user_id' => auth()->id(),
            ]);
            
            return response()->json([
                'success' => true,
                'message' => 'M-Pesa transaction recorded',
                'transaction' => $mpesa
            ]);
            
        } catch (\Exception $e) {
            Log::error('Manual M-Pesa error: ' . $e->getMessage());
            return response()->json([
                'success' => false,
                'message' => 'Failed to record M-Pesa transaction'
            ], 500);
        }
    }
    
    /**
     * Check M-Pesa payment status
     */
    public function checkMpesaStatus(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'checkout_request_id' => 'required|string',
        ]);
        
        if ($validator->fails()) {
            return response()->json([
                'success' => false,
                'message' => 'Validation failed',
                'errors' => $validator->errors()
            ], 422);
        }
        
        // In production, check with Daraja API
        // For now, simulate status check
        
        $statuses = ['pending', 'completed', 'failed', 'cancelled'];
        $status = $statuses[array_rand($statuses)];
        
        return response()->json([
            'success' => true,
            'status' => $status,
            'checkout_request_id' => $request->checkout_request_id,
            'message' => 'Payment ' . $status,
            'transaction_id' => $status === 'completed' ? 'MPESA_' . Str::random(10) : null,
            'receipt_no' => $status === 'completed' ? 'RCPT' . rand(100000, 999999) : null,
        ]);
    }
    
    /**
     * Process card payment
     */
    public function processCard(Request $request)
    {
        $request->merge(['payment_method' => 'card']);
        
        $validator = Validator::make($request->all(), [
            'card_number' => 'required|string|min:16|max:19',
            'card_holder' => 'required|string',
            'card_expiry' => 'required|string',
            'card_cvv' => 'required|string|min:3|max:4',
            'card_type' => 'nullable|in:visa,mastercard,amex',
        ]);
        
        if ($validator->fails()) {
            return response()->json([
                'success' => false,
                'message' => 'Validation failed',
                'errors' => $validator->errors()
            ], 422);
        }
        
        return $this->process($request);
    }
    
    /**
     * Process split payment
     */
    public function processSplit(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'split_payments' => 'required|array|min:2',
            'split_payments.*.method' => 'required|string',
            'split_payments.*.amount' => 'required|numeric|min:0.01',
            'split_payments.*.details' => 'nullable|array',
        ]);
        
        if ($validator->fails()) {
            return response()->json([
                'success' => false,
                'message' => 'Validation failed',
                'errors' => $validator->errors()
            ], 422);
        }
        
        $data = $validator->validated();
        
        // Verify total matches
        $total = array_sum(array_column($data['split_payments'], 'amount'));
        
        if (abs($total - $request->amount) > 0.01) {
            return response()->json([
                'success' => false,
                'message' => 'Split total does not match sale total'
            ], 422);
        }
        
        // Process main payment
        $request->merge(['payment_method' => 'multiple']);
        $response = $this->process($request);
        
        if ($response->getData()->success) {
            $saleId = $response->getData()->sale['id'];
            
            // Record split payment details
            foreach ($data['split_payments'] as $split) {
                $method = PaymentMethod::where('code', $split['method'])->first();
                
                if ($method) {
                    Payment::create([
                        'sale_id' => $saleId,
                        'payment_method_id' => $method->id,
                        'amount' => $split['amount'],
                        'reference' => 'SPLIT_' . $this->generatePaymentReference($method->code),
                        'status' => 'completed',
                        'payment_details' => $split['details'] ?? [],
                        'user_id' => auth()->id(),
                    ]);
                }
            }
        }
        
        return $response;
    }
    
    // ==================== HELPER METHODS (from original PaymentController) ====================
    
    private function validatePaymentRequest(Request $request): array
    {
        $validator = Validator::make($request->all(), [
            'payment_method' => 'required|string|in:cash,mpesa,card,credit,multiple,bank',
            'amount' => 'required|numeric|min:0.01',
            'cart' => 'required|array|min:1',
            'cart.*.product_id' => 'required|exists:products,id',
            'cart.*.quantity' => 'nullable|integer|min:1',
            'cart.*.qty' => 'nullable|integer|min:1',
            'cart.*.price' => 'required|numeric|min:0',
            'cart.*.price_ex_tax' => 'nullable|numeric|min:0', // Add this
            'cart.*.tax_rate' => 'nullable|numeric|min:0|max:100', // Add this
            'cart.*.is_vatable' => 'nullable|boolean', // Add this
            'cart.*.has_vat' => 'nullable|boolean', // Add this
            'customer_id' => 'nullable|exists:customers,id',
            'discount' => 'nullable|numeric|min:0',
            'notes' => 'nullable|string|max:500',
            'subtotal' => 'nullable|numeric|min:0',
            'vat_amount' => 'nullable|numeric|min:0',
            'vat_rate' => 'nullable|numeric|min:0|max:100',
            'taxable_amount' => 'nullable|numeric|min:0',
            'non_taxable_amount' => 'nullable|numeric|min:0',
            'cash_received' => 'nullable|required_if:payment_method,cash|numeric|min:0',
            'change' => 'nullable|numeric|min:0',
            'mpesa_phone' => 'nullable|required_if:payment_method,mpesa|string|size:9',
            'mpesa_transaction_id' => 'nullable|string|max:100',
            'mpesa_receipt_no' => 'nullable|string|max:100',
            'card_number' => 'nullable|required_if:payment_method,card|string|size:16',
            'card_holder' => 'nullable|string|max:255',
            'bank_reference' => 'nullable|required_if:payment_method,bank|string|max:100',
            'bank_name' => 'nullable|string|max:255',
            'split_payments' => 'nullable|array',
            'hold_sale_id' => 'nullable|exists:hold_sales,id',
        ]);
        
        if ($validator->fails()) {
            \Log::error('Payment validation failed:', $validator->errors()->toArray());
            throw new \Illuminate\Validation\ValidationException($validator);
        }
        
        $validated = $validator->validated();
        
        // Normalize quantity field
        foreach ($validated['cart'] as &$item) {
            if (isset($item['quantity']) && !isset($item['qty'])) {
                $item['qty'] = $item['quantity'];
            } elseif (isset($item['qty']) && !isset($item['quantity'])) {
                $item['quantity'] = $item['qty'];
            }
            
            if (!isset($item['qty']) && !isset($item['quantity'])) {
                $item['qty'] = $item['quantity'] = 1;
            }
            
            if (!isset($item['qty'])) {
                $item['qty'] = $item['quantity'];
            }
            if (!isset($item['quantity'])) {
                $item['quantity'] = $item['qty'];
            }
            
            // Ensure price_ex_tax is set
            if (!isset($item['price_ex_tax']) && isset($item['price'])) {
                $item['price_ex_tax'] = $item['price'];
            }
        }
        
        \Log::info('Validated payment data:', ['cart_count' => count($validated['cart']), 'cart_items' => $validated['cart']]);
        
        return $validated;
    }
    
    // In PaymentController.php - Update calculateCartTotals method:

    private function calculateCartTotals(array $cartItems, $customer = null): array
    {
        $subtotal = 0;
        $taxTotal = 0;
        $items = [];
        $hasVatApplied = false;
        $taxableAmount = 0;
        $nonTaxableAmount = 0;
        $exemptedAmount = 0;
        $zeroRatedAmount = 0;
        
        // Determine customer VAT status
        $customerVatStatus = $customer->vat_status ?? 'vatable';
        $isExempted = $customerVatStatus === 'exempted';
        $isZeroRated = $customerVatStatus === 'zero_rated';
        $isVatable = $customerVatStatus === 'vatable' || !$customer;
        
        foreach ($cartItems as $cartItem) {
            // Extract data with multiple fallbacks
            $productId = $cartItem['product_id'] ?? $cartItem['id'] ?? 0;
            $product = Product::with('tax')->find($productId);
            
            if (!$product) {
                throw new \Exception("Product not found: {$productId}");
            }
            
            $quantity = $cartItem['qty'] ?? $cartItem['quantity'] ?? 1;
            $price = $cartItem['price'] ?? $product->sale_price;
            
            // CRITICAL FIX: Use price_ex_tax if available, otherwise use price
            $itemPriceExTax = $cartItem['price_ex_tax'] ?? $price;
            $itemTotal = $itemPriceExTax * $quantity;
            
            $itemTaxAmount = 0;
            $itemTaxRate = 0;
            $isProductVatable = false;
            $vatType = 'none'; // none, zero_rated, exempted, standard
            
            // Check if product is VATable - use multiple sources
            if (isset($cartItem['is_vatable'])) {
                $isProductVatable = $cartItem['is_vatable'];
            } elseif (isset($cartItem['has_vat'])) {
                $isProductVatable = $cartItem['has_vat'];
            } else {
                $isProductVatable = $product->has_vat || $product->is_vatable || ($product->tax && $product->tax->rate > 0);
            }
            
            // Get tax rate from multiple sources
            if (isset($cartItem['tax_rate'])) {
                $itemTaxRate = $cartItem['tax_rate'];
            } elseif ($product->tax) {
                $itemTaxRate = $product->tax->rate;
            } else {
                $itemTaxRate = 0;
            }
            
            // Apply customer VAT status
  
            if ($isExempted) {
                // VAT exempted customer - no VAT on any items
                $itemTaxAmount = 0;
                $itemTaxRate = 0;
                $vatType = 'exempted';
                $exemptedAmount += $itemTotal;
                $nonTaxableAmount += $itemTotal;
                
            } elseif ($isZeroRated) {
                // Zero-rated customer - items are taxable but at 0% rate
                $itemTaxAmount = 0;
                $itemTaxRate = 0;
                $vatType = 'zero_rated';
                $zeroRatedAmount += $itemTotal;
                $taxableAmount += $itemTotal;
                
            } elseif ($isVatable && $isProductVatable && $itemTaxRate > 0) {
                // VATable customer with VATable product at non-zero rate
                $itemTaxAmount = ($itemPriceExTax * $itemTaxRate / 100) * $quantity;
                $hasVatApplied = true;
                $vatType = 'standard';
                $taxableAmount += $itemTotal;
                $taxTotal += $itemTaxAmount;
                
            } elseif ($isVatable && $isProductVatable && $itemTaxRate == 0) {
                // VATable customer with VATable product at 0% rate
                $itemTaxAmount = 0;
                $vatType = 'zero_rated';
                $zeroRatedAmount += $itemTotal;
                $taxableAmount += $itemTotal;
                
            } else {
                // Non-VATable product OR non-VATable customer
                $itemTaxAmount = 0;
                $itemTaxRate = 0;
                $vatType = 'none';
                $nonTaxableAmount += $itemTotal;
            }
            
            $items[] = [
                'product' => $product,
                'quantity' => $quantity,
                'qty' => $quantity,
                'price' => $itemPriceExTax, // Price without VAT
                'price_ex_tax' => $itemPriceExTax,
                'total' => $itemTotal,
                'tax_rate' => $itemTaxRate,
                'tax_amount' => $itemTaxAmount,
                'is_vatable' => $isProductVatable,
                'vat_type' => $vatType,
                'customer_vat_status' => $customerVatStatus,
                'applied_vat_rate' => $itemTaxRate
            ];
            
            $subtotal += $itemTotal;
        }
        
        return [
            'items' => $items,
            'subtotal' => $subtotal,
            'taxTotal' => $taxTotal,
            'hasVatApplied' => $hasVatApplied,
            'taxableAmount' => $taxableAmount,
            'nonTaxableAmount' => $nonTaxableAmount,
            'exemptedAmount' => $exemptedAmount,
            'zeroRatedAmount' => $zeroRatedAmount,
            'customerVatStatus' => $customerVatStatus,
            'isVatable' => $isVatable,
            'isZeroRated' => $isZeroRated,
            'isExempted' => $isExempted
        ];
    }
    
    private function validateAmount(float $providedAmount, float $calculatedTotal): void
    {
        $calculatedTotal = round($calculatedTotal, 2);
        $providedAmount = round($providedAmount, 2);
        
        if (abs($calculatedTotal - $providedAmount) > 0.01) {
            throw new \Exception(
                "Calculated total (KES {$calculatedTotal}) doesn't match provided amount (KES {$providedAmount})"
            );
        }
    }
    
    private function updateCustomerPurchase($customerId, float $amount): void
    {
        $customer = Customer::find($customerId);
        if ($customer) {
            $customer->last_purchase_date = Carbon::now();
            $customer->total_purchases = ($customer->total_purchases ?? 0) + $amount;
            $customer->save();
        }
    }
    
    private function generateReceiptNumber(): string
    {
        $date = date('Ymd');
        $count = Sale::whereDate('created_at', today())->count() + 1;
        return 'RCP-' . $date . '-' . str_pad($count, 4, '0', STR_PAD_LEFT);
    }
    
    private function generateInvoiceNumber(): string
    {
        $date = date('Ymd');
        $count = Sale::whereDate('created_at', today())->count() + 1;
        return 'INV-' . $date . '-' . str_pad($count, 4, '0', STR_PAD_LEFT);
    }
    
    private function generateTransactionId(): string
    {
        return 'TXN-' . date('YmdHis') . '-' . rand(1000, 9999);
    }
    
    private function generatePaymentReference($methodCode): string
    {
        $prefix = strtoupper($methodCode);
        return $prefix . '-' . date('YmdHis') . '-' . Str::random(6);
    }
    
    private function handlePaymentMethodRecords(string $method, Sale $sale, array $data, Payment $payment = null): void
    {
        switch ($method) {
            case 'mpesa':
                if (!empty($data['mpesa_transaction_id'])) {
                    MpesaTransaction::create([
                        'sale_id' => $sale->id,
                        'transaction_id' => $data['mpesa_transaction_id'],
                        'receipt_no' => $data['mpesa_receipt_no'] ?? null,
                        'amount' => $sale->grand_total,
                        'phone' => $this->formatPhone($data['mpesa_phone'] ?? ''),
                        'transaction_date' => Carbon::now(),
                        'status' => 'completed',
                        'type' => 'manual',
                        'user_id' => $sale->user_id,
                    ]);
                }
                break;
                
            case 'cash':
                // Additional cash handling if needed
                break;
        }
    }
    
    private function formatPhone(string $phone): string
    {
        $phone = preg_replace('/[^0-9]/', '', $phone);
        
        if (strlen($phone) === 9 && preg_match('/^[17]\d{8}$/', $phone)) {
            return '0' . $phone;
        } elseif (strlen($phone) === 10 && str_starts_with($phone, '0')) {
            return $phone;
        } elseif (strlen($phone) === 12 && str_starts_with($phone, '254')) {
            return '0' . substr($phone, 3);
        }
        
        return $phone;
    }
    
    private function getPaymentDetails(array $data): array
    {
        $details = [];
        
        switch ($data['payment_method']) {
            case 'cash':
                $details['cash_received'] = $data['cash_received'] ?? null;
                $details['change'] = isset($data['cash_received']) 
                    ? $data['cash_received'] - $data['amount'] 
                    : 0;
                break;
                
            case 'mpesa':
                $details['phone'] = $this->formatPhone($data['mpesa_phone'] ?? '');
                $details['transaction_id'] = $data['mpesa_transaction_id'] ?? null;
                $details['receipt_no'] = $data['mpesa_receipt_no'] ?? null;
                $details['type'] = $data['mpesa_type'] ?? 'manual';
                break;
                
            case 'card':
                $details['card_last4'] = isset($data['card_number']) 
                    ? substr($data['card_number'], -4) 
                    : null;
                $details['card_type'] = $data['card_type'] ?? null;
                $details['card_holder'] = $data['card_holder'] ?? null;
                $details['card_expiry'] = $data['card_expiry'] ?? null;
                break;
                
            case 'bank':
                $details['bank_name'] = $data['bank_name'] ?? null;
                $details['reference'] = $data['bank_reference'] ?? null;
                $details['account_name'] = $data['account_name'] ?? null;
                break;
                
            case 'credit':
                $details['terms'] = $data['terms'] ?? 30;
                $details['due_date'] = $data['due_date'] ?? null;
                $details['approved_by'] = auth()->user()->name ?? null;
                break;
                
            case 'multiple':
                $details['split_payments'] = $data['split_payments'] ?? [];
                break;
        }
        
        // Common details
        $details['payment_method'] = $data['payment_method'];
        $details['amount'] = $data['amount'];
        $details['customer_id'] = $data['customer_id'] ?? null;
        $details['timestamp'] = Carbon::now()->toISOString();
        $details['processed_by'] = auth()->user()->name ?? 'System';
        
        return $details;
    }
    
    // Add this method to your PaymentController
    
    /**
     * Generate receipt for a sale
     */
    public function generateReceipt($identifier, Request $request)
    {
        try {
            // Find the sale with all related data
            $sale = Sale::with([
                'items.product', 
                'customer', 
                'user', 
                'payments.paymentMethod',
                'mpesaTransactions'
            ])
            ->where('invoice_no', $identifier)
            ->orWhere('receipt_no', $identifier)
            ->orWhere('id', $identifier)
            ->firstOrFail();
            
            // Generate comprehensive receipt data
            $receiptData = $this->prepareDetailedReceiptData($sale);
            
            // Check if it's an AJAX request
            if ($request->expectsJson() || $request->is('api/*')) {
                return response()->json([
                    'success' => true,
                    'receipt' => $receiptData,
                    'print_url' => url("/pos/receipt/{$sale->receipt_no}?autoprint=true"),
                    'download_url' => url("/pos/receipt/{$sale->receipt_no}/pdf"),
                ]);
            }
            
            // Return view for direct browser access
            return view('pos.receipts.receipt', [
                'data' => $receiptData,
                'autoprint' => $request->boolean('autoprint'),
                'download' => $request->boolean('download')
            ]);
            
        } catch (\Exception $e) {
            \Log::error('Receipt generation error: ' . $e->getMessage());
            
            if ($request->expectsJson()) {
                return response()->json([
                    'success' => false,
                    'message' => 'Receipt not found'
                ], 404);
            }
            
            abort(404, 'Receipt not found');
        }
    }
    
    /**
     * Prepare detailed receipt data
     */
    private function prepareDetailedReceiptData(Sale $sale): array
    {
        $vatBreakdown = [];
        $totalVAT = 0;
        $taxableAmount = 0;
        $zeroRatedAmount = 0;
        $exemptedAmount = 0;
        $nonTaxableAmount = 0;
        
        foreach ($sale->items as $item) {
            $itemTotal = $item->price_ex_tax * $item->qty;
            
            // Handle based on product VAT status
            if ($item->tax_rate > 0) {
                // VATable item
                $taxableAmount += $itemTotal;
                $itemVAT = $item->tax_amount;
                $totalVAT += $itemVAT;
                
                // Group by rate
                $rateKey = (string) $item->tax_rate;
                if (!isset($vatBreakdown[$rateKey])) {
                    $vatBreakdown[$rateKey] = [
                        'rate' => $item->tax_rate,
                        'taxable_amount' => 0,
                        'vat_amount' => 0,
                        'type' => 'standard'
                    ];
                }
                $vatBreakdown[$rateKey]['taxable_amount'] += $itemTotal;
                $vatBreakdown[$rateKey]['vat_amount'] += $itemVAT;
                
            } else if ($sale->zero_rated) {
                // Zero-rated (for zero-rated customers)
                $zeroRatedAmount += $itemTotal;
                if (!isset($vatBreakdown['zero'])) {
                    $vatBreakdown['zero'] = [
                        'rate' => 0,
                        'taxable_amount' => 0,
                        'vat_amount' => 0,
                        'type' => 'zero_rated'
                    ];
                }
                $vatBreakdown['zero']['taxable_amount'] += $itemTotal;
                
            } else if ($sale->exempted) {
                // Exempted (for exempted customers)
                $exemptedAmount += $itemTotal;
                
            } else {
                // Non-vatable product
                $nonTaxableAmount += $itemTotal;
            }
        }
        
        // Get customer info
        $customerData = [
            'name' => 'Walk-in Customer',
            'phone' => '',
            'email' => '',
            'company_name' => '',
            'address' => '',
            'pin' => '',
            'vat_number' => '',
            'vat_status' => 'vatable',
        ];

        if ($sale->customer) {
            $customerData = [
                'name' => $sale->customer->name ?? 'Walk-in Customer',
                'phone' => $sale->customer->phone ?? '',
                'email' => $sale->customer->email ?? '',
                'company_name' => $sale->customer->company_name ?? '',
                'address' => $sale->customer->address ?? '',
                'pin' => $sale->customer->pin ?? '',
                'vat_number' => $sale->customer->vat_number ?? '',
                'vat_status' => $sale->customer->vat_status ?? 'vatable',
            ];
        }
        
        // Prepare receipt items with VAT info
        $items = [];
        foreach ($sale->items as $item) {
            $items[] = [
                'name' => $item->product->name ?? 'Product',
                'sku' => $item->product->sku ?? '',
                'quantity' => $item->qty,
                'price' => $item->price,
                'price_ex_tax' => $item->price_ex_tax ?? $item->price,
                'tax_rate' => $item->tax_rate,
                'tax_amount' => $item->tax_amount,
                'total' => $item->total,
                'is_vatable' => $item->tax_rate > 0,
                'vat_included' => true,
            ];
        }
        
        // Store information
        $storeInfo = [
            'name' => config('app.name', 'Kenyan Supermarket'),
            'address' => config('app.address', 'Nairobi CBD'),
            'phone' => config('app.phone', '0700 000 000'),
            'pin' => config('app.pin', 'P051234567N'),
            'vat_number' => config('app.vat_number', 'VAT001234567'),
        ];
        
        // Totals with detailed VAT breakdown
        $totals = [
            'subtotal' => $sale->subtotal,
            'discount' => $sale->discount,
            'taxable_amount' => $sale->taxable_amount ?? $taxableAmount,
            'non_taxable_amount' => $sale->non_taxable_amount ?? $nonTaxableAmount,
            'exempted_amount' => $sale->exempted_amount ?? $exemptedAmount,
            'zero_rated_amount' => $sale->zero_rated_amount ?? $zeroRatedAmount,
            'vat_amount' => $sale->tax_total,
            'grand_total' => $sale->grand_total,
        ];
        
        // VAT information with detailed breakdown
        $vatInfo = [
            'customer_status' => $customerData['vat_status'],
            'is_vat_applicable' => !$sale->exempted,
            'is_zero_rated' => $sale->zero_rated,
            'is_exempted' => $sale->exempted,
            'breakdown' => array_values($vatBreakdown), // Convert to indexed array
            'total_vat' => $sale->tax_total,
        ];
        
        return [
            'id' => $sale->id,
            'invoice_no' => $sale->invoice_no,
            'receipt_no' => $sale->receipt_no,
            'date' => $sale->created_at->format('Y-m-d'),
            'time' => $sale->created_at->format('H:i:s'),
            
            'store' => $storeInfo,
            'customer' => $customerData,
            
            'items' => $items,
            'totals' => $totals,
            'vat_info' => $vatInfo,
            
            'payment' => [
                'method' => $sale->payment_method,
                'amount_paid' => $sale->grand_total,
                'change' => $sale->customer_change,
                'transaction_id' => $sale->transaction_id,
            ],
            
            'cashier' => $sale->user->name ?? 'Cashier',
            'notes' => [
                'Thank you for your business!',
                'Items sold are not returnable unless defective',
                'Please check goods before leaving the counter',
                'Valid for 7 days from date of purchase',
                'Keep this receipt for warranty claims',
                'VAT Invoice - Valid for Tax Purposes'
            ]
        ];
    }
    
    private function generateReceiptData(Sale $sale): array
    {
        $sale->load(['items.product', 'customer', 'user']);
        
        $items = [];
        foreach ($sale->items as $item) {
            $items[] = [
                'name' => $item->product->name ?? $item->product_name,
                'quantity' => $item->qty,
                'unit_price' => $item->price,
                'total' => $item->total,
                'tax_rate' => $item->tax_rate,
                'tax_amount' => $item->tax_amount,
                'is_vatable' => $item->tax_rate > 0,
            ];
        }
        
        $paymentDetails = [
            'method' => $sale->payment_method,
            'amount_paid' => $sale->grand_total,
            'transaction_id' => $sale->transaction_id,
        ];
        
        if ($sale->payment_method === 'cash') {
            $paymentDetails['cash_received'] = $sale->cash_received;
            $paymentDetails['change'] = $sale->customer_change;
        } elseif ($sale->payment_method === 'mpesa') {
            $paymentDetails['mpesa_received'] = $sale->mpesa_received;
            $paymentDetails['mpesa_transaction_id'] = $sale->transaction_id;
        } elseif ($sale->payment_method === 'card') {
            $paymentDetails['card_received'] = $sale->card_received;
        } elseif ($sale->payment_method === 'bank') {
            $paymentDetails['bank_received'] = $sale->bank_received;
        } elseif ($sale->payment_method === 'credit') {
            $paymentDetails['credit_amount'] = $sale->credit_amount;
        }
        
        return [
            'unified_number' => $sale->unified_number ?? $sale->invoice_no,
            'invoice_no' => $sale->invoice_no,
            'receipt_no' => $sale->receipt_no,
            'date' => $sale->created_at->format('Y-m-d'),
            'time' => $sale->created_at->format('H:i:s'),
            'customer' => $sale->customer ? [
                'name' => $sale->customer->name,
                'phone' => $sale->customer->phone,
                'email' => $sale->customer->email,
                'vat_number' => $sale->customer->vat_number,
                'pin' => $sale->customer->pin,
                'company_name' => $sale->customer->company_name,
                'address' => $sale->customer->address,
            ] : null,
            'items' => $items,
            'totals' => [
                'subtotal' => $sale->subtotal,
                'discount' => $sale->discount,
                'vat_amount' => $sale->tax_total,
                'tax_total' => $sale->tax_total,
                'grand_total' => $sale->grand_total,
            ],
            'payment' => $paymentDetails,
            'store' => [
                'name' => config('app.name', 'Kenyan Supermarket'),
                'address' => config('app.address', 'Nairobi CBD'),
                'phone' => config('app.phone', '0700 000 000'),
                'email' => config('app.email', 'info@supermarket.co.ke'),
                'pin' => config('app.pin', 'P051234567N'),
                'vat_number' => config('app.vat_number', 'VAT001234567'),
            ],
            'cashier' => $sale->user->name ?? 'Cashier',
            'autoprint' => true,
        ];
    }
    
    // ==================== ADDITIONAL METHODS ====================
    
    /**
     * Verify payment
     */
    public function verify(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'reference' => 'required|string',
            'invoice_no' => 'nullable|string',
            'receipt_no' => 'nullable|string',
        ]);
        
        if ($validator->fails()) {
            return response()->json([
                'success' => false,
                'message' => 'Validation failed',
                'errors' => $validator->errors()
            ], 422);
        }
        
        $data = $validator->validated();
        
        try {
            $sale = Sale::where(function($query) use ($data) {
                    $query->where('invoice_no', $data['reference'])
                        ->orWhere('receipt_no', $data['reference']);
                })
                ->orWhere(function($query) use ($data) {
                    if ($data['invoice_no']) {
                        $query->where('invoice_no', $data['invoice_no']);
                    }
                    if ($data['receipt_no']) {
                        $query->where('receipt_no', $data['receipt_no']);
                    }
                })
                ->first();
            
            if (!$sale) {
                return response()->json([
                    'success' => false,
                    'message' => 'Sale not found'
                ], 404);
            }
            
            return response()->json([
                'success' => true,
                'sale' => [
                    'id' => $sale->id,
                    'invoice_no' => $sale->invoice_no,
                    'receipt_no' => $sale->receipt_no,
                    'grand_total' => $sale->grand_total,
                    'payment_method' => $sale->payment_method,
                    'status' => $sale->payment_status,
                    'date' => $sale->created_at->format('Y-m-d H:i:s'),
                ],
                'verified' => $sale->payment_status === 'paid',
            ]);
            
        } catch (\Exception $e) {
            Log::error('Payment verification error: ' . $e->getMessage());
            return response()->json([
                'success' => false,
                'message' => 'Verification failed'
            ], 500);
        }
    }
    
    /**
     * Refund payment
     */
    public function refund(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'sale_id' => 'required|exists:sales,id',
            'amount' => 'required|numeric|min:0.01',
            'reason' => 'required|string|max:255',
        ]);
        
        if ($validator->fails()) {
            return response()->json([
                'success' => false,
                'message' => 'Validation failed',
                'errors' => $validator->errors()
            ], 422);
        }
        
        DB::beginTransaction();
        
        try {
            $sale = Sale::findOrFail($request->sale_id);
            
            if ($sale->payment_status !== 'paid') {
                throw new \Exception('Only paid sales can be refunded');
            }
            
            if ($request->amount > $sale->grand_total) {
                throw new \Exception('Refund amount cannot exceed original amount');
            }
            
            // Create refund sale
            $refundSale = Sale::create([
                'invoice_no' => 'REFUND-' . $sale->invoice_no,
                'receipt_no' => 'REFUND-' . $sale->receipt_no,
                'customer_id' => $sale->customer_id,
                'user_id' => auth()->id(),
                'subtotal' => -$request->amount,
                'grand_total' => -$request->amount,
                'status' => 'refunded',
                'payment_status' => 'refunded',
                'payment_method' => $sale->payment_method,
                'notes' => $request->reason,
                'original_sale_id' => $sale->id,
                'created_at' => Carbon::now(),
                'updated_at' => Carbon::now(),
            ]);
            
            // Update original sale status
            $sale->payment_status = $request->amount == $sale->grand_total ? 'refunded' : 'partially_refunded';
            $sale->save();
            
            DB::commit();
            
            return response()->json([
                'success' => true,
                'message' => 'Refund processed successfully',
                'refund_id' => $refundSale->id,
                'refund_invoice_no' => $refundSale->invoice_no,
                'amount' => $request->amount,
            ]);
            
        } catch (\Exception $e) {
            DB::rollBack();
            Log::error('Refund error: ' . $e->getMessage());
            return response()->json([
                'success' => false,
                'message' => 'Refund failed: ' . $e->getMessage()
            ], 500);
        }
    }
    
    /**
     * Get payment methods list
     */
    public function getPaymentMethods()
    {
        try {
            // Try to get from database first
            $methods = PaymentMethod::where('is_active', true)
                ->orderBy('sort_order')
                ->get()
                ->map(function ($method) {
                    return [
                        'id' => $method->id,
                        'code' => $method->code,
                        'name' => $method->name,
                        'type' => $method->type,
                        'provider' => $method->provider,
                        'icon' => $method->icon,
                        'description' => $method->description,
                        'requires_confirmation' => (bool) $method->requires_confirmation,
                        'config' => $method->config ?? [],
                        'color' => $this->getMethodColor($method->code),
                        'sort_order' => $method->sort_order,
                        'is_active' => (bool) $method->is_active,
                    ];
                });
            
            // If no methods in DB, return defaults
            if ($methods->isEmpty()) {
                $methods = collect($this->getDefaultMethods());
            }
            
            return response()->json([
                'success' => true,
                'methods' => $methods,
                'count' => $methods->count(),
                'timestamp' => now()->toISOString()
            ]);
            
        } catch (\Exception $e) {
            Log::error('Error loading payment methods: ' . $e->getMessage());
            
            // Return defaults on error
            return response()->json([
                'success' => true,
                'methods' => $this->getDefaultMethods(),
                'count' => 6,
                'error' => config('app.debug') ? $e->getMessage() : null,
                'timestamp' => now()->toISOString()
            ]);
        }
    }
    
    private function getMethodColor($code)
    {
        $colors = [
            'cash' => '#28a745',
            'mpesa' => '#4facfe',
            'card' => '#007bff',
            'credit' => '#ffc107',
            'multiple' => '#6f42c1',
            'bank' => '#20c997',
            'cheque' => '#17a2b8',
            'airtel' => '#fd7e14',
            'split' => '#9b59b6',
        ];
        
        return $colors[$code] ?? '#6c757d';
    }
    
    private function getDefaultMethods()
    {
        return [
            [
                'id' => 1,
                'code' => 'cash',
                'name' => 'Cash',
                'type' => 'cash',
                'icon' => 'money',
                'color' => '#28a745',
                'description' => 'Physical cash payment',
                'requires_confirmation' => false,
                'config' => [],
                'sort_order' => 1,
                'is_active' => true,
            ],
            [
                'id' => 2,
                'code' => 'mpesa',
                'name' => 'M-Pesa',
                'type' => 'mobile',
                'provider' => 'mpesa',
                'icon' => 'mobile-alt',
                'color' => '#4facfe',
                'description' => 'Mobile money payment',
                'requires_confirmation' => true,
                'config' => ['stk_push_enabled' => true, 'manual_entry_enabled' => true],
                'sort_order' => 2,
                'is_active' => true,
            ],
            [
                'id' => 3,
                'code' => 'card',
                'name' => 'Card',
                'type' => 'card',
                'icon' => 'credit-card',
                'color' => '#007bff',
                'description' => 'Credit/Debit card',
                'requires_confirmation' => true,
                'config' => ['supported_types' => ['visa', 'mastercard', 'amex']],
                'sort_order' => 3,
                'is_active' => true,
            ],
            [
                'id' => 4,
                'code' => 'credit',
                'name' => 'Credit',
                'type' => 'credit',
                'icon' => 'receipt',
                'color' => '#ffc107',
                'description' => 'Pay later',
                'requires_confirmation' => true,
                'config' => ['default_terms' => 30, 'max_terms' => 90],
                'sort_order' => 4,
                'is_active' => true,
            ],
            [
                'id' => 5,
                'code' => 'multiple',
                'name' => 'Split Payment',
                'type' => 'multiple',
                'icon' => 'layer',
                'color' => '#6f42c1',
                'description' => 'Multiple payment methods',
                'requires_confirmation' => false,
                'config' => ['max_methods' => 3],
                'sort_order' => 5,
                'is_active' => true,
            ],
            [
                'id' => 6,
                'code' => 'bank',
                'name' => 'Bank Transfer',
                'type' => 'bank',
                'icon' => 'bank',
                'color' => '#20c997',
                'description' => 'Bank payment',
                'requires_confirmation' => true,
                'config' => [],
                'sort_order' => 6,
                'is_active' => true,
            ],
        ];
    }
    
    /**
     * Display receipt for a sale
     */
    /**
     * Display receipt for a sale
     */
    public function showReceipt($identifier)
    {
        try {
            Log::info('Receipt requested', ['identifier' => $identifier]);
            
            // Try to find sale by various identifiers
            $sale = Sale::with([
                'items.product', 
                'customer', 
                'user', 
                'payments.paymentMethod',
                'mpesaTransactions'
            ])
            ->where('unified_number', $identifier)
            ->orWhere('invoice_no', $identifier)
            ->orWhere('receipt_no', $identifier)
            ->orWhere('id', $identifier)
            ->first();
            
            if (!$sale) {
                Log::error('Sale not found for receipt', ['identifier' => $identifier]);
                
                // Check if it's a unified number
                if (str_starts_with($identifier, 'INVRCP-')) {
                    // Try to find by date and counter
                    $parts = explode('-', $identifier);
                    if (count($parts) === 3) {
                        $date = $parts[1];
                        $counter = (int) $parts[2];
                        
                        // Try to find sale created around this time
                        $dateObj = Carbon::createFromFormat('Ymd', $date);
                        if ($dateObj) {
                            $sale = Sale::whereDate('created_at', $dateObj->format('Y-m-d'))
                                ->orderBy('id', 'desc')
                                ->first();
                        }
                    }
                }
                
                if (!$sale) {
                    // Generate emergency receipt
                    $receiptData = $this->generateEmergencyReceipt($identifier);
                    
                    // Check if it's an AJAX/API request
                    if (request()->expectsJson() || request()->is('api/*')) {
                        return response()->json([
                            'success' => false,
                            'message' => 'Sale not found in database. Emergency receipt generated.',
                            'receipt' => $receiptData,
                            'sale_found' => false,
                            'identifier' => $identifier,
                        ]);
                    }
                    
                    // For web requests, show emergency receipt
                    return view('pos.receipts.emergency', [
                        'data' => $receiptData,
                        'autoprint' => false
                    ]);
                }
            }
            
            // Generate receipt data
            $receiptData = $this->generateCompleteReceiptData($sale);
            
            // Make sure unified number is set
            if (!$sale->unified_number && $identifier && str_starts_with($identifier, 'INVRCP-')) {
                $sale->unified_number = $identifier;
                $sale->save();
            }
            
            // Check if it's an AJAX/API request
            if (request()->expectsJson() || request()->is('api/*')) {
                return response()->json([
                    'success' => true,
                    'receipt' => $receiptData,
                    'sale_found' => true,
                    'unified_number' => $sale->unified_number ?? $identifier
                ]);
            }
            
            // For web requests, return the view
            return view('pos.receipts.receipt', [
                'data' => $receiptData,
                'autoprint' => request()->boolean('autoprint')
            ]);
            
        } catch (\Exception $e) {
            Log::error('Receipt generation error', [
                'identifier' => $identifier,
                'error' => $e->getMessage()
            ]);
            
            if (request()->expectsJson()) {
                return response()->json([
                    'success' => false,
                    'message' => 'Error generating receipt: ' . $e->getMessage()
                ], 500);
            }
            
            return $this->showReceiptErrorPage($identifier, 'Error generating receipt: ' . $e->getMessage());
        }
    }
    
    private function isTestIdentifier(string $identifier): bool
    {
        return str_contains($identifier, 'TEST') || 
               str_contains($identifier, 'test') ||
               $identifier === 'preview';
    }
    
    private function showReceiptErrorPage(string $identifier, string $error): \Illuminate\View\View
    {
        return view('pos.receipts.error', [
            'identifier' => $identifier,
            'error' => $error,
            'retry_url' => url()->current(),
            'home_url' => route('pos.index'),
            'timestamp' => now()->toDateTimeString(),
        ]);
    }
    
    private function generateCompleteReceiptData(Sale $sale): array
    {
        // Calculate VAT breakdown
        $vatBreakdown = [];
        $totalVAT = 0;
        $taxableAmount = 0;
        $nonTaxableAmount = 0;
        
        foreach ($sale->items as $item) {
            if ($item->tax_rate > 0 && $item->tax_amount > 0) {
                $rateKey = (int)$item->tax_rate . '%';
                if (!isset($vatBreakdown[$rateKey])) {
                    $vatBreakdown[$rateKey] = [
                        'rate' => $item->tax_rate,
                        'amount' => 0,
                        'taxable_amount' => 0
                    ];
                }
                $vatBreakdown[$rateKey]['amount'] += $item->tax_amount;
                $vatBreakdown[$rateKey]['taxable_amount'] += ($item->price_ex_tax * $item->qty);
                $totalVAT += $item->tax_amount;
            }
            
            // Calculate taxable vs non-taxable amounts
            if ($item->tax_rate > 0) {
                $taxableAmount += ($item->price_ex_tax * $item->qty);
            } else {
                $nonTaxableAmount += ($item->price_ex_tax * $item->qty);
            }
        }
        
        // Format items for receipt
        $items = [];
        foreach ($sale->items as $item) {
            $items[] = [
                'name' => $item->product->name ?? 'Product',
                'sku' => $item->product->sku ?? '',
                'quantity' => $item->qty,
                'unit_price' => $item->price,
                'price_ex_tax' => $item->price_ex_tax ?? $item->price,
                'tax_rate' => $item->tax_rate,
                'tax_amount' => $item->tax_amount,
                'total' => $item->total,
                'is_vatable' => $item->tax_rate > 0,
                'vat_included' => true,
            ];
        }
        
        // Get payment details
        $paymentDetails = [
            'method' => $sale->payment_method,
            'amount_paid' => $sale->grand_total,
            'transaction_id' => $sale->transaction_id,
            'status' => $sale->payment_status,
        ];
        
        // Add method-specific details
        switch ($sale->payment_method) {
            case 'cash':
                $paymentDetails['cash_received'] = $sale->cash_received;
                $paymentDetails['change'] = $sale->customer_change;
                break;
            case 'mpesa':
                $mpesa = $sale->mpesaTransactions->first();
                if ($mpesa) {
                    $paymentDetails['mpesa_details'] = [
                        'phone' => $mpesa->phone,
                        'transaction_id' => $mpesa->transaction_id,
                        'receipt_no' => $mpesa->receipt_no,
                    ];
                }
                break;
            case 'card':
                $paymentDetails['card_details'] = [
                    'last4' => substr($sale->transaction_id ?? '', -4) ?: '****',
                ];
                break;
        }
        
        // FIXED: Customer information - always provide an array
        $customerData = [
            'name' => 'Walk-in Customer',
            'phone' => '',
            'email' => '',
            'company_name' => '',
            'address' => '',
            'pin' => '',
            'vat_number' => '',
            'vat_status' => 'vatable',
        ];
        
        if ($sale->customer) {
            $customerData = [
                'name' => $sale->customer->name ?? 'Walk-in Customer',
                'phone' => $sale->customer->phone ?? '',
                'email' => $sale->customer->email ?? '',
                'company_name' => $sale->customer->company_name ?? '',
                'address' => $sale->customer->address ?? '',
                'pin' => $sale->customer->pin ?? '',
                'vat_number' => $sale->customer->vat_number ?? '',
                'vat_status' => $sale->customer->vat_status ?? 'vatable',
            ];
        }
        
        // Store information
        $storeInfo = [
            'name' => config('app.name', 'Kenyan Supermarket'),
            'address' => config('app.address', 'Nairobi CBD'),
            'phone' => config('app.phone', '0700 000 000'),
            'email' => config('app.email', 'info@supermarket.co.ke'),
            'pin' => config('app.pin', 'P051234567N'),
            'vat_number' => config('app.vat_number', 'VAT001234567'),
            'branch_code' => config('app.branch_code', '001'),
        ];
        
        // Totals
        $totals = [
            'subtotal' => $sale->subtotal,
            'discount' => $sale->discount,
            'taxable_amount' => $sale->taxable_amount ?? $taxableAmount,
            'non_taxable_amount' => $sale->non_taxable_amount ?? $nonTaxableAmount,
            'exempted_amount' => $sale->exempted_amount ?? 0,
            'zero_rated_amount' => $sale->zero_rated_amount ?? 0,
            'vat_amount' => $sale->tax_total,
            'grand_total' => $sale->grand_total,
        ];
        
        // VAT information
        $vatInfo = [
            'customer_status' => $customerData['vat_status'] ?? 'vatable',
            'is_vat_applicable' => $sale->is_vat_applied ?? true,
            'is_zero_rated' => $sale->zero_rated ?? false,
            'is_exempted' => $sale->exempted ?? false,
            'breakdown' => array_values($vatBreakdown),
            'total_vat' => $totalVAT,
        ];
        
        return [
            // Basic Info
            'id' => $sale->id,
            'invoice_no' => $sale->invoice_no,
            'receipt_no' => $sale->receipt_no,
            'transaction_id' => $sale->transaction_id,
            
            // Dates
            'date' => $sale->created_at->format('Y-m-d'),
            'time' => $sale->created_at->format('H:i:s'),
            'timestamp' => $sale->created_at->toISOString(),
            
            // Entities - ALWAYS PROVIDED
            'store' => $storeInfo,
            'customer' => $customerData, // Always exists now
            
            // Items
            'items' => $items,
            
            // Totals
            'totals' => $totals,
            
            // VAT Info
            'vat_info' => $vatInfo,
            
            // Payment
            'payment' => $paymentDetails,
            
            // Personnel
            'cashier' => $sale->user->name ?? 'Cashier',
            'user_id' => $sale->user_id,
            
            // Settings
            'autoprint' => request()->boolean('autoprint'),
            'download' => request()->boolean('download'),
            
            // Notes
            'notes' => [
                'Thank you for your business!',
                'Items sold are not returnable unless defective',
                'Please check goods before leaving the counter',
                'Valid for 7 days from date of purchase for exchanges only',
                'Keep this receipt for warranty claims',
                'VAT Invoice - Valid for Tax Purposes'
            ]
        ];
    }
    
    /**
     * Emergency receipt when sale not found
     */
    private function generateEmergencyReceipt(string $identifier): array
    {
        \Log::warning('Emergency receipt generated', ['identifier' => $identifier]);
        
        $customerData = [
            'name' => 'Walk-in Customer',
            'phone' => '',
            'email' => '',
            'company_name' => '',
            'address' => '',
            'pin' => '',
            'vat_number' => '',
            'vat_status' => 'vatable',
        ];
        
        return [
            'store' => [
                'name' => config('app.name', 'Kenyan Supermarket'),
                'address' => config('app.address', 'Nairobi CBD'),
                'phone' => config('app.phone', '0700 000 000'),
                'pin' => config('app.pin', 'P051234567N'),
                'vat_number' => config('app.vat_number', 'VAT001234567'),
            ],
            'customer' => $customerData, // Always provided
            'invoice_no' => $identifier,
            'receipt_no' => str_replace('INV', 'RCP', $identifier),
            'date' => date('Y-m-d'),
            'time' => date('H:i:s'),
            'cashier' => 'System',
            'items' => [],
            'totals' => [
                'subtotal' => 0,
                'discount' => 0,
                'taxable_amount' => 0,
                'non_taxable_amount' => 0,
                'vat_amount' => 0,
                'grand_total' => 0,
            ],
            'vat_info' => [
                'customer_status' => 'vatable',
                'is_vat_applicable' => false,
                'is_zero_rated' => false,
                'is_exempted' => false,
                'breakdown' => [],
                'total_vat' => 0,
            ],
            'payment' => [
                'method' => 'unknown',
                'amount_paid' => 0,
                'status' => 'unknown'
            ],
            'notes' => [
                '⚠️ Emergency Receipt - Original data not found in database',
                'This receipt was generated from cached information',
                'Please contact support if this is incorrect',
                'Reference: ' . $identifier
            ],
            'autoprint' => false
        ];
    }
    
    /**
     * Display receipt for a sale
     */
    public function printReceipt($id)
    {
        try {
            // Find the sale
            $sale = Sale::with(['items.product', 'customer', 'user', 'payments'])
                        ->where('invoice_no', $id)
                        ->orWhere('receipt_no', $id)
                        ->orWhere('id', $id)
                        ->firstOrFail();
            
            // Generate receipt data
            $receiptData = $this->generateReceiptData($sale);
            
            // Add autoprint flag from query parameter
            $autoprint = request('autoprint', false);
            
            return view('pos.receipts.receipt', [
                'data' => $receiptData,
                'autoprint' => $autoprint
            ]);
            
        } catch (\Exception $e) {
            Log::error('Receipt generation error: ' . $e->getMessage());
            
            return response()->view('errors.404', [
                'message' => 'Receipt not found'
            ], 404);
        }
    }
    
    /**
     * Download receipt as PDF
     */
    public function downloadReceipt($id)
    {
        // Similar to printReceipt but with PDF download headers
        // You'll need to implement PDF generation
        
        try {
            // Find the sale
            $sale = Sale::with(['items.product', 'customer', 'user', 'payments'])
                        ->where('invoice_no', $id)
                        ->orWhere('receipt_no', $id)
                        ->orWhere('id', $id)
                        ->firstOrFail();
            
            // Generate receipt data
            $receiptData = $this->generateReceiptData($sale);
            
            // For now, return JSON with PDF generation info
            return response()->json([
                'success' => true,
                'message' => 'PDF receipt generation not yet implemented',
                'receipt_data' => $receiptData,
                'download_url' => route('receipt.pdf.download', ['id' => $id]),
            ]);
            
        } catch (\Exception $e) {
            Log::error('PDF receipt error: ' . $e->getMessage());
            return response()->json([
                'success' => false,
                'message' => 'Receipt not found'
            ], 404);
        }
    }
}