<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use App\Models\UserMaster;
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;

class AuthController extends Controller
{

    public function login(Request $request)
    {
        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);
            }

            // Check if account is locked
            if ($user->is_locked == 1) {
                return response()->json([
                    'success' => false,
                    'message' => 'Your account is locked. 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);

                // Upgrade to Bcrypt
                $user->update([
                    'Usr_Pas' => Hash::make($inputPassword)
                ]);
            }
            // Method 2: Try Bcrypt
            else if (Hash::check($inputPassword, $storedPassword)) {
                $isPasswordValid = true;
                Log::info('Password validated as Bcrypt for user: ' . $user->Usr_Id);
            }
            // Method 3: Try MD5
            else if (md5($inputPassword) === $storedPassword) {
                $isPasswordValid = true;
                Log::info('Password validated as MD5 for user: ' . $user->Usr_Id);

                // Upgrade to Bcrypt
                $user->update([
                    'Usr_Pas' => Hash::make($inputPassword)
                ]);
            }
            // Method 4: Try SHA1
            else if (sha1($inputPassword) === $storedPassword) {
                $isPasswordValid = true;
                Log::info('Password validated as SHA1 for user: ' . $user->Usr_Id);

                // Upgrade to Bcrypt
                $user->update([
                    'Usr_Pas' => Hash::make($inputPassword)
                ]);
            }

            if (!$isPasswordValid) {
                // Increment failed attempts
                $user->increment('failed_loginattempts', 1);

                // Check if account should be locked (after 5 failed attempts)
                if ($user->failed_loginattempts >= 5) {
                    $user->update(['is_locked' => 1]);

                    return response()->json([
                        'success' => false,
                        'message' => 'Account locked due to too many failed attempts. Please contact administrator.'
                    ], 401);
                }

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

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

            // ================= LOGIN SUCCESS =================
            // Reset failed attempts and update login info
            $user->update([
                'failed_loginattempts' => 0,
                'is_locked' => 0,
                'last_login' => now(),
                'updated_at' => now()
            ]);

            // Generate session token
            $sessionToken = Str::random(60);

            // Get session timeout from user or use default (30 minutes)
            $sessionTimeout = $request->remember_me
                ? 60 * 24 * 30  // 30 days for remember me
                : ($user->session_timeout ?? 30);  // Default 30 minutes

            // For now, just create a token without session table
            // You can add session creation later when you create the sessions table

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

            // ================= FETCH USER DATA =================
            // Load relationships
            $user->load(['role', 'department']);

            // Get user info for response
            $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,
                'Usr_Dpt_Id' => $user->Usr_Dpt_Id,
                'is_active' => $user->is_active,
                'is_locked' => $user->is_locked,
                'role' => $user->role,
                // 'allow_menus' => $user->allow_menus,
                // 'department' => $user->department
            ];

            // Get department and menus (optional - if your app has these)
            $departmentInfo = null;
            $allowedMenus = collect();

          try {

    if ($user->Usr_Dpt_Id) {

        $departmentInfo = DB::table('dept_master')
            ->where('Dpt_Id', $user->Usr_Dpt_Id)
            ->first();

        // Dept Menu Map
        $deptMenuMap = DB::table('dept_menu_map')
            ->where('Dpt_Id', $user->Usr_Dpt_Id)   // ✅ correct
            ->where('Status', 1)
            ->first();

        if ($deptMenuMap && !empty($deptMenuMap->Fnc_Id)) {

            // comma separated ids → array
            $menuIds = explode(',', $deptMenuMap->Fnc_Id);

            $allowedMenus = DB::table('function_types')
                ->whereIn('Fnc_Id', $menuIds)
                ->where('isvisible', 1)
                ->get();
        }
    }

} catch (\Exception $e) {
                Log::warning('Department/menu fetch error: ' . $e->getMessage());
                // Continue without department/menu data
            }

            // ================= FINAL RESPONSE =================
            return response()->json([
                'success' => true,
                'message' => 'Login successful',
                'data' => [
                    'user' => $userData,
                    'session' => $sessionData,
                    'department' => $departmentInfo,
                    'allowed_menus' => $allowedMenus
                ]
            ], 200);

        } catch (\Exception $e) {
            Log::error('Login Error: ' . $e->getMessage());
            Log::error('Login Error Trace: ' . $e->getTraceAsString());

            return response()->json([
                'success' => false,
                'message' => 'Login failed. Please try again later.'
            ], 500);
        }
    }

    /**
     * Check if password is expired
     */
    private function isPasswordExpired($user)
    {
        // Check if password_expiry_days is set and password_changed_at exists
        if ($user->password_expiry_days && $user->password_changed_at) {
            $expiryDate = Carbon::parse($user->password_changed_at)->addDays($user->password_expiry_days);
            return now()->greaterThan($expiryDate);
        }

        // Default: password doesn't expire if no expiry policy set
        return false;
    }

    /**
     * Logout User (Simple version without session table)
     */


    public function logout(Request $request)
    {
        try {

            return response()->json([
                'success' => true,
                'message' => 'Logged out successfully'
            ], 200);

        } catch (\Exception $e) {
            Log::error('Logout Error: ' . $e->getMessage());
            return response()->json([
                'success' => false,
                'message' => 'Logout failed'
            ], 500);
        }
    }

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

            if (!$token) {
                return response()->json([
                    'success' => false,
                    'message' => 'No token provided'
                ], 401);
            }


            return response()->json([
                'success' => true,
                'message' => 'Session is valid (basic check)',
                'data' => [
                    'token_exists' => !empty($token),
                    'timestamp' => now()->format('Y-m-d H:i:s')
                ]
            ], 200);

        } catch (\Exception $e) {
            Log::error('Check Session Error: ' . $e->getMessage());
            return response()->json([
                'success' => false,
                'message' => 'Session check failed'
            ], 500);
        }
    }


    public static function validateToken($token)
    {

        return !empty($token);
    }
}
