<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\User;
use App\Models\Restaurant;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\ValidationException;

class PosAuthController extends Controller
{
    public function login(Request $request)
    {
        try {
            $request->validate([
                'email' => 'required|email',
                'password' => 'required',
            ]);

            // Log the request for debugging
            Log::info('Login attempt', [
                'email' => $request->email,
                'ip' => $request->ip(),
            ]);

            $user = User::where('email', $request->email)->first();

            if (!$user) {
                return response()->json([
                    'message' => 'The provided credentials are incorrect.',
                    'error' => 'Invalid email or password'
                ], 401);
            }

            if (!Hash::check($request->password, $user->password)) {
                return response()->json([
                    'message' => 'The provided credentials are incorrect.',
                    'error' => 'Invalid email or password'
                ], 401);
            }

            // Check if user is disabled (skip for admin users)
            if (!$user->isAdmin() && isset($user->is_active) && !$user->is_active) {
                return response()->json([
                    'message' => 'Your account has been disabled. Please contact administrator.',
                    'error' => 'Account disabled'
                ], 403);
            }

            // Check restaurant status if user has restaurant_id (skip for admin users)
            if (!$user->isAdmin() && $user->restaurant_id) {
                $restaurant = \App\Models\Restaurant::find($user->restaurant_id);
                if ($restaurant && $restaurant->status !== 'active') {
                    return response()->json([
                        'message' => 'Your Restaurant account is Disabled please contact to the Admin',
                        'error' => 'Restaurant disabled'
                    ], 403);
                }
            }

            // Check branch status if user has branch_id (skip for admin users)
            if (!$user->isAdmin() && $user->branch_id) {
                $branch = \App\Models\Branch::find($user->branch_id);
                if ($branch && $branch->status !== 'active') {
                    return response()->json([
                        'message' => 'Your Restaurant account is Disabled please contact to the Admin',
                        'error' => 'Branch disabled'
                    ], 403);
                }
            }

            // Allow admin users to login from frontend
            // Check if user has access (admin, manager, pos_staff, branch_manager, restaurant_owner, branch_cashier, inventory_manager roles)
            $allowedRoles = ['admin', 'manager', 'pos_staff', 'branch_manager', 'restaurant_owner', 'branch_cashier', 'inventory_manager'];
            if (!in_array($user->role, $allowedRoles)) {
                return response()->json([
                    'message' => 'You do not have access to POS system.',
                    'error' => 'Access denied'
                ], 403);
            }

            // Load relationships
            $user->load(['branch', 'restaurant']);

            // Initialize branches collection
            $branches = collect();

            // For admin users, load all active branches
            if ($user->isAdmin()) {
                $branches = \App\Models\Branch::where('status', 'active')->get();
            }
            // For restaurant owners, check restaurant_id and load branches
            elseif ($user->isRestaurantOwner()) {
                if (!$user->restaurant_id) {
                    return response()->json([
                        'message' => 'Your account is not assigned to a restaurant. Please contact administrator.',
                        'error' => 'No restaurant assigned'
                    ], 403);
                }
                // Load branches for restaurant owner
                $branches = \App\Models\Branch::where('restaurant_id', $user->restaurant_id)
                    ->where('status', 'active')
                    ->get();
            }

            // For branch managers, check branch_id
            if ($user->isBranchManager()) {
                if (!$user->branch_id) {
                    return response()->json([
                        'message' => 'Your account is not assigned to a branch. Please contact administrator.',
                        'error' => 'No branch assigned'
                    ], 403);
                }
            }

            // For branch cashiers and pos_staff, check branch_id
            if ($user->isBranchCashier() || $user->isPosStaff()) {
                if (!$user->branch_id) {
                    Log::warning('Branch cashier/staff login failed - no branch_id', [
                        'user_id' => $user->id,
                        'email' => $user->email,
                        'role' => $user->role
                    ]);
                    return response()->json([
                        'message' => 'Your account is not assigned to a branch. Please contact administrator.',
                        'error' => 'No branch assigned'
                    ], 403);
                }
                // Also verify branch exists and is active
                $branch = \App\Models\Branch::find($user->branch_id);
                if (!$branch) {
                    Log::warning('Branch cashier/staff login failed - branch not found', [
                        'user_id' => $user->id,
                        'email' => $user->email,
                        'branch_id' => $user->branch_id
                    ]);
                    return response()->json([
                        'message' => 'Your assigned branch was not found. Please contact administrator.',
                        'error' => 'Branch not found'
                    ], 403);
                }
                if ($branch->status !== 'active') {
                    Log::warning('Branch cashier/staff login failed - branch inactive', [
                        'user_id' => $user->id,
                        'email' => $user->email,
                        'branch_id' => $user->branch_id,
                        'branch_status' => $branch->status
                    ]);
                    return response()->json([
                        'message' => 'Your assigned branch is inactive. Please contact administrator.',
                        'error' => 'Branch inactive'
                    ], 403);
                }
            }

            // For other roles (non-admin), check branch_id (skip inventory_manager as they don't need branch_id)
            if (!$user->isAdmin() && !$user->isRestaurantOwner() && !$user->isBranchManager() && !$user->isBranchCashier() && !$user->isPosStaff() && $user->role !== 'inventory_manager' && !$user->branch_id) {
                return response()->json([
                    'message' => 'Your account is not assigned to a branch. Please contact administrator.',
                    'error' => 'No branch assigned'
                ], 403);
            }

            // Delete existing tokens for this user (optional - for single device login)
            // $user->tokens()->delete();

            $token = $user->createToken('pos-token', ['*'])->plainTextToken;
            
            // Store restaurant_id and branch_id in session for all users
            $restaurantId = null;
            $branchId = null;
            
            // Get restaurant_id
            if ($user->restaurant_id) {
                // Restaurant owner - use their restaurant_id
                $restaurantId = $user->restaurant_id;
            } elseif ($user->branch_id) {
                // Sub-users (branch managers, staff) - get restaurant_id from their branch
                $branch = $user->branch;
                if ($branch && $branch->restaurant_id) {
                    $restaurantId = $branch->restaurant_id;
                }
            }
            
            // Get branch_id for branch managers and sub-users
            if ($user->branch_id) {
                $branchId = $user->branch_id;
            }
            
            // Store restaurant_id, branch_id, and user_id in session
            $sessionData = [];
            if ($restaurantId) {
                $sessionData['restaurant_id'] = $restaurantId;
            }
            if ($branchId) {
                $sessionData['branch_id'] = $branchId;
            }
            // Always store user_id for reference
            $sessionData['user_id'] = $user->id;
            
            // Store all session data at once
            if (!empty($sessionData)) {
                session($sessionData);
            }
            
            $responseData = [
                'user' => [
                    'id' => $user->id,
                    'name' => $user->name,
                    'email' => $user->email,
                    'role' => $user->role,
                    'branch_id' => $user->branch_id,
                    'restaurant_id' => $user->restaurant_id,
                ],
                'token' => $token,
                'branch' => $user->branch ? [
                    'id' => $user->branch->id,
                    'name' => $user->branch->name,
                    'code' => $user->branch->code,
                    'logo' => $user->branch->logo,
                    'restaurant_id' => $user->branch->restaurant_id,
                ] : null,
                'restaurant' => $user->restaurant ? [
                    'id' => $user->restaurant->id,
                    'name' => $user->restaurant->name,
                    'code' => $user->restaurant->code,
                    'logo' => $user->restaurant->logo,
                ] : null,
                'branches' => $branches->map(function ($branch) {
                    return [
                        'id' => $branch->id,
                        'name' => $branch->name,
                        'code' => $branch->code,
                        'logo' => $branch->logo,
                    ];
                }),
                'message' => 'Login successful'
            ];

            return response()->json($responseData, 200);
        } catch (\Illuminate\Validation\ValidationException $e) {
            return response()->json([
                'message' => 'Validation failed',
                'errors' => $e->errors()
            ], 422);
        } catch (\Exception $e) {
            Log::error('Login exception', [
                'error' => $e->getMessage(),
                'trace' => $e->getTraceAsString(),
            ]);
            return response()->json([
                'message' => 'An error occurred during login',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    public function logout(Request $request)
    {
        $request->user()->currentAccessToken()->delete();
        
        // Clear session data
        session()->forget(['restaurant_id', 'branch_id', 'selected_branch_id']);

        return response()->json([
            'message' => 'Logged out successfully'
        ]);
    }

    public function me(Request $request)
    {
        $user = $request->user();
        $user->load(['branch', 'restaurant']);

        // Update session data to ensure it's current
        $restaurantId = null;
        $branchId = null;
        
        // Get restaurant_id
        if ($user->restaurant_id) {
            $restaurantId = $user->restaurant_id;
        } elseif ($user->branch_id) {
            $branch = $user->branch;
            if ($branch && $branch->restaurant_id) {
                $restaurantId = $branch->restaurant_id;
            }
        }
        
        // Get branch_id for branch managers and sub-users
        if ($user->branch_id) {
            $branchId = $user->branch_id;
        }
        
        // Update session data
        $sessionData = [];
        if ($restaurantId) {
            $sessionData['restaurant_id'] = $restaurantId;
        }
        if ($branchId) {
            $sessionData['branch_id'] = $branchId;
        }
        $sessionData['user_id'] = $user->id;
        
        if (!empty($sessionData)) {
            session($sessionData);
        }

        // Load branches for restaurant owner
        $branches = collect();
        if ($user->isRestaurantOwner() && $user->restaurant_id) {
            $branches = \App\Models\Branch::where('restaurant_id', $user->restaurant_id)
                ->where('status', 'active')
                ->get();
        }
        
        return response()->json([
            'user' => [
                'id' => $user->id,
                'name' => $user->name,
                'email' => $user->email,
                'role' => $user->role,
                'branch_id' => $user->branch_id,
                'restaurant_id' => $user->restaurant_id,
            ],
            'branch' => $user->branch ? [
                'id' => $user->branch->id,
                'name' => $user->branch->name,
                'code' => $user->branch->code,
                'logo' => $user->branch->logo,
                'restaurant_id' => $user->branch->restaurant_id,
            ] : null,
            'restaurant' => $user->restaurant ? [
                'id' => $user->restaurant->id,
                'name' => $user->restaurant->name,
                'code' => $user->restaurant->code,
                'logo' => $user->restaurant->logo,
            ] : null,
            'branches' => $branches->map(function ($branch) {
                return [
                    'id' => $branch->id,
                    'name' => $branch->name,
                    'code' => $branch->code,
                    'logo' => $branch->logo,
                ];
            }),
        ]);
    }

    public function register(Request $request)
    {
        try {
            $validated = $request->validate([
                'owner_name' => 'required|string|max:255',
                'email' => 'required|email|max:255|unique:users,email',
                'password' => 'required|string|min:8|confirmed',
                'restaurant_name' => 'required|string|max:255',
                'contact_phone' => 'nullable|string|max:50',
            ]);

            // Generate unique restaurant code
            $restaurantCode = strtoupper(substr(preg_replace('/[^A-Za-z0-9]/', '', $validated['restaurant_name']), 0, 10));
            $baseCode = $restaurantCode;
            $counter = 1;
            while (Restaurant::where('code', $restaurantCode)->exists()) {
                $restaurantCode = $baseCode . $counter;
                $counter++;
            }

            // Create restaurant with pending status
            $restaurant = Restaurant::create([
                'name' => $validated['restaurant_name'],
                'code' => $restaurantCode,
                'phone' => $validated['contact_phone'] ?? null,
                'email' => $validated['email'],
                'status' => 'pending', // Account remains inactive until admin approval
            ]);

            // 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)'
            );

            // Create user with restaurant_owner role
            $user = User::create([
                'name' => $validated['owner_name'],
                'email' => $validated['email'],
                'password' => Hash::make($validated['password']),
                'role' => 'restaurant_owner',
                'restaurant_id' => $restaurant->id,
                'is_active' => false, // Inactive until admin approval
            ]);

            Log::info('Restaurant owner registration', [
                'user_id' => $user->id,
                'restaurant_id' => $restaurant->id,
                'email' => $user->email,
                'ip' => $request->ip(),
            ]);

            return response()->json([
                'message' => 'Registration successful! Your account is pending admin approval. You will be notified once your account is activated.',
                'user' => [
                    'id' => $user->id,
                    'name' => $user->name,
                    'email' => $user->email,
                    'role' => $user->role,
                ],
                'restaurant' => [
                    'id' => $restaurant->id,
                    'name' => $restaurant->name,
                    'code' => $restaurant->code,
                    'status' => $restaurant->status,
                ],
            ], 201);
        } catch (\Illuminate\Validation\ValidationException $e) {
            return response()->json([
                'message' => 'Validation failed',
                'errors' => $e->errors()
            ], 422);
        } catch (\Exception $e) {
            Log::error('Registration error', [
                'error' => $e->getMessage(),
                'trace' => $e->getTraceAsString(),
                'ip' => $request->ip(),
            ]);
            return response()->json([
                'message' => 'An error occurred during registration',
                'error' => $e->getMessage()
            ], 500);
        }
    }
}
