<?php

namespace App\Http\Controllers;

use App\Models\HoldSale;
use App\Models\Customer;
use App\Models\Product;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
use Carbon\Carbon;

class HoldSaleController extends Controller
{
    /**
     * Get all held sales with pagination
     */
    public function index(Request $request)
    {
        try {
            $userId = auth()->id();
            $search = $request->input('q', '');
            $status = $request->input('status', 'active');
            $date = $request->input('date', '');
            
            $query = HoldSale::with(['customer', 'user'])
                ->byUser($userId)
                ->orderBy('created_at', 'desc');
            
            // Apply search filter
            if ($search) {
                $query->where(function($q) use ($search) {
                    $q->where('reference', 'like', "%{$search}%")
                      ->orWhereHas('customer', function($q2) use ($search) {
                          $q2->where('name', 'like', "%{$search}%")
                             ->orWhere('phone', 'like', "%{$search}%");
                      })
                      ->orWhere('notes', 'like', "%{$search}%");
                });
            }
            
            // Apply status filter
            switch ($status) {
                case 'active':
                    $query->active();
                    break;
                case 'expired':
                    $query->expired();
                    break;
                case 'converted':
                    $query->converted();
                    break;
                case 'all':
                    // No filter
                    break;
            }
            
            // Apply date filter
            if ($date) {
                switch ($date) {
                    case 'today':
                        $query->whereDate('created_at', today());
                        break;
                    case 'yesterday':
                        $query->whereDate('created_at', today()->subDay());
                        break;
                    case 'week':
                        $query->whereDate('created_at', '>=', today()->subDays(7));
                        break;
                    case 'month':
                        $query->whereMonth('created_at', now()->month);
                        break;
                }
            }
            
            $holds = $query->paginate($request->input('per_page', 20));
            
            return response()->json([
                'success' => true,
                'holds' => $holds->items(),
                'pagination' => [
                    'current_page' => $holds->currentPage(),
                    'last_page' => $holds->lastPage(),
                    'per_page' => $holds->perPage(),
                    'total' => $holds->total(),
                ]
            ]);
            
        } catch (\Exception $e) {
            Log::error('Get held sales error: ' . $e->getMessage());
            return response()->json(['success' => false, 'error' => 'Failed to get held sales'], 500);
        }
    }
    
    /**
     * Get held sale statistics
     */
    public function stats()
    {
        try {
            $userId = auth()->id();
            $now = now();
            
            $stats = [
                'active_holds' => HoldSale::byUser($userId)->active()->count(),
                'total_value' => HoldSale::byUser($userId)->active()->sum('total'),
                'expiring_soon' => HoldSale::byUser($userId)
                    ->active()
                    ->where('expires_at', '<=', $now->addHour())
                    ->where('expires_at', '>', $now)
                    ->count(),
                'todays_holds' => HoldSale::byUser($userId)
                    ->whereDate('created_at', today())
                    ->count(),
                'total_holds' => HoldSale::byUser($userId)->count(),
            ];
            
            return response()->json([
                'success' => true,
                'stats' => $stats
            ]);
            
        } catch (\Exception $e) {
            Log::error('Get held stats error: ' . $e->getMessage());
            return response()->json(['success' => false, 'error' => 'Failed to get stats'], 500);
        }
    }
    
    /**
     * Create new hold sale
     */
  public function store(Request $request)
{
    DB::beginTransaction();
    
    try {
        // Accept both 'price' and 'unit_price' from frontend
        $validated = $request->validate([
            'customer_id' => 'nullable|exists:customers,id',
            'items' => 'required|array|min:1',
            'items.*.product_id' => 'required|exists:products,id',
            'items.*.name' => 'required|string',
            'items.*.quantity' => 'required|numeric|min:0.001',
            'items.*.unit_price' => 'required|numeric|min:0',
            'items.*.price' => 'nullable|numeric|min:0', // Accept 'price' as fallback
            'items.*.total' => 'nullable|numeric|min:0',
            'subtotal' => 'required|numeric|min:0',
            'vat' => 'required|numeric|min:0',
            'discount' => 'required|numeric|min:0',
            'total' => 'required|numeric|min:0',
            'notes' => 'nullable|string|max:500'
        ]);

        // Normalize item prices: use unit_price if provided, otherwise price
        foreach ($validated['items'] as &$item) {
            if (empty($item['unit_price']) && !empty($item['price'])) {
                $item['unit_price'] = $item['price'];
            }
            unset($item['price']); // Remove duplicate field
        }

        $reference = HoldSale::generateReference();
        
        $hold = HoldSale::create([
            'reference' => $reference,
            'customer_id' => $validated['customer_id'] ?? null,
            'user_id' => auth()->id(), // Match your model's 'user_id' field
            'items' => $validated['items'],
            'subtotal' => $validated['subtotal'],
            'vat' => $validated['vat'],
            'discount' => $validated['discount'],
            'total' => $validated['total'],
            'notes' => $validated['notes'] ?? null,
            'status' => 'active',
            'expires_at' => now()->addHours(24),
        ]);

        DB::commit();
        
        return response()->json([
            'success' => true,
            'hold' => [
                'id' => $hold->id,
                'reference' => $hold->reference,
                'total' => $hold->total,
                'expires_at' => $hold->expires_at,
            ],
            'message' => 'Sale held successfully'
        ]);
        
    } catch (\Exception $e) {
        DB::rollBack();
        Log::error('Hold sale error: ' . $e->getMessage());
        return response()->json([
            'success' => false, 
            'error' => 'Failed to hold sale: ' . $e->getMessage()
        ], 500);
    }
}
    
    /**
     * Get single hold sale
     */
    public function show($id)
    {
        try {
            $hold = HoldSale::with(['customer', 'user'])
                ->where('id', $id)
                ->where('user_id', auth()->id())
                ->firstOrFail();
            
            return response()->json([
                'success' => true,
                'hold' => [
                    'id' => $hold->id,
                    'reference' => $hold->reference,
                    'customer' => $hold->customer ? [
                        'id' => $hold->customer->id,
                        'name' => $hold->customer->name,
                        'phone' => $hold->customer->phone,
                        'email' => $hold->customer->email,
                    ] : null,
                    'items' => $hold->items,
                    'subtotal' => (float) $hold->subtotal,
                    'vat' => (float) $hold->vat,
                    'discount' => (float) $hold->discount,
                    'total' => (float) $hold->total,
                    'status' => $hold->status,
                    'is_expired' => $hold->is_expired,
                    'held_by' => $hold->user ? $hold->user->name : 'Unknown',
                    'created_at' => $hold->created_at->toISOString(),
                    'expires_at' => $hold->expires_at->toISOString(),
                    'expires_in' => $hold->expires_at ? $hold->expires_at->diffForHumans() : null,
                    'notes' => $hold->notes,
                ]
            ]);
            
        } catch (\Exception $e) {
            Log::error('Get hold sale error: ' . $e->getMessage());
            return response()->json(['success' => false, 'error' => 'Hold sale not found'], 404);
        }
    }
    
    /**
     * Load hold sale into cart
     */
    public function load($id)
    {
        try {
            $hold = HoldSale::with(['customer'])
                ->where('id', $id)
                ->where('user_id', auth()->id())
                ->firstOrFail();
            
            // Check if expired
            if ($hold->is_expired) {
                $hold->markAsExpired();
                return response()->json([
                    'success' => false,
                    'error' => 'This hold sale has expired'
                ], 400);
            }
            
            // Check if already converted
            if ($hold->status === 'converted') {
                return response()->json([
                    'success' => false,
                    'error' => 'This hold sale has already been converted to a sale'
                ], 400);
            }
            
            // Get current product information
            $productIds = collect($hold->items)->pluck('product_id');
            $products = Product::with('tax')
                ->whereIn('id', $productIds)
                ->get()
                ->keyBy('id');
            
            $loadedItems = [];
            foreach ($hold->items as $item) {
                $product = $products[$item['product_id']] ?? null;
                if ($product) {
                    $loadedItems[] = [
                        'id' => $product->id,
                        'sku' => $product->sku,
                        'barcode' => $product->barcode,
                        'name' => $product->name,
                        'price' => $item['price'] ?? $product->sale_price,
                        'quantity' => $item['quantity'] ?? 1,
                        'has_vat' => $product->has_vat,
                        'tax_rate' => $product->tax_rate,
                        'stock' => $product->stock,
                        'original_item' => $item,
                    ];
                } else {
                    // Product might have been deleted, use original data
                    $loadedItems[] = [
                        'id' => $item['product_id'] ?? 0,
                        'sku' => 'N/A',
                        'barcode' => 'N/A',
                        'name' => $item['name'] ?? 'Unknown Product',
                        'price' => $item['price'] ?? 0,
                        'quantity' => $item['quantity'] ?? 1,
                        'has_vat' => false,
                        'tax_rate' => 0,
                        'stock' => 0,
                        'original_item' => $item,
                        'warning' => 'Product not found in system',
                    ];
                }
            }
            
            return response()->json([
                'success' => true,
                'items' => $loadedItems,
                'customer' => $hold->customer ? [
                    'id' => $hold->customer->id,
                    'name' => $hold->customer->name,
                    'phone' => $hold->customer->phone,
                    'email' => $hold->customer->email,
                ] : null,
                'discount' => (float) $hold->discount,
                'subtotal' => (float) $hold->subtotal,
                'vat' => (float) $hold->vat,
                'total' => (float) $hold->total,
                'notes' => $hold->notes,
                'hold_id' => $hold->id,
                'reference' => $hold->reference,
            ]);
            
        } catch (\Exception $e) {
            Log::error('Load hold sale error: ' . $e->getMessage());
            return response()->json(['success' => false, 'error' => 'Failed to load hold sale'], 500);
        }
    }
    
    /**
     * Delete hold sale
     */
    public function destroy($id)
    {
        try {
            $hold = HoldSale::where('id', $id)
                ->where('user_id', auth()->id())
                ->firstOrFail();
            
            $hold->delete();
            
            return response()->json([
                'success' => true,
                'message' => 'Hold sale deleted successfully'
            ]);
            
        } catch (\Exception $e) {
            Log::error('Delete hold sale error: ' . $e->getMessage());
            return response()->json(['success' => false, 'error' => 'Failed to delete hold sale'], 500);
        }
    }
    
    /**
     * Clear expired holds
     */
    public function clearExpired()
    {
        try {
            $expiredCount = HoldSale::byUser(auth()->id())
                ->expired()
                ->delete();
            
            return response()->json([
                'success' => true,
                'cleared_count' => $expiredCount,
                'message' => "Cleared {$expiredCount} expired hold sales"
            ]);
            
        } catch (\Exception $e) {
            Log::error('Clear expired holds error: ' . $e->getMessage());
            return response()->json(['success' => false, 'error' => 'Failed to clear expired holds'], 500);
        }
    }
    
    /**
     * Extend hold validity
     */
    public function extend($id, Request $request)
    {
        try {
            $validated = $request->validate([
                'hours' => 'required|integer|min:1|max:168' // Max 7 days
            ]);
            
            $hold = HoldSale::where('id', $id)
                ->where('user_id', auth()->id())
                ->firstOrFail();
            
            $hold->extendValidity($validated['hours']);
            
            return response()->json([
                'success' => true,
                'message' => 'Hold validity extended successfully',
                'new_expiry' => $hold->expires_at->toISOString()
            ]);
            
        } catch (\Exception $e) {
            Log::error('Extend hold error: ' . $e->getMessage());
            return response()->json(['success' => false, 'error' => 'Failed to extend hold'], 500);
        }
    }
}