<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\Restaurant;
use App\Models\User;
use App\Models\PosOrderItem;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\DB;

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

    public function index(Request $request)
    {
        $user = $request->user();
        
        if (!$user->isAdmin()) {
            return response()->json(['error' => 'Unauthorized'], 403);
        }

        $query = Restaurant::with(['owners']);

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

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

        $restaurants = $query->orderBy('created_at', 'desc')->paginate($request->get('per_page', 50));

        // Transform to include owner details and logo URL
        $restaurants->getCollection()->transform(function ($restaurant) {
            $restaurant->owners_count = $restaurant->owners()->count();
            $restaurant->owners_list = $restaurant->owners()->get()->map(function ($owner) {
                return [
                    'id' => $owner->id,
                    'name' => $owner->name,
                    'email' => $owner->email,
                    'is_active' => $owner->is_active ?? true,
                ];
            });
            
            // Add full logo URL if logo exists
            if ($restaurant->logo) {
                $restaurant->logo_url = Storage::disk('public')->url($restaurant->logo);
            }
            
            return $restaurant;
        });

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

    public function store(Request $request)
    {
        $user = $request->user();
        
        if (!$user->isAdmin()) {
            return response()->json(['error' => 'Unauthorized'], 403);
        }

        $validated = $request->validate([
            'name' => 'required|string|max:255',
            'code' => 'required|string|max:50|unique:restaurants,code',
            'logo' => 'nullable|image|mimes:jpeg,png,jpg,gif|max:2048',
            'address' => 'nullable|string',
            'phone' => 'nullable|string|max:20',
            'email' => 'nullable|email|max:255',
            'status' => 'required|in:active,inactive',
            // Optional owner details
            'owner_name' => 'nullable|string|max:255',
            'owner_email' => 'nullable|email|max:255',
            'owner_password' => 'nullable|string|min:6',
        ]);
        
        // Validate owner_email uniqueness only if provided
        if (!empty($validated['owner_email'])) {
            $request->validate([
                'owner_email' => 'unique:users,email',
            ]);
        }

        $data = $validated;

        // Handle logo upload - save under restaurant name directory
        if ($request->hasFile('logo')) {
            $restaurantName = str_replace([' ', '/', '\\', ':', '*', '?', '"', '<', '>', '|'], '_', $validated['name']);
            $restaurantName = preg_replace('/[^A-Za-z0-9_]/', '', $restaurantName); // Remove special characters
            $logoPath = $request->file('logo')->storeAs(
                'restaurants/' . $restaurantName,
                'logo_' . time() . '.' . $request->file('logo')->getClientOriginalExtension(),
                'public'
            );
            $data['logo'] = $logoPath;
        }

        $restaurant = Restaurant::create($data);
        
        // Set default timezone for new restaurant
        \App\Models\PosSetting::setSetting(
            'timezone',
            '+05:00',
            'string',
            $restaurant->id,
            null,
            'Restaurant timezone (e.g., +05:00 for Pakistan, Asia/Karachi)'
        );
        
        // Automatically create restaurant owner if owner details provided, or auto-generate if not
        $ownerEmail = $validated['owner_email'] ?? null;
        $ownerName = $validated['owner_name'] ?? null;
        $ownerPassword = $validated['owner_password'] ?? null;
        
        // If owner details are provided, use them; otherwise auto-generate
        if (!$ownerEmail) {
            // Auto-generate email based on restaurant code
            $ownerEmail = strtolower($validated['code']) . '@restaurant.com';
            // Ensure email is unique
            $counter = 1;
            while (User::where('email', $ownerEmail)->exists()) {
                $ownerEmail = strtolower($validated['code']) . $counter . '@restaurant.com';
                $counter++;
            }
        }
        
        if (!$ownerName) {
            // Auto-generate name based on restaurant name
            $ownerName = $validated['name'] . ' Owner';
        }
        
        if (!$ownerPassword) {
            // Auto-generate password (default: restaurant code + 123456)
            $ownerPassword = $validated['code'] . '123456';
        }
        
        // Create restaurant owner user
        $owner = User::create([
            'name' => $ownerName,
            'email' => $ownerEmail,
            'password' => Hash::make($ownerPassword),
            'role' => 'restaurant_owner',
            'restaurant_id' => $restaurant->id,
            'is_active' => true,
        ]);
        
        $restaurant->load('owners');
        
        // Add logo URL if exists
        if ($restaurant->logo) {
            $restaurant->logo_url = Storage::disk('public')->url($restaurant->logo);
        }
        
        // Include owner details in response
        $restaurant->created_owner = [
            'name' => $owner->name,
            'email' => $owner->email,
            'password' => $ownerPassword, // Return plain password only on creation
        ];
        
        return response()->json($restaurant, 201);
    }

    public function show(Restaurant $restaurant)
    {
        $user = request()->user();
        
        if (!$user->isAdmin()) {
            return response()->json(['error' => 'Unauthorized'], 403);
        }

        $restaurant->load(['owners', 'branches']);
        
        return response()->json($restaurant);
    }

    public function update(Request $request, Restaurant $restaurant)
    {
        $user = $request->user();
        
        if (!$user->isAdmin()) {
            return response()->json(['error' => 'Unauthorized'], 403);
        }

        // Handle owners data first to validate properly
        $ownersData = null;
        if ($request->has('owners')) {
            $ownersInput = $request->input('owners');
            if (is_string($ownersInput)) {
                // Decode JSON string
                $decoded = json_decode($ownersInput, true);
                if (json_last_error() === JSON_ERROR_NONE && is_array($decoded)) {
                    $ownersData = $decoded;
                }
            } elseif (is_array($ownersInput)) {
                $ownersData = $ownersInput;
            }
        }
        
        $validated = $request->validate([
            'name' => 'sometimes|required|string|max:255',
            'code' => 'sometimes|required|string|max:50|unique:restaurants,code,' . $restaurant->id,
            'logo' => 'nullable|image|mimes:jpeg,png,jpg,gif|max:2048',
            'address' => 'nullable|string',
            'phone' => 'nullable|string|max:20',
            'email' => 'nullable|email|max:255',
            'status' => 'sometimes|required|in:active,inactive',
        ]);
        
        // Validate owners data separately if provided
        if ($ownersData && is_array($ownersData)) {
            foreach ($ownersData as $index => $ownerData) {
                $ownerId = $ownerData['id'] ?? null;
                $ownerEmail = $ownerData['email'] ?? null;
                
                // Basic validation
                if (!$ownerId || !User::find($ownerId)) {
                    return response()->json(['error' => "Owner {$index} ID is invalid"], 422);
                }
                
                if (!$ownerData['name'] || !$ownerEmail) {
                    return response()->json(['error' => "Owner {$index} name and email are required"], 422);
                }
                
                // Check email uniqueness (excluding current owner)
                if ($ownerEmail) {
                    $emailExists = User::where('email', $ownerEmail)
                        ->where('id', '!=', $ownerId)
                        ->exists();
                    
                    if ($emailExists) {
                        return response()->json([
                            'error' => "The email {$ownerEmail} is already taken by another user."
                        ], 422);
                    }
                }
                
                // Validate password if provided
                if (isset($ownerData['password']) && !empty($ownerData['password']) && strlen($ownerData['password']) < 6) {
                    return response()->json(['error' => "Owner {$index} password must be at least 6 characters"], 422);
                }
            }
        }

        $data = $validated;

        // Handle logo upload - save under restaurant name directory
        if ($request->hasFile('logo')) {
            // Delete old logo if exists
            if ($restaurant->logo) {
                Storage::disk('public')->delete($restaurant->logo);
                // Also try to delete the directory if it's empty
                $oldDir = dirname($restaurant->logo);
                if ($oldDir && Storage::disk('public')->exists($oldDir)) {
                    $files = Storage::disk('public')->files($oldDir);
                    if (empty($files)) {
                        Storage::disk('public')->deleteDirectory($oldDir);
                    }
                }
            }
            
            // Create directory based on restaurant name
            $restaurantName = str_replace([' ', '/', '\\', ':', '*', '?', '"', '<', '>', '|'], '_', $restaurant->name);
            $restaurantName = preg_replace('/[^A-Za-z0-9_]/', '', $restaurantName); // Remove special characters
            $logoPath = $request->file('logo')->storeAs(
                'restaurants/' . $restaurantName,
                'logo_' . time() . '.' . $request->file('logo')->getClientOriginalExtension(),
                'public'
            );
            $data['logo'] = $logoPath;
        } else {
            // Don't update logo if not provided
            unset($data['logo']);
        }

        // Remove owners from restaurant data before updating restaurant (already handled above)

        $restaurant->update($data);
        
        // Update owners if provided
        if ($ownersData && is_array($ownersData)) {
            foreach ($ownersData as $ownerData) {
                $owner = User::find($ownerData['id']);
                
                // Verify owner belongs to this restaurant
                if ($owner && $owner->restaurant_id === $restaurant->id && $owner->role === 'restaurant_owner') {
                    $updateData = [];
                    
                    if (isset($ownerData['name'])) {
                        $updateData['name'] = $ownerData['name'];
                    }
                    
                    if (isset($ownerData['email'])) {
                        // Check email uniqueness (excluding current owner)
                        $emailExists = User::where('email', $ownerData['email'])
                            ->where('id', '!=', $owner->id)
                            ->exists();
                        
                        if ($emailExists) {
                            return response()->json([
                                'error' => 'The email ' . $ownerData['email'] . ' is already taken by another user.'
                            ], 422);
                        }
                        
                        $updateData['email'] = $ownerData['email'];
                    }
                    
                    if (!empty($ownerData['password'])) {
                        $updateData['password'] = Hash::make($ownerData['password']);
                    }
                    
                    if (!empty($updateData)) {
                        $owner->update($updateData);
                    }
                }
            }
        }
        
        $restaurant->load('owners');
        
        // Add logo URL if exists
        if ($restaurant->logo) {
            $restaurant->logo_url = Storage::disk('public')->url($restaurant->logo);
        }
        
        return response()->json($restaurant);
    }

    public function destroy(Request $request, Restaurant $restaurant)
    {
        $user = request()->user();
        
        if (!$user->isAdmin()) {
            return response()->json(['error' => 'Unauthorized'], 403);
        }

        $action = $request->input('action', 'delete'); // 'disable' or 'delete'

        if ($action === 'disable') {
            // Soft delete: Disable restaurant and all related staff
            $restaurant->status = 'inactive';
            $restaurant->save();

            // Disable all restaurant owners
            $restaurant->owners()->update(['is_active' => false]);

            // Disable all branches
            $restaurant->branches()->update(['status' => 'inactive']);

            // Disable all users associated with this restaurant's branches
            $branchIds = $restaurant->branches()->pluck('id');
            User::whereIn('branch_id', $branchIds)->update(['is_active' => false]);

            // Disable all waiters
            $restaurant->waiters()->update(['status' => 'inactive']);

            return response()->json([
                'message' => 'Restaurant and all associated staff have been disabled successfully. They will not be able to login or use the system. Please contact admin to reactivate.',
                'action' => 'disabled'
            ]);
        } else {
            // Hard delete: Permanently remove all related data
            DB::transaction(function () use ($restaurant) {
                // Delete logo if exists
                if ($restaurant->logo) {
                    Storage::disk('public')->delete($restaurant->logo);
                }

                // Delete all related data
                $restaurant->owners()->delete();
                $restaurant->waiters()->delete();
                $restaurant->agents()->delete();
                
                // Delete branches and their related data
                foreach ($restaurant->branches as $branch) {
                    // Delete branch-related users
                    User::where('branch_id', $branch->id)->delete();
                    // Delete branch logo if exists
                    if ($branch->logo) {
                        Storage::disk('public')->delete($branch->logo);
                    }
                }
                $restaurant->branches()->delete();
                
                // Delete inventory related
                $restaurant->inventories()->delete();
                $restaurant->inventoryCategories()->delete();
                $restaurant->items()->delete();
                
                // Delete menu related
                foreach ($restaurant->menuItems as $item) {
                    if ($item->image) {
                        Storage::disk('public')->delete($item->image);
                    }
                    // Delete recipes if relationship exists
                    if (method_exists($item, 'recipes')) {
                        $item->recipes()->delete();
                    }
                }
                $restaurant->menuItems()->delete();
                $restaurant->menuCategories()->delete();
                
                // Delete tables
                $restaurant->tables()->delete();
                
                // Delete orders and order items
                foreach ($restaurant->orders as $order) {
                    // Delete order items
                    PosOrderItem::where('order_id', $order->id)->delete();
                }
                $restaurant->orders()->delete();
                
                // Delete customers
                $restaurant->customers()->delete();
                
                // Delete shifts
                $restaurant->shifts()->delete();
                
                // Delete daily expenses
                $restaurant->dailyExpenses()->delete();
                
                // Delete stock related
                $restaurant->stockOuts()->delete();
                $restaurant->stockClosings()->delete();
                
                // Finally delete the restaurant
                $restaurant->delete();
            });

            return response()->json([
                'message' => 'Restaurant and all associated data have been permanently deleted.',
                'action' => 'deleted'
            ]);
        }
    }

    /**
     * Get restaurant owners
     */
    public function getOwners(Restaurant $restaurant)
    {
        $user = request()->user();
        
        if (!$user->isAdmin()) {
            return response()->json(['error' => 'Unauthorized'], 403);
        }

        $owners = $restaurant->owners()->get();

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

    /**
     * Create restaurant owner
     */
    public function createOwner(Request $request, Restaurant $restaurant)
    {
        $user = $request->user();
        
        if (!$user->isAdmin()) {
            return response()->json(['error' => 'Unauthorized'], 403);
        }

        $validated = $request->validate([
            'name' => 'required|string|max:255',
            'email' => 'required|email|unique:users,email',
            'password' => 'required|string|min:6',
        ]);

        $owner = User::create([
            'name' => $validated['name'],
            'email' => $validated['email'],
            'password' => Hash::make($validated['password']),
            'role' => 'restaurant_owner',
            'restaurant_id' => $restaurant->id,
            'is_active' => true,
        ]);

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

    /**
     * Toggle owner status (enable/disable)
     */
    public function toggleOwnerStatus(Request $request, Restaurant $restaurant, User $owner)
    {
        $user = $request->user();
        
        if (!$user->isAdmin()) {
            return response()->json(['error' => 'Unauthorized'], 403);
        }

        // Verify owner belongs to restaurant
        if ($owner->restaurant_id !== $restaurant->id || $owner->role !== 'restaurant_owner') {
            return response()->json(['error' => 'Invalid owner'], 400);
        }

        // Toggle is_active status
        $currentStatus = $owner->is_active ?? true;
        $newStatus = !$currentStatus;
        
        // Update is_active field
        $owner->is_active = $newStatus;
        $owner->save();

        return response()->json([
            'message' => $newStatus ? 'Owner enabled successfully' : 'Owner disabled successfully',
            'owner' => $owner->fresh()
        ]);
    }

    /**
     * Delete restaurant owner
     */
    public function deleteOwner(Restaurant $restaurant, User $owner)
    {
        $user = request()->user();
        
        if (!$user->isAdmin()) {
            return response()->json(['error' => 'Unauthorized'], 403);
        }

        // Verify owner belongs to restaurant
        if ($owner->restaurant_id !== $restaurant->id || $owner->role !== 'restaurant_owner') {
            return response()->json(['error' => 'Invalid owner'], 400);
        }

        $owner->delete();

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

