<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\RestaurantMenuCategory;
use App\Models\PosMenuItem;
use App\Models\MenuItemRecipe;
use App\Models\Item;
use App\Models\Branch;
use Illuminate\Http\Request;
use Maatwebsite\Excel\Facades\Excel;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

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

    /**
     * Download menu categories template
     */
    public function downloadMenuCategoriesTemplate()
    {
        $headers = ['Name', 'Description', 'Sort Order', 'Status'];
        
        $sample = [
            $headers,
            ['All Menu items', 'All menu items category', '0', 'active'],
            ['Desi Food', 'Traditional Pakistani/Indian food', '1', 'active'],
            ['Fast Food', 'Quick service items', '2', 'active'],
            ['Beverages', 'Drinks and beverages', '3', 'active'],
            ['Desserts', 'Sweet items and desserts', '4', 'active'],
        ];

        return Excel::download(
            new class($sample) implements \Maatwebsite\Excel\Concerns\FromArray {
                protected $data;
                public function __construct($data) { $this->data = $data; }
                public function array(): array { return $this->data; }
            },
            'menu_categories_template_' . date('Y-m-d') . '.xlsx'
        );
    }

    /**
     * Import menu categories from Excel
     */
    public function importMenuCategories(Request $request)
    {
        $request->validate([
            'file' => 'required|mimes:xlsx,xls,csv|max:5120',
        ]);

        $user = $request->user();

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

        if ($user->isAdmin()) {
            if (!$request->has('restaurant_id') || !$request->restaurant_id) {
                return response()->json(['error' => 'Restaurant selection is required'], 400);
            }
            if (!$request->has('branch_id') || !$request->branch_id) {
                return response()->json(['error' => 'Branch selection is required'], 400);
            }
            $restaurantId = $request->restaurant_id;
            $branchId = $request->branch_id;
        } elseif ($user->isRestaurantOwner() && $user->restaurant_id) {
            $restaurantId = $user->restaurant_id;
            if (!$request->has('branch_id') || !$request->branch_id) {
                return response()->json(['error' => 'Branch selection is required'], 400);
            }
            $branchId = $request->branch_id;
            // Verify branch belongs to their restaurant
            $branch = Branch::findOrFail($branchId);
            if ($branch->restaurant_id != $restaurantId) {
                return response()->json(['error' => 'You do not have access to this branch'], 403);
            }
        } elseif ($user->isBranchManager() && $user->branch_id) {
            $branch = Branch::findOrFail($user->branch_id);
            if (!$branch || !$branch->restaurant_id) {
                return response()->json(['error' => 'Branch not found'], 400);
            }
            $restaurantId = $branch->restaurant_id;
            $branchId = $user->branch_id;
        } else {
            return response()->json(['error' => 'Unauthorized'], 403);
        }

        try {
            $file = $request->file('file');
            $data = Excel::toArray([], $file);
            
            if (empty($data) || empty($data[0])) {
                return response()->json(['error' => 'File is empty'], 400);
            }

            $rows = $data[0];
            $headers = array_shift($rows); // Remove header row

            $imported = 0;
            $skipped = 0;
            $errors = [];

            DB::beginTransaction();

            foreach ($rows as $index => $row) {
                try {
                    if (empty($row[0])) continue; // Skip empty rows

                    $name = trim($row[0] ?? '');
                    $description = trim($row[1] ?? '');
                    $sortOrder = isset($row[2]) && $row[2] !== '' ? (int) $row[2] : 0;
                    $status = isset($row[3]) ? strtolower(trim($row[3])) : 'active';
                    $status = in_array($status, ['active', 'inactive', '1', '0', 'true', 'false']) 
                        ? (in_array($status, ['active', '1', 'true']) ? true : false)
                        : true;

                    if (empty($name)) {
                        $skipped++;
                        $errors[] = "Row " . ($index + 2) . ": Name is required";
                        continue;
                    }

                    // Special handling for "All Menu items" category
                    if (strtolower($name) === 'all menu items' && $sortOrder == 0) {
                        // Create for all branches of the restaurant
                        $branches = Branch::where('restaurant_id', $restaurantId)->get();
                        $createdCount = 0;
                        foreach ($branches as $branch) {
                            // Check if already exists for this branch (case-insensitive)
                            $existingBranch = RestaurantMenuCategory::whereRaw('LOWER(name) = ?', [strtolower($name)])
                                ->where('restaurant_id', $restaurantId)
                                ->where('branch_id', $branch->id)
                                ->first();
                            
                            if (!$existingBranch) {
                                RestaurantMenuCategory::create([
                                    'name' => $name,
                                    'description' => $description,
                                    'sort_order' => 0,
                                    'status' => $status,
                                    'restaurant_id' => $restaurantId,
                                    'branch_id' => $branch->id,
                                ]);
                                $createdCount++;
                            }
                        }
                        if ($createdCount > 0) {
                            $imported += $createdCount;
                        } else {
                            $skipped++;
                            $errors[] = "Row " . ($index + 2) . ": Category '{$name}' already exists for all branches";
                        }
                    } else {
                        // Regular category - check if already exists for this restaurant/branch (case-insensitive)
                        $existing = RestaurantMenuCategory::whereRaw('LOWER(name) = ?', [strtolower($name)])
                            ->where('restaurant_id', $restaurantId)
                            ->where('branch_id', $branchId)
                            ->first();

                        if ($existing) {
                            $skipped++;
                            $errors[] = "Row " . ($index + 2) . ": Category '{$name}' already exists for this branch";
                            continue;
                        }

                        // Regular category - create for selected branch
                        RestaurantMenuCategory::create([
                            'name' => $name,
                            'description' => $description,
                            'sort_order' => $sortOrder,
                            'status' => $status,
                            'restaurant_id' => $restaurantId,
                            'branch_id' => $branchId,
                        ]);
                        $imported++;
                    }
                } catch (\Exception $e) {
                    $skipped++;
                    $errors[] = "Row " . ($index + 2) . ": " . $e->getMessage();
                    Log::error('Error importing menu category row: ' . $e->getMessage());
                }
            }

            DB::commit();

            return response()->json([
                'message' => 'Import completed',
                'imported' => $imported,
                'skipped' => $skipped,
                'errors' => $errors
            ], 200);

        } catch (\Exception $e) {
            DB::rollBack();
            Log::error('Error importing menu categories: ' . $e->getMessage());
            return response()->json([
                'error' => 'Failed to import menu categories: ' . $e->getMessage()
            ], 500);
        }
    }

    /**
     * Download menu items template
     */
    public function downloadMenuItemsTemplate()
    {
        $headers = ['Name', 'Description', 'Category Name', 'Price', 'Sort Order'];
        
        $sample = [
            $headers,
            ['Chicken Biryani', 'Traditional biryani with chicken', 'Desi Food', '15.00', '1'],
            ['Beef Karahi', 'Spicy beef curry', 'Desi Food', '18.00', '2'],
            ['Pizza', 'Italian pizza', 'Fast Food', '12.00', '1'],
            ['Burger', 'Classic burger', 'Fast Food', '10.00', '2'],
            ['Coke', 'Soft drink', 'Beverages', '2.00', '1'],
            ['Pepsi', 'Soft drink', 'Beverages', '2.00', '2'],
            ['Ice Cream', 'Vanilla ice cream', 'Desserts', '5.00', '1'],
        ];

        return Excel::download(
            new class($sample) implements \Maatwebsite\Excel\Concerns\FromArray {
                protected $data;
                public function __construct($data) { $this->data = $data; }
                public function array(): array { return $this->data; }
            },
            'menu_items_template_' . date('Y-m-d') . '.xlsx'
        );
    }

    /**
     * Import menu items from Excel
     */
    public function importMenuItems(Request $request)
    {
        $request->validate([
            'file' => 'required|mimes:xlsx,xls,csv|max:5120',
        ]);

        $user = $request->user();

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

        if ($user->isAdmin()) {
            if (!$request->has('restaurant_id') || !$request->restaurant_id) {
                return response()->json(['error' => 'Restaurant selection is required'], 400);
            }
            if (!$request->has('branch_id') || !$request->branch_id) {
                return response()->json(['error' => 'Branch selection is required'], 400);
            }
            $restaurantId = $request->restaurant_id;
            $branchId = $request->branch_id;
        } elseif ($user->isRestaurantOwner() && $user->restaurant_id) {
            $restaurantId = $user->restaurant_id;
            if (!$request->has('branch_id') || !$request->branch_id) {
                return response()->json(['error' => 'Branch selection is required'], 400);
            }
            $branchId = $request->branch_id;
            // Verify branch belongs to their restaurant
            $branch = Branch::findOrFail($branchId);
            if ($branch->restaurant_id != $restaurantId) {
                return response()->json(['error' => 'You do not have access to this branch'], 403);
            }
        } elseif ($user->isBranchManager() && $user->branch_id) {
            $branch = Branch::findOrFail($user->branch_id);
            if (!$branch || !$branch->restaurant_id) {
                return response()->json(['error' => 'Branch not found'], 400);
            }
            $restaurantId = $branch->restaurant_id;
            $branchId = $user->branch_id;
        } else {
            return response()->json(['error' => 'Unauthorized'], 403);
        }

        try {
            $file = $request->file('file');
            $data = Excel::toArray([], $file);
            
            if (empty($data) || empty($data[0])) {
                return response()->json(['error' => 'File is empty'], 400);
            }

            $rows = $data[0];
            $headers = array_shift($rows); // Remove header row

            $imported = 0;
            $skipped = 0;
            $errors = [];

            DB::beginTransaction();

            foreach ($rows as $index => $row) {
                try {
                    if (empty($row[0])) continue; // Skip empty rows

                    $name = trim($row[0] ?? '');
                    $description = trim($row[1] ?? '');
                    $categoryName = trim($row[2] ?? '');
                    $price = isset($row[3]) && $row[3] !== '' ? (float) $row[3] : 0;
                    $sortOrder = isset($row[4]) && $row[4] !== '' ? (int) $row[4] : 0;
                    // Set is_available to true by default for all imported items
                    $isAvailable = true;

                    if (empty($name)) {
                        $skipped++;
                        $errors[] = "Row " . ($index + 2) . ": Name is required";
                        continue;
                    }

                    if (empty($categoryName)) {
                        $skipped++;
                        $errors[] = "Row " . ($index + 2) . ": Category Name is required";
                        continue;
                    }

                    if ($price < 0) {
                        $skipped++;
                        $errors[] = "Row " . ($index + 2) . ": Price must be greater than or equal to 0";
                        continue;
                    }

                    // Find category by name (case-insensitive)
                    $category = RestaurantMenuCategory::whereRaw('LOWER(name) = ?', [strtolower($categoryName)])
                        ->where('restaurant_id', $restaurantId)
                        ->where('branch_id', $branchId)
                        ->first();

                    if (!$category) {
                        $skipped++;
                        $errors[] = "Row " . ($index + 2) . ": Category '{$categoryName}' not found. Please create the category first.";
                        continue;
                    }

                    // Check if menu item already exists for this branch (case-insensitive)
                    $existing = PosMenuItem::whereRaw('LOWER(name) = ?', [strtolower($name)])
                        ->where('restaurant_id', $restaurantId)
                        ->where('branch_id', $branchId)
                        ->first();

                    if ($existing) {
                        $skipped++;
                        $errors[] = "Row " . ($index + 2) . ": Menu item '{$name}' already exists for this branch";
                        continue;
                    }

                    // Create menu item
                    PosMenuItem::create([
                        'name' => $name,
                        'description' => $description,
                        'price' => $price,
                        'restaurant_category_id' => $category->id,
                        'restaurant_category_name' => $category->name,
                        'sort_order' => $sortOrder,
                        'is_available' => $isAvailable,
                        'restaurant_id' => $restaurantId,
                        'branch_id' => $branchId,
                    ]);

                    $imported++;
                } catch (\Exception $e) {
                    $skipped++;
                    $errors[] = "Row " . ($index + 2) . ": " . $e->getMessage();
                    Log::error('Error importing menu item row: ' . $e->getMessage());
                }
            }

            DB::commit();

            return response()->json([
                'message' => 'Import completed',
                'imported' => $imported,
                'skipped' => $skipped,
                'errors' => $errors
            ], 200);

        } catch (\Exception $e) {
            DB::rollBack();
            Log::error('Error importing menu items: ' . $e->getMessage());
            return response()->json([
                'error' => 'Failed to import menu items: ' . $e->getMessage()
            ], 500);
        }
    }

    /**
     * Download menu item recipes template
     */
    public function downloadMenuItemRecipesTemplate()
    {
        $headers = ['Menu Item Name', 'Inventory Item Name', 'Quantity', 'Unit', 'Details', 'Sort Order'];
        
        $sample = [
            $headers,
            ['Chicken Biryani', 'Chicken', '500', 'g', 'Boneless chicken pieces', '1'],
            ['Chicken Biryani', 'Basmati Rice', '250', 'g', 'Long grain rice', '2'],
            ['Chicken Biryani', 'Onions', '100', 'g', 'Sliced onions', '3'],
            ['Beef Karahi', 'Beef', '500', 'g', 'Cubed beef', '1'],
            ['Beef Karahi', 'Tomatoes', '200', 'g', 'Fresh tomatoes', '2'],
            ['Pizza', 'Flour', '300', 'g', 'All-purpose flour', '1'],
            ['Pizza', 'Cheese', '150', 'g', 'Mozzarella cheese', '2'],
        ];

        return Excel::download(
            new class($sample) implements \Maatwebsite\Excel\Concerns\FromArray {
                protected $data;
                public function __construct($data) { $this->data = $data; }
                public function array(): array { return $this->data; }
            },
            'menu_item_recipes_template_' . date('Y-m-d') . '.xlsx'
        );
    }

    /**
     * Import menu item recipes from Excel
     */
    public function importMenuItemRecipes(Request $request)
    {
        $request->validate([
            'file' => 'required|mimes:xlsx,xls,csv|max:5120',
        ]);

        $user = $request->user();

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

        if ($user->isAdmin()) {
            if (!$request->has('restaurant_id') || !$request->restaurant_id) {
                return response()->json(['error' => 'Restaurant selection is required'], 400);
            }
            if (!$request->has('branch_id') || !$request->branch_id) {
                return response()->json(['error' => 'Branch selection is required'], 400);
            }
            $restaurantId = $request->restaurant_id;
            $branchId = $request->branch_id;
        } elseif ($user->isRestaurantOwner() && $user->restaurant_id) {
            $restaurantId = $user->restaurant_id;
            if (!$request->has('branch_id') || !$request->branch_id) {
                return response()->json(['error' => 'Branch selection is required'], 400);
            }
            $branchId = $request->branch_id;
            // Verify branch belongs to their restaurant
            $branch = Branch::findOrFail($branchId);
            if ($branch->restaurant_id != $restaurantId) {
                return response()->json(['error' => 'You do not have access to this branch'], 403);
            }
        } elseif ($user->isBranchManager() && $user->branch_id) {
            $branch = Branch::findOrFail($user->branch_id);
            if (!$branch || !$branch->restaurant_id) {
                return response()->json(['error' => 'Branch not found'], 400);
            }
            $restaurantId = $branch->restaurant_id;
            $branchId = $user->branch_id;
        } else {
            return response()->json(['error' => 'Unauthorized'], 403);
        }

        try {
            $file = $request->file('file');
            $data = Excel::toArray([], $file);
            
            if (empty($data) || empty($data[0])) {
                return response()->json(['error' => 'File is empty'], 400);
            }

            $rows = $data[0];
            $headers = array_shift($rows); // Remove header row

            $imported = 0;
            $skipped = 0;
            $errors = [];

            DB::beginTransaction();

            foreach ($rows as $index => $row) {
                try {
                    if (empty($row[0])) continue; // Skip empty rows

                    $menuItemName = trim($row[0] ?? '');
                    $inventoryItemName = trim($row[1] ?? '');
                    $quantity = isset($row[2]) && $row[2] !== '' ? (float) $row[2] : 0;
                    $unit = isset($row[3]) ? trim($row[3] ?? '') : '';
                    $details = isset($row[4]) ? trim($row[4] ?? '') : null;
                    $sortOrder = isset($row[5]) && $row[5] !== '' ? (int) $row[5] : 0;

                    if (empty($menuItemName)) {
                        $skipped++;
                        $errors[] = "Row " . ($index + 2) . ": Menu Item Name is required";
                        continue;
                    }

                    if (empty($inventoryItemName)) {
                        $skipped++;
                        $errors[] = "Row " . ($index + 2) . ": Inventory Item Name is required";
                        continue;
                    }

                    if ($quantity <= 0) {
                        $skipped++;
                        $errors[] = "Row " . ($index + 2) . ": Quantity must be greater than 0";
                        continue;
                    }

                    // Find menu item by name (case-insensitive) for the selected branch
                    $menuItem = PosMenuItem::whereRaw('LOWER(name) = ?', [strtolower($menuItemName)])
                        ->where('restaurant_id', $restaurantId)
                        ->where('branch_id', $branchId)
                        ->first();

                    if (!$menuItem) {
                        $skipped++;
                        $errors[] = "Row " . ($index + 2) . ": Menu item '{$menuItemName}' not found for this branch";
                        continue;
                    }

                    // Find inventory item by name (case-insensitive)
                    $inventoryItem = Item::whereRaw('LOWER(name) = ?', [strtolower($inventoryItemName)])
                        ->first();

                    if (!$inventoryItem) {
                        $skipped++;
                        $errors[] = "Row " . ($index + 2) . ": Inventory item '{$inventoryItemName}' not found";
                        continue;
                    }

                    // Convert unit: g -> gram, kg stays as kg, kilogram -> kg
                    $unit = strtolower(trim($unit));
                    if ($unit === 'g') {
                        $unit = 'gram';
                    } elseif ($unit === 'kilogram') {
                        $unit = 'kg';
                    }
                    // 'kg' stays as 'kg'

                    // Check if recipe already exists (same menu item + inventory item combination)
                    $existing = MenuItemRecipe::where('menu_item_id', $menuItem->id)
                        ->where('inventory_item_id', $inventoryItem->id)
                        ->first();

                    if ($existing) {
                        $skipped++;
                        $errors[] = "Row " . ($index + 2) . ": Recipe for '{$menuItemName}' with '{$inventoryItemName}' already exists";
                        continue;
                    }

                    // Create recipe
                    MenuItemRecipe::create([
                        'menu_item_id' => $menuItem->id,
                        'inventory_item_id' => $inventoryItem->id,
                        'quantity' => round($quantity, 2),
                        'unit' => $unit,
                        'details' => $details,
                        'sort_order' => $sortOrder,
                        'restaurant_id' => $restaurantId,
                    ]);

                    $imported++;
                } catch (\Exception $e) {
                    $skipped++;
                    $errors[] = "Row " . ($index + 2) . ": " . $e->getMessage();
                    Log::error('Error importing menu item recipe row: ' . $e->getMessage());
                }
            }

            DB::commit();

            return response()->json([
                'message' => 'Import completed',
                'imported' => $imported,
                'skipped' => $skipped,
                'errors' => $errors
            ], 200);

        } catch (\Exception $e) {
            DB::rollBack();
            Log::error('Error importing menu item recipes: ' . $e->getMessage());
            return response()->json([
                'error' => 'Failed to import menu item recipes: ' . $e->getMessage()
            ], 500);
        }
    }
}

