<?php

namespace App\Http\Controllers\Tenant;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\Tenant\Product;
use App\Models\Tenant\Customer;
use App\Models\Tenant\Sale;
use App\Models\Tenant\ProductVariant;
use App\Models\Tenant\Category;
use App\Models\Tenant\Setting;
use Illuminate\Support\Facades\DB;

class PosController extends Controller
{
    public function index()
    {
        $products = Product::on('tenant')
            ->select('id', 'name', 'unit_id', 'image', 'category_id', 'expiry_date') // Added expiry_date to select
            ->where(function ($query) {
                $query->whereNull('expiry_date')
                      ->orWhere('expiry_date', '>', now());
            })
            ->with([
                'variants' => function($q) {
                    $q->select('id', 'product_id', 'name', 'sku', 'barcode', 'price', 'stock')
                      ->with(['prices.productUnit']); // Load variant specific prices
                },
                'productUnits', // Load alternate units defined for the product
                'unit:id,name,short_name', 
                'brand:id,name',
                'category:id,name'
            ])
            ->limit(500) // Prevent loading too many products at once causing browser hang
            ->get();
        
        $categories = Category::on('tenant')->select('id', 'name')->orderBy('name')->get();

        // Separate customers...
        $customers = Customer::on('tenant')
            ->select('id', 'name', 'is_sub_dealer')
            ->orderBy('name')
            ->get()
            ->map(function($c) {
                return [
                    'id' => $c->id,
                    'name' => $c->name,
                    'type' => $c->is_sub_dealer ? 'Sub-Dealer' : 'Customer'
                ];
            });
        
        // Group products by parent product for variant selection
        $posProducts = $products->map(function ($product) {
            if ($product->variants->isEmpty()) return null;

            // Prepare variant data for each product
            $variants = $product->variants->map(function ($variant) use ($product) {
                // Prepare available units
                $units = [];
                
                // 1. Base Unit
                $units[] = [
                    'id' => 'base',
                    'name' => $product->unit->short_name ?? 'Unit',
                    'factor' => 1,
                    'price' => $variant->price,
                ];

                // 2. Alternate Units
                foreach ($product->productUnits as $pUnit) {
                    // Check if specific price exists for this variant + unit
                    $specificPrice = $variant->prices->where('product_unit_id', $pUnit->id)->first();
                    
                    $price = $specificPrice ? $specificPrice->price : ($variant->price * $pUnit->conversion_factor);

                    $units[] = [
                        'id' => $pUnit->id,
                        'name' => $pUnit->name,
                        'factor' => $pUnit->conversion_factor,
                        'price' => $price,
                    ];
                }

                return [
                    'id' => $variant->id,
                    'product_id' => $product->id,
                    'name' => $variant->name,
                    'sku' => $variant->sku,
                    'barcode' => $variant->barcode,
                    'price' => $variant->price, // Default base price
                    'image' => $product->image ? asset('storage/' . $product->image) : '',
                    'stock' => $variant->stock ?? 0,
                    'unit' => $product->unit->short_name ?? '',
                    'category_id' => $product->category_id ?? '',
                    'available_units' => $units, // Attach units list
                ];
            });

            return [
                'id' => $product->id,
                'name' => $product->name,
                'image' => $product->image ? asset('storage/' . $product->image) : '',
                'category_id' => $product->category_id ?? '',
                'has_variants' => $variants->count() > 1,
                'variants' => $variants->toArray(),
            ];
        })->filter()->values()->all();

        return view('tenant.pos.index', compact('posProducts', 'customers', 'categories'));
    }

    public function store(Request $request)
    {
        $validated = $request->validate([
            'customer_id' => 'nullable|exists:tenant.customers,id',
            'items' => 'required|array',
            'items.*.variant_id' => 'required|exists:tenant.product_variants,id',
            'items.*.quantity' => 'required|numeric|min:0.01',
            'items.*.price' => 'required|numeric|min:0',
            'items.*.unit_id' => 'nullable', // Can be ID or 'base' or null
            'items.*.discount_type' => 'nullable|in:none,fixed,percent',
            'items.*.discount_value' => 'nullable|numeric|min:0',
            'subtotal' => 'required|numeric|min:0',
            'discount' => 'nullable|numeric|min:0',
            'total' => 'required|numeric|min:0',
            'payment_type' => 'required|string|in:cash,card,due',
            'paid_amount' => 'required|numeric|min:0',
            'note' => 'nullable|string',
            'status' => 'required|in:completed,hold',
        ]);

        try {
            DB::transaction(function () use ($validated, $request) {
                // ... (Sale Creation remains same) ...
                // Determine payment status
                $paymentStatus = 'paid';
                if ($validated['payment_type'] === 'due') {
                    $paymentStatus = 'due';
                } elseif ($validated['paid_amount'] < $validated['total']) {
                    $paymentStatus = 'partial';
                }

                $invoiceNo = 'INV-' . date('Ymd') . '-' . strtoupper(uniqid());
                
                $sale = Sale::create([
                    'invoice_no' => $invoiceNo,
                    'customer_id' => $validated['customer_id'],
                    'subtotal' => $validated['subtotal'],
                    'discount' => $validated['discount'] ?? 0,
                    'total' => $validated['total'],
                    'paid_amount' => $validated['paid_amount'],
                    'payment_method' => $validated['payment_type'],
                    'payment_status' => $paymentStatus,
                    'status' => $validated['status'], // 'completed' or 'hold'
                    'note' => $validated['note'] . ($request->transaction_id ? " | Trans ID: {$request->transaction_id}" : ''),
                ]);

                // Award Loyalty Points
                if ($validated['status'] === 'completed' && Setting::get('loyalty_enabled') == '1') {
                        $customerId = $validated['customer_id'];
                        if ($customerId) {
                            $points = floor($validated['total']); 
                            Customer::where('id', $customerId)->increment('loyalty_points', $points);
                        }
                }

                // Update Customer Due/Credit Balance if needed
                if ($validated['customer_id'] && $paymentStatus !== 'paid') {
                     $customer = Customer::find($validated['customer_id']);
                     $dueAmount = $validated['total'] - $validated['paid_amount'];
                     // $customer->increment('balance', $dueAmount); 
                }

                // Create Sale Items
                foreach ($validated['items'] as $item) {
                    // Determine Unit and Conversion
                    $productUnitId = null;
                    $conversionFactor = 1;

                    if (!empty($item['unit_id']) && $item['unit_id'] !== 'base') {
                        $productUnit = \App\Models\Tenant\ProductUnit::find($item['unit_id']);
                        if ($productUnit) {
                            $productUnitId = $productUnit->id;
                            $conversionFactor = $productUnit->conversion_factor;
                        }
                    }

                    $sale->items()->create([
                        'variant_id' => $item['variant_id'],
                        'product_unit_id' => $productUnitId,
                        'conversion_factor' => $conversionFactor,
                        'quantity' => $item['quantity'],
                        'price' => $item['price'],
                        'discount_type' => $item['discount_type'] ?? 'none',
                        'discount_value' => $item['discount_value'] ?? 0,
                        'total' => ($item['quantity'] * $item['price']) - ($this->calculateLineDiscount($item)),
                    ]);
                    
                    // Deduct Stock only if completed
                    if ($validated['status'] === 'completed') {
                         $variant = ProductVariant::find($item['variant_id']);
                         if ($variant) {
                             $deductQty = $item['quantity'] * $conversionFactor;
                             $variant->decrement('stock', $deductQty);
                             
                             // Record stock movement
                             \App\Models\Tenant\StockMovement::record(
                                 $item['variant_id'],
                                 $deductQty,
                                 'sale',
                                 'sale',
                                 $sale->id,
                                 "Sale #{$sale->invoice_no} - {$item['quantity']} units sold"
                             );
                         }
                    }
                }
            });

            return response()->json(['success' => true, 'message' => 'Sale processed successfully!']);
        } catch (\Exception $e) {
            return response()->json(['success' => false, 'message' => 'Sale failed: ' . $e->getMessage()], 500);
        }
    }

    private function calculateLineDiscount($item)
    {
        $total = $item['quantity'] * $item['price'];
        $type = $item['discount_type'] ?? 'none';
        $value = $item['discount_value'] ?? 0;

        if ($type === 'fixed') {
            return min($total, $value);
        } elseif ($type === 'percent') {
            return $total * ($value / 100);
        }
        return 0;
    }
}
