<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use App\Models\UserMaster;
use App\Models\FunctionType;
use App\Models\Department;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
use Carbon\Carbon;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Cache;

class AuthController extends Controller
{
    public function login(Request $request)
    {

        // $maxAttempts = 5;
        // $lockoutMinutes = 15;

        // $key = 'login_attempts_' . md5(
        //     strtolower($request->username ?? '') . '_' . $request->ip()
        // );

        // $attempts = Cache::get($key, 0);

        // if ($attempts >= $maxAttempts) {
        //     return response()->json([
        //         'success' => false,
        //         'message' => "Too many failed attempts. Please try again after {$lockoutMinutes} minutes."
        //     ], 429);
        // }
        // Cache::put(
        //     $key,
        //     $attempts + 1,
        //     now()->addMinutes($lockoutMinutes)
        // );

        try {
            $validator = Validator::make($request->all(), [
                'username' => 'required|string',
                'password' => 'required|string',
                'remember_me' => 'boolean'
            ], [
                'username.required' => 'Email or Mobile is required'
            ]);

            if ($validator->fails()) {
                return response()->json([
                    'success' => false,
                    'message' => 'Validation failed',
                    'errors' => $validator->errors()
                ], 422);
            }

            $user = UserMaster::where(function ($query) use ($request) {
                $query->where('Usr_Email', $request->username)
                    ->orWhere('Usr_Mobile', $request->username);
            })->first();

            if (!$user) {
                return response()->json([
                    'success' => false,
                    'message' => 'Invalid credentials'
                ], 401);
            }

            if (!$user->is_active) {
                return response()->json([
                    'success' => false,
                    'message' => 'Your account is inactive. Please contact administrator.'
                ], 401);
            }

            $storedPassword = $user->Usr_Pas;
            $inputPassword = $request->password;
            $isPasswordValid = false;

            if ($storedPassword === $inputPassword) {
                $isPasswordValid = true;
                Log::info('Password validated as plain text for user: ' . $user->Usr_Id);
                $user->update([
                    'Usr_Pas' => Hash::make($inputPassword)
                ]);
            } else if (Hash::check($inputPassword, $storedPassword)) {
                $isPasswordValid = true;
                Log::info('Password validated as Bcrypt for user: ' . $user->Usr_Id);
            } else if (md5($inputPassword) === $storedPassword) {
                $isPasswordValid = true;
                Log::info('Password validated as MD5 for user: ' . $user->Usr_Id);
                $user->update([
                    'Usr_Pas' => Hash::make($inputPassword)
                ]);
            } else if (sha1($inputPassword) === $storedPassword) {
                $isPasswordValid = true;
                Log::info('Password validated as SHA1 for user: ' . $user->Usr_Id);
                $user->update([
                    'Usr_Pas' => Hash::make($inputPassword)
                ]);
            }

            if (!$isPasswordValid) {
                $user->increment('failed_login_attempts');
                $user->refresh();

                return response()->json([
                    'success' => false,
                    'message' => 'Invalid credentials',
                    'attempts_remaining' => 5 - $user->failed_login_attempts
                ], 401);
            }

            // if ($this->isPasswordExpired($user)) {
            //     return response()->json([
            //         'success' => false,
            //         'message' => 'Password has expired. Please reset your password.',
            //         'requires_password_reset' => true
            //     ], 401);
            // }

            // ================= LOGIN SUCCESS =================

            $user->update([
                'failed_login_attempts' => 0,
                'is_locked' => 0,
                'last_login' => now(),
                'updated_at' => now()
            ]);

            // $user->tokens()->delete();

           
            $user->load([
                'role',
                'departmentMaps' => function ($query) {
                    $query->where('Status', 1)->whereNull('deleted_at');
                },
                'employee',
                'employee.personalProfile.designation'
            ]);

            
            $allDepartmentIds = [];
            foreach ($user->departmentMaps as $deptMap) {
                $deptIds = $deptMap->Dpt_Id ?? [];
                if (is_array($deptIds)) {
                    $allDepartmentIds = array_merge($allDepartmentIds, $deptIds);
                } elseif ($deptIds) {
                    $allDepartmentIds[] = $deptIds;
                }
            }
            $allDepartmentIds = array_unique(array_filter($allDepartmentIds));

            
            $firstDeptId = !empty($allDepartmentIds) ? $allDepartmentIds[0] : null;
            $departmentInfo = $firstDeptId ? Department::find($firstDeptId) : null;

            
            $departments = !empty($allDepartmentIds)
                ? Department::whereIn('Dpt_id', $allDepartmentIds)->get()
                : collect();

            
            $allowedMenus = collect();

            try {
                if (!empty($allDepartmentIds)) {
                    $allMenuIds = [];

                    
                    foreach ($allDepartmentIds as $deptId) {
                        $deptMenuMaps = DB::table('dept_menu_map')
                            ->where('Dpt_Id', $deptId)
                            ->where('Status', 1)
                            ->whereNull('deleted_at')
                            ->get();

                        foreach ($deptMenuMaps as $menuMap) {
                            
                            $menuIds = explode(',', $menuMap->Fnc_Id);
                            $allMenuIds = array_merge($allMenuIds, $menuIds);
                        }
                    }

                    
                    $allMenuIds = array_unique($allMenuIds);

                    if (!empty($allMenuIds)) {
                        $allowedMenus = FunctionType::with('action')
                            ->whereIn('Fnc_Id', $allMenuIds)
                            ->where('isvisible', 1)
                            ->whereNull('deleted_at')
                            ->orderBy('GrSrn')
                            ->get()
                            ->each(function ($item) {
                                if ($item->action) {
                                    $item->action->setAppends([]);
                                }
                            });

                        Log::info('Menus loaded for user: ' . $user->Usr_Id . ' | Departments: ' . implode(',', $allDepartmentIds) . ' | Total Menus: ' . $allowedMenus->count());
                    }
                }
            } catch (\Exception $e) {
                Log::warning('Department/menu fetch error: ' . 'Something went wrong. Please try again later.');
            }

            // ✅ Create token
            $token = $user->createToken('auth_token', [
                'Usr_Id:' . $user->Usr_Id,
                'Usr_Role_Id:' . $user->Usr_Role_Id,
                'Dpt_id:' . ($firstDeptId ?? ''),
                'Dsg_id:' . optional(optional($user->employee)->personalProfile->designation ?? null)->Dsg_id
            ])->plainTextToken;

            $sessionTimeout = 30 * 24 * 60; 

            $sessionData = [
                'token' => $token,
                'expires_at' => now()->addMinutes($sessionTimeout)->format('Y-m-d H:i:s'),
                'timeout_minutes' => $sessionTimeout,
                'remember_me' => $request->remember_me ?? false
            ];

            $userData = [
                'Usr_Id' => $user->Usr_Id,
                'Usr_Name' => $user->Usr_Name,
                'Usr_Email' => $user->Usr_Email,
                'Usr_Mobile' => $user->Usr_Mobile,
                'Usr_Role_Id' => $user->Usr_Role_Id,
                'is_active' => $user->is_active,
                'is_locked' => $user->is_locked,
                'role' => $user->role,
                'employee' => $user->employee,
                'department_ids' => $allDepartmentIds,
                'departments' => $departments
            ];

            return response()->json([
                'success' => true,
                'message' => 'Login successful',
                'data' => [
                    'token' => $token,
                    'user' => $userData,
                    'session' => $sessionData,
                    'primary_department' => $departmentInfo,
                    'all_departments' => $departments,
                    'allowed_menus' => $allowedMenus
                ]
            ], 200);
        } catch (\Exception $e) {
            Log::error('Login Error: ' . 'Something went wrong. Please try again later.');
            Log::error('Login Error Trace: ' . $e->getTraceAsString());

            return response()->json([
                'success' => false,
                'message' => 'Login failed. Please try again later.',
                'error' => config('app.debug') ? 'Something went wrong. Please try again later.' : null
            ], 500);
        }
    }

    private function isPasswordExpired($user)
    {
        if ($user->password_expiry_days && $user->last_password_change) {
            $expiryDate = Carbon::parse($user->last_password_change)->addDays($user->password_expiry_days);
            return now()->greaterThan($expiryDate);
        }
        return false;
    }

    public function logout(Request $request)
    {
        try {
            if ($request->user()) {
                $request->user()->currentAccessToken()->delete();
            }
            return response()->json([
                'success' => true,
                'message' => 'Logged out successfully'
            ], 200);
        } catch (\Exception $e) {
            Log::error('Logout Error: ' . 'Something went wrong. Please try again later.');
            return response()->json([
                'success' => false,
                'message' => 'Logout failed'
            ], 500);
        }
    }

    public function checkSession(Request $request)
    {
        try {
            $user = $request->user();

            if (!$user) {
                return response()->json([
                    'success' => false,
                    'message' => 'Session expired or invalid token'
                ], 401);
            }

            return response()->json([
                'success' => true,
                'message' => 'Session is valid',
                'data' => [
                    'user_id' => $user->Usr_Id,
                    'user_name' => $user->Usr_Name,
                    'timestamp' => now()->format('Y-m-d H:i:s')
                ]
            ], 200);
        } catch (\Exception $e) {
            Log::error('Check Session Error: ' . 'Something went wrong. Please try again later.');
            return response()->json([
                'success' => false,
                'message' => 'Session check failed'
            ], 500);
        }
    }

    public function changePassword(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'old_password' => 'required|string',
                'new_password' => 'required|string|min:6|confirmed'
            ]);

            if ($validator->fails()) {
                return response()->json([
                    'success' => false,
                    'message' => 'Validation failed',
                    'errors' => $validator->errors()
                ], 422);
            }

            $user = Auth::user();

            if (!$user) {
                return response()->json([
                    'success' => false,
                    'message' => 'User not authenticated'
                ], 401);
            }

            // Verify old password
            if (!Hash::check($request->old_password, $user->Usr_Pas)) {
                return response()->json([
                    'success' => false,
                    'message' => 'Old password is incorrect'
                ], 401);
            }

            
            $user->Usr_Pas = $request->new_password;
            $user->last_password_change = now();
            $user->save();

            
            // $user->tokens()->delete();

            return response()->json([
                'success' => true,
                'message' => 'Password changed successfully. Please login again.'
            ]);
        } catch (\Exception $e) {
            Log::error('Change Password Error: ' . 'Something went wrong. Please try again later.');
            return response()->json([
                'success' => false,
                'message' => 'Failed to change password: ' . 'Something went wrong. Please try again later.'
            ], 500);
        }
    }
}
