<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\Branch;
use App\Models\Restaurant;
use App\Models\PosTable;
use App\Models\PosMenuItem;
use App\Models\RestaurantMenuCategory;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\DB;

class BranchController extends Controller
{
    /**
     * List branches
     */
    public function index(Request $request)
    {
        $user = $request->user();
        $query = Branch::query();
        
        // Restaurant owners see all branches of their restaurant
        if ($user->isRestaurantOwner() && $user->restaurant_id) {
            $query->where('restaurant_id', $user->restaurant_id);
        }
        // Branch managers see only their branch
        elseif ($user->isBranchManager() && $user->branch_id) {
            $query->where('id', $user->branch_id);
        }
        // Staff see their assigned branch
        elseif ($user->branch_id) {
            $query->where('id', $user->branch_id);
        }
        // Admin can see all or filter by restaurant
        elseif ($user->isAdmin()) {
            if ($request->has('restaurant_id')) {
                $query->where('restaurant_id', $request->restaurant_id);
            }
        }
        
        if ($request->has('status')) {
            $query->where('status', $request->status);
        }
        
        $branches = $query->with('restaurant')->orderBy('name')->paginate($request->get('per_page', 50));
        
        // Transform branches to include logo URL
        $branches->getCollection()->transform(function ($branch) {
            if ($branch->logo) {
                $branch->logo_url = Storage::disk('public')->url($branch->logo);
            }
            return $branch;
        });
        
        return response()->json($branches);
    }

    /**
     * Show a single branch
     */
    public function show(Branch $branch)
    {
        $user = request()->user();
        
        // Load restaurant relationship if not already loaded
        if (!$branch->relationLoaded('restaurant')) {
            $branch->load('restaurant');
        }
        
        // Verify access - use type casting for comparison
        if ($user->isRestaurantOwner()) {
            $userRestaurantId = (int) $user->restaurant_id;
            $branchRestaurantId = (int) $branch->restaurant_id;
            
            if ($userRestaurantId !== $branchRestaurantId) {
                return response()->json(['message' => 'Unauthorized'], 403);
            }
        }
        
        if ($user->isBranchManager()) {
            $userBranchId = (int) $user->branch_id;
            $branchId = (int) $branch->id;
            
            if ($userBranchId !== $branchId) {
                return response()->json(['message' => 'Unauthorized'], 403);
            }
        }
        
        $branch->load('restaurant');
        
        // Add logo URL if exists
        if ($branch->logo) {
            $branch->logo_url = Storage::disk('public')->url($branch->logo);
        }
        
        return response()->json($branch);
    }

    /**
     * Create a new branch (restaurant owner or admin)
     */
    public function store(Request $request)
    {
        $user = $request->user();
        
        $validated = $request->validate([
            'name' => 'required|string|max:255',
            'code' => 'required|string|max:50|unique:branches,code',
            'restaurant_id' => 'required|exists:restaurants,id',
            'logo' => 'nullable|image|mimes:jpeg,png,jpg,gif|max:2048',
            'phone' => 'nullable|string|max:20',
            'address' => 'nullable|string',
            'status' => 'required|in:active,inactive',
            'opening_time' => 'nullable|date_format:H:i',
            'closing_time' => 'nullable|date_format:H:i',
        ]);
        
        // Restaurant owners can only create branches for their restaurant
        // Use type casting to handle string/int type differences
        if ($user->isRestaurantOwner()) {
            // Check if user has restaurant_id assigned
            if (!$user->restaurant_id) {
                return response()->json([
                    'message' => 'Your account is not assigned to a restaurant. Please contact administrator.'
                ], 403);
            }
            
            // Cast both to integers for comparison
            $userRestaurantId = (int) $user->restaurant_id;
            $requestRestaurantId = (int) $validated['restaurant_id'];
            
            if ($userRestaurantId !== $requestRestaurantId) {
                return response()->json([
                    'message' => 'You can only create branches for your restaurant'
                ], 403);
            }
        }
        
        if (!$user->isAdmin() && !$user->isRestaurantOwner()) {
            return response()->json(['message' => 'Unauthorized'], 403);
        }
        
        // Handle logo upload
        if ($request->hasFile('logo')) {
            $logo = $request->file('logo');
            $restaurant = Restaurant::find($validated['restaurant_id']);
            $restaurantName = $restaurant ? str_replace(' ', '_', strtolower($restaurant->name)) : 'default';
            $logoPath = $logo->store("restaurants/{$restaurantName}/branches", 'public');
            $validated['logo'] = $logoPath;
        }
        
        $branch = Branch::create($validated);
        $branch->load('restaurant');
        
        // Create default data for the new branch
        try {
            DB::beginTransaction();
            
            // Create 3 default tables
            for ($i = 1; $i <= 3; $i++) {
                PosTable::create([
                    'name' => "Table {$i}",
                    'number' => $i,
                    'capacity' => 4,
                    'status' => 'active',
                    'branch_id' => $branch->id,
                    'restaurant_id' => $branch->restaurant_id,
                ]);
            }
            
            // Get or create a default category for the branch
            $defaultCategory = RestaurantMenuCategory::where('branch_id', $branch->id)
                ->where('name', 'Default')
                ->first();
            
            if (!$defaultCategory) {
                $defaultCategory = RestaurantMenuCategory::create([
                    'name' => 'Default',
                    'description' => 'Default category',
                    'branch_id' => $branch->id,
                    'restaurant_id' => $branch->restaurant_id,
                    'status' => true, // boolean true for active
                    'sort_order' => 0,
                ]);
            }
            
            // Create 3 default menu items: Water, Roti, Naan
            $defaultMenuItems = [
                [
                    'name' => 'Water',
                    'description' => 'Bottled Water',
                    'price' => 20.00,
                    'restaurant_category_id' => $defaultCategory->id,
                    'restaurant_category_name' => 'Default',
                    'branch_id' => $branch->id,
                    'restaurant_id' => $branch->restaurant_id,
                    'is_available' => true,
                    'sort_order' => 1,
                ],
                [
                    'name' => 'Roti',
                    'description' => 'Fresh Roti',
                    'price' => 15.00,
                    'restaurant_category_id' => $defaultCategory->id,
                    'restaurant_category_name' => 'Default',
                    'branch_id' => $branch->id,
                    'restaurant_id' => $branch->restaurant_id,
                    'is_available' => true,
                    'sort_order' => 2,
                ],
                [
                    'name' => 'Naan',
                    'description' => 'Fresh Naan',
                    'price' => 25.00,
                    'restaurant_category_id' => $defaultCategory->id,
                    'restaurant_category_name' => 'Default',
                    'branch_id' => $branch->id,
                    'restaurant_id' => $branch->restaurant_id,
                    'is_available' => true,
                    'sort_order' => 3,
                ],
            ];
            
            foreach ($defaultMenuItems as $menuItemData) {
                PosMenuItem::create($menuItemData);
            }
            
            DB::commit();
        } catch (\Exception $e) {
            DB::rollBack();
            // Log error but don't fail branch creation
            \Log::error("Failed to create default data for branch {$branch->id}: " . $e->getMessage());
        }
        
        // Add logo URL if exists
        if ($branch->logo) {
            $branch->logo_url = Storage::disk('public')->url($branch->logo);
        }
        
        return response()->json($branch, 201);
    }

    /**
     * Update branch (restaurant owner or admin)
     */
    public function update(Request $request, Branch $branch)
    {
        $user = $request->user();
        
        // Load restaurant relationship if not already loaded
        if (!$branch->relationLoaded('restaurant')) {
            $branch->load('restaurant');
        }
        
        // Restaurant owners can only update branches of their restaurant
        // Use type casting to handle string/int type differences
        if ($user->isRestaurantOwner()) {
            if (!$user->restaurant_id) {
                return response()->json([
                    'message' => 'Your account is not assigned to a restaurant. Please contact administrator.'
                ], 403);
            }
            
            $userRestaurantId = (int) $user->restaurant_id;
            $branchRestaurantId = (int) $branch->restaurant_id;
            
            if ($userRestaurantId !== $branchRestaurantId) {
                return response()->json(['message' => 'Unauthorized'], 403);
            }
        }
        
        if (!$user->isAdmin() && !$user->isRestaurantOwner()) {
            return response()->json(['message' => 'Unauthorized'], 403);
        }
        
        // Validation rules - restaurant_id is only required for admin, not for restaurant owners
        $validationRules = [
            'name' => 'required|string|max:255',
            'code' => 'required|string|max:50|unique:branches,code,' . $branch->id,
            'logo' => 'nullable|image|mimes:jpeg,png,jpg,gif|max:2048',
            'phone' => 'nullable|string|max:20',
            'address' => 'nullable|string',
            'status' => 'sometimes|required|in:active,inactive',
            'opening_time' => 'nullable|date_format:H:i',
            'closing_time' => 'nullable|date_format:H:i',
        ];
        
        // Only admins can change restaurant_id
        if ($user->isAdmin()) {
            $validationRules['restaurant_id'] = 'sometimes|required|exists:restaurants,id';
        }
        
        $validated = $request->validate($validationRules);
        
        // For restaurant owners, ensure restaurant_id is set to their restaurant (cannot be changed)
        if ($user->isRestaurantOwner()) {
            $validated['restaurant_id'] = $branch->restaurant_id; // Keep existing restaurant_id
        }
        
        // Handle logo upload
        if ($request->hasFile('logo')) {
            // Delete old logo if exists
            if ($branch->logo && Storage::disk('public')->exists($branch->logo)) {
                Storage::disk('public')->delete($branch->logo);
            }
            
            $logo = $request->file('logo');
            $restaurant = $branch->restaurant;
            $restaurantName = $restaurant ? str_replace(' ', '_', strtolower($restaurant->name)) : 'default';
            $logoPath = $logo->store("restaurants/{$restaurantName}/branches", 'public');
            $validated['logo'] = $logoPath;
        }
        
        $branch->update($validated);
        $branch->load('restaurant');
        
        // Add logo URL if exists
        if ($branch->logo) {
            $branch->logo_url = Storage::disk('public')->url($branch->logo);
        }
        
        return response()->json($branch);
    }

    /**
     * Delete branch (restaurant owner or admin)
     */
    public function destroy(Branch $branch)
    {
        $user = request()->user();
        
        // Load restaurant relationship if not already loaded
        if (!$branch->relationLoaded('restaurant')) {
            $branch->load('restaurant');
        }
        
        // Restaurant owners can only delete branches of their restaurant
        // Use type casting to handle string/int type differences
        if ($user->isRestaurantOwner()) {
            $userRestaurantId = (int) $user->restaurant_id;
            $branchRestaurantId = (int) $branch->restaurant_id;
            
            if ($userRestaurantId !== $branchRestaurantId) {
                return response()->json(['message' => 'Unauthorized'], 403);
            }
        }
        
        if (!$user->isAdmin() && !$user->isRestaurantOwner()) {
            return response()->json(['message' => 'Unauthorized'], 403);
        }
        
        $branch->delete();
        
        return response()->json(['message' => 'Branch deleted successfully']);
    }
}
