<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Http\Controllers\Api\Helpers\RestaurantBranchFilterTrait;
use App\Models\PosMenuItem;
use App\Models\Branch;
use App\Helpers\ImageHelper;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;

class AdminMenuItemController extends Controller
{
    use RestaurantBranchFilterTrait;

    public function __construct()
    {
        $this->middleware('auth:sanctum');
    }

    public function index(Request $request)
    {
        $user = $request->user();
        
        // Allow admin, restaurant owners, and branch managers
        if (!$user->isAdmin() && !$user->isRestaurantOwner() && !$user->isBranchManager()) {
            return response()->json(['error' => 'Unauthorized'], 403);
        }

        $query = PosMenuItem::with(['restaurantCategory', 'branch', 'restaurant']);

        // Apply role-based filtering
        if ($user->isAdmin()) {
            // Admin: filter by restaurant and branch if provided
            if ($request->has('restaurant_id') && $request->restaurant_id) {
                $query->where('restaurant_id', $request->restaurant_id);
            }
            if ($request->has('branch_id') && $request->branch_id) {
                $query->where('branch_id', $request->branch_id);
            }
        } elseif ($user->isRestaurantOwner() && $user->restaurant_id) {
            // Restaurant owner: filter by their restaurant
            $query->where('restaurant_id', $user->restaurant_id);
            // Filter by branch if selected - REQUIRED for restaurant owners
            if ($request->has('branch_id') && $request->branch_id) {
                // Verify branch belongs to restaurant
                $branch = Branch::find($request->branch_id);
                if ($branch && $branch->restaurant_id === $user->restaurant_id) {
                    $query->where('branch_id', $request->branch_id);
                } else {
                    // Branch doesn't belong to restaurant or doesn't exist - return empty result
                    $query->whereRaw('1 = 0');
                }
            } else {
                // No branch selected - return empty result (restaurant owner must select branch)
                $query->whereRaw('1 = 0');
            }
        } elseif ($user->isBranchManager() && $user->branch_id) {
            // Branch manager: filter by their branch ONLY
            $query->where('branch_id', $user->branch_id);
            // Also filter by restaurant if branch has restaurant_id
            if (!$user->relationLoaded('branch')) {
                $user->load('branch');
            }
            if ($user->branch && $user->branch->restaurant_id) {
                $query->where('restaurant_id', $user->branch->restaurant_id);
            }
        }

        // Filter by category
        if ($request->has('category_id') && $request->category_id) {
            $query->where('restaurant_category_id', $request->category_id);
        }

        // Filter by status
        if ($request->has('is_available') && $request->is_available !== '') {
            $isAvailable = filter_var($request->is_available, FILTER_VALIDATE_BOOLEAN);
            $query->where('is_available', $isAvailable);
        }

        // Search
        if ($request->has('search') && $request->search) {
            $search = $request->search;
            $query->where(function($q) use ($search) {
                $q->where('name', 'like', '%' . $search . '%')
                  ->orWhere('description', 'like', '%' . $search . '%');
            });
        }

        $items = $query->orderBy('name')->paginate($request->get('per_page', 50));

        // Transform each item to include full resolved image URLs (public/menu_items/...)
        $items->getCollection()->transform(function ($item) {
            return ImageHelper::transformMenuItemImage($item);
        });

        return response()->json($items);
    }

    public function store(Request $request)
    {
        $user = $request->user();
        
        // Allow admin, restaurant owners, and branch managers
        if (!$user->isAdmin() && !$user->isRestaurantOwner() && !$user->isBranchManager()) {
            return response()->json(['error' => 'Unauthorized'], 403);
        }

        $validated = $request->validate([
            'name' => 'required|string|max:255',
            'description' => 'nullable|string',
            'price' => 'required|numeric|min:0',
            'restaurant_category_id' => 'required|exists:restaurant_menu_categories,id',
            'restaurant_id' => 'nullable|exists:restaurants,id',
            'branch_id' => 'nullable|exists:branches,id',
            'is_available' => 'boolean',
            'image' => 'nullable|image|mimes:jpeg,png,jpg,gif|max:2048',
        ]);

        // Get restaurant and branch context
        $context = $this->getRestaurantBranchContext($user, $request);

        // Determine restaurant_id and branch_id based on user role
        $restaurantId = null;
        $branchId = null;

        if ($user->isAdmin()) {
            // Admin must provide restaurant_id and branch_id
            $restaurantId = $validated['restaurant_id'] ?? $context['restaurant_id'] ?? null;
            $branchId = $validated['branch_id'] ?? $context['branch_id'] ?? null;
            
            if (!$restaurantId || !$branchId) {
                return response()->json([
                    'error' => 'Restaurant and branch selection is required'
                ], 422);
            }
        } elseif ($user->isRestaurantOwner()) {
            // Restaurant owner: restaurant_id from user, branch_id from selection
            $restaurantId = $user->restaurant_id;
            $branchId = $validated['branch_id'] ?? $context['branch_id'] ?? $request->input('branch_id');
            
            if (!$branchId) {
                return response()->json([
                    'error' => 'Branch selection is required. Please select a branch first.'
                ], 422);
            }
            
            // Verify branch belongs to restaurant
            $branch = Branch::find($branchId);
            if (!$branch || $branch->restaurant_id !== $restaurantId) {
                return response()->json([
                    'error' => 'Invalid branch. The selected branch does not belong to your restaurant.'
                ], 422);
            }
        } elseif ($user->isBranchManager()) {
            // Branch manager: get from user's branch
            $branchId = $user->branch_id;
            if ($user->branch && $user->branch->restaurant_id) {
                $restaurantId = $user->branch->restaurant_id;
            } else {
                return response()->json([
                    'error' => 'Your branch is not assigned to a restaurant'
                ], 422);
            }
        }

        // Set restaurant_id and branch_id in validated array
        $validated['restaurant_id'] = $restaurantId;
        $validated['branch_id'] = $branchId;

        if ($request->hasFile('image')) {
            $validated['image'] = $request->file('image')->store('menu-items', 'public');
        }

        $validated['is_available'] = $validated['is_available'] ?? true;
        $item = PosMenuItem::create($validated);
        $item->load(['restaurantCategory', 'branch', 'restaurant']);
        $item = ImageHelper::transformMenuItemImage($item);

        return response()->json($item, 201);
    }

    public function show(PosMenuItem $posMenuItem)
    {
        $user = request()->user();
        
        // Allow admin, restaurant owners, and branch managers
        if (!$user->isAdmin() && !$user->isRestaurantOwner() && !$user->isBranchManager()) {
            return response()->json(['error' => 'Unauthorized'], 403);
        }

        // Refresh to ensure latest data
        $posMenuItem->refresh();
        
        // Verify access with proper type casting
        if ($user->isRestaurantOwner()) {
            $itemRestaurantId = $posMenuItem->restaurant_id ? (int) $posMenuItem->restaurant_id : null;
            $userRestaurantId = $user->restaurant_id ? (int) $user->restaurant_id : null;
            if ($itemRestaurantId !== $userRestaurantId) {
                return response()->json(['error' => 'Unauthorized'], 403);
            }
        }
        if ($user->isBranchManager()) {
            if (!$user->branch_id) {
                return response()->json(['error' => 'Unauthorized. Your account is not assigned to a branch.'], 403);
            }
            $itemBranchId = $posMenuItem->branch_id ? (int) $posMenuItem->branch_id : null;
            $userBranchId = (int) $user->branch_id;
            if ($itemBranchId !== null && $itemBranchId !== $userBranchId) {
                return response()->json(['error' => 'Unauthorized'], 403);
            }
        }

        $posMenuItem->load(['restaurantCategory', 'branch', 'restaurant']);
        $posMenuItem = ImageHelper::transformMenuItemImage($posMenuItem);
        return response()->json($posMenuItem);
    }

    public function update(Request $request, PosMenuItem $posMenuItem)
    {
        $user = $request->user();
        
        // Allow admin, restaurant owners, and branch managers
        if (!$user->isAdmin() && !$user->isRestaurantOwner() && !$user->isBranchManager()) {
            return response()->json(['error' => 'Unauthorized'], 403);
        }

        // Refresh to ensure latest data
        $posMenuItem->refresh();
        
        // Verify access with proper type casting
        if ($user->isRestaurantOwner()) {
            $itemRestaurantId = $posMenuItem->restaurant_id ? (int) $posMenuItem->restaurant_id : null;
            $userRestaurantId = $user->restaurant_id ? (int) $user->restaurant_id : null;
            if ($itemRestaurantId !== $userRestaurantId) {
                return response()->json(['error' => 'Unauthorized'], 403);
            }
        }
        if ($user->isBranchManager()) {
            if (!$user->branch_id) {
                return response()->json(['error' => 'Unauthorized. Your account is not assigned to a branch.'], 403);
            }
            $itemBranchId = $posMenuItem->branch_id ? (int) $posMenuItem->branch_id : null;
            $userBranchId = (int) $user->branch_id;
            if ($itemBranchId !== null && $itemBranchId !== $userBranchId) {
                return response()->json(['error' => 'Unauthorized'], 403);
            }
        }

        $validated = $request->validate([
            'name' => 'required|string|max:255',
            'description' => 'nullable|string',
            'price' => 'required|numeric|min:0',
            'restaurant_category_id' => 'required|exists:restaurant_menu_categories,id',
            'restaurant_id' => 'nullable|exists:restaurants,id',
            'branch_id' => 'nullable|exists:branches,id',
            'is_available' => 'boolean',
            'image' => 'nullable|image|mimes:jpeg,png,jpg,gif|max:2048',
        ]);

        // Get restaurant and branch context
        $context = $this->getRestaurantBranchContext($user, $request);

        // Determine restaurant_id and branch_id based on user role
        if ($user->isAdmin()) {
            // Admin can update restaurant_id and branch_id if provided
            if (isset($validated['restaurant_id'])) {
                $validated['restaurant_id'] = $validated['restaurant_id'];
            } else {
                $validated['restaurant_id'] = $posMenuItem->restaurant_id; // Keep existing
            }
            if (isset($validated['branch_id'])) {
                $validated['branch_id'] = $validated['branch_id'];
            } else {
                $validated['branch_id'] = $posMenuItem->branch_id; // Keep existing
            }
        } elseif ($user->isRestaurantOwner()) {
            // Restaurant owner: cannot change restaurant_id, can change branch_id
            $validated['restaurant_id'] = $user->restaurant_id;
            
            $branchId = $validated['branch_id'] ?? $context['branch_id'] ?? $request->input('branch_id') ?? $posMenuItem->branch_id;
            
            // Verify branch belongs to restaurant
            $branch = Branch::find($branchId);
            if (!$branch || $branch->restaurant_id !== $user->restaurant_id) {
                return response()->json([
                    'error' => 'Invalid branch. The selected branch does not belong to your restaurant.'
                ], 422);
            }
            $validated['branch_id'] = $branchId;
        } elseif ($user->isBranchManager()) {
            // Branch manager: cannot change restaurant_id or branch_id
            $validated['restaurant_id'] = $posMenuItem->restaurant_id;
            $validated['branch_id'] = $user->branch_id;
        }

        if ($request->hasFile('image')) {
            if ($posMenuItem->image) {
                Storage::disk('public')->delete($posMenuItem->image);
            }
            $validated['image'] = $request->file('image')->store('menu-items', 'public');
        }

        $posMenuItem->update($validated);
        $posMenuItem->load(['restaurantCategory', 'branch', 'restaurant']);
        $posMenuItem = ImageHelper::transformMenuItemImage($posMenuItem);

        return response()->json($posMenuItem);
    }

    public function destroy(PosMenuItem $posMenuItem)
    {
        $user = request()->user();
        
        // Allow admin, restaurant owners, and branch managers
        if (!$user->isAdmin() && !$user->isRestaurantOwner() && !$user->isBranchManager()) {
            return response()->json(['error' => 'Unauthorized'], 403);
        }

        // Refresh to ensure latest data
        $posMenuItem->refresh();
        
        // Verify access with proper type casting
        if ($user->isRestaurantOwner()) {
            $itemRestaurantId = $posMenuItem->restaurant_id ? (int) $posMenuItem->restaurant_id : null;
            $userRestaurantId = $user->restaurant_id ? (int) $user->restaurant_id : null;
            if ($itemRestaurantId !== $userRestaurantId) {
                return response()->json(['error' => 'Unauthorized'], 403);
            }
        }
        if ($user->isBranchManager()) {
            if (!$user->branch_id) {
                return response()->json(['error' => 'Unauthorized. Your account is not assigned to a branch.'], 403);
            }
            $itemBranchId = $posMenuItem->branch_id ? (int) $posMenuItem->branch_id : null;
            $userBranchId = (int) $user->branch_id;
            if ($itemBranchId !== null && $itemBranchId !== $userBranchId) {
                return response()->json(['error' => 'Unauthorized'], 403);
            }
        }

        if ($posMenuItem->image) {
            Storage::disk('public')->delete($posMenuItem->image);
        }

        $posMenuItem->delete();

        return response()->json(['message' => 'Menu item deleted successfully']);
    }
}

