<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\User;
use App\Models\TravelAgent; // <-- ADDED: For eager loading the relationship
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Http;
use Carbon\Carbon;

// NEW: Firebase Admin SDK Imports
use Kreait\Firebase\Contract\Auth; 
use Kreait\Firebase\Exception\Auth\FailedToVerifyToken;

class AuthController extends Controller
{
    // NEW: Property to hold the Firebase Auth instance
    protected $firebaseAuth;

    // NEW: Constructor to inject the Firebase Auth instance
    public function __construct(Auth $firebaseAuth)
    {
        $this->firebaseAuth = $firebaseAuth;
    }

// ----------------------------------------------------------------------
// NEW FIREBASE AUTHENTICATION METHOD
// ----------------------------------------------------------------------

    /**
     * Verify Firebase ID Token and Log in/Register the User.
     * * The Flutter client sends the Firebase ID Token (JWT) after successful 
     * phone number verification.
     * * @param \Illuminate\Http\Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function firebaseAuth(Request $request)
    {
        // 1. Validate the incoming request data
        $request->validate([
            'id_token' => 'required|string',
            'mobile' => 'required|string',
        ]);

        $idToken = $request->id_token;
        $mobile = $request->mobile;
        
        try {
            // 2. VERIFY the ID Token using Firebase Admin SDK
            $verifiedIdToken = $this->firebaseAuth->verifyIdToken($idToken);
            $firebaseUid = $verifiedIdToken->claims()->get('sub');
            $userPayload = $this->firebaseAuth->getUser($firebaseUid);

        } catch (FailedToVerifyToken $e) {
            return response()->json(['message' => 'Invalid or expired Firebase token.'], 401);
        } catch (\Exception $e) {
            \Log::error('Firebase authentication error: ' . $e->getMessage());
            return response()->json(['message' => 'Authentication failed. Please try again.'], 401);
        }

        // 3. Find or Create User in Your Database
        // We will load the relationship later to ensure it works for newly created users
        $user = User::where('mobile', $mobile)->first(); 
        if (!$user || !$user->is_active) { // <-- ADDED CHECK
        return response()->json(['message' => 'Your account has been deactivated. Please contact your administrator.'], 403);
        }
        $isFirstTimeLogin = false;
        $needsSave = false;

        if (!$user) {
            try {
                // A) User not found: Create a new user record
                $user = User::create([
                    'name' => $userPayload->displayName ?? 'User-' . substr($mobile, -4),
                    'email' => $userPayload->email ?? $firebaseUid . '@temp.com',
                    'mobile' => $mobile,
                    'firebase_uid' => $firebaseUid,
                    'password' => Hash::make(base64_encode(random_bytes(10))),
                    'travel_agent_id' => $this->determineTravelAgentId($mobile), // Dynamic assignment
                ]);
                $isFirstTimeLogin = true;
            } catch (\Exception $e) {
                \Log::error('User creation failed: ' . $e->getMessage());
                return response()->json(['message' => 'User registration failed.'], 500);
            }
        } else {
            // B) Existing user: Update Firebase UID if different or not set
            if ($user->firebase_uid !== $firebaseUid) {
                $user->firebase_uid = $firebaseUid;
                $needsSave = true;
            }
            
            // Update name from Firebase if available and different
            $firebaseName = $userPayload->displayName ?? null;
            if ($firebaseName && $user->name !== $firebaseName) {
                $user->name = $firebaseName;
                $needsSave = true;
            }
        }
        
        if ($needsSave) {
             $user->save();
        }

        // 4. Update login status and generate Sanctum Token
        $user->last_login_at = now();
        $user->last_login_method = 'Firebase Auth';
        $user->access_expires_at = now()->addDays(30);
        $user->save();
        
        // EAGER LOAD THE RELATIONSHIP before response (Crucial for Company Name)
        $user->load('travelAgent'); // <-- ADDED

        // Delete existing tokens and create a new one
        $user->tokens()->delete();
        $token = $user->createToken('api-token')->plainTextToken;

        return response()->json([
            'user' => [
                'id' => $user->id,
                'name' => $user->name,
                'email' => $user->email,
                'mobile' => $user->mobile,
                'travel_agent_id' => $user->travel_agent_id,
            ],
            'token' => $token,
            'travel_agent_id' => $user->travel_agent_id,
            'company_name' => $user->travelAgent->name ?? null, // <-- MODIFIED/CONFIRMED
            'first_time_login' => $isFirstTimeLogin || is_null($user->pin_code),
        ]);
    }

    /**
     * Determine travel_agent_id based on your business logic
     * Replace this with your actual logic
     */
    private function determineTravelAgentId($mobile)
    {
        // Example logic - replace with your actual business rules:
        return 1;
    }

// ----------------------------------------------------------------------
// EXISTING CUSTOM AUTHENTICATION METHODS
// ----------------------------------------------------------------------

    /**
     * Request OTP for login (dev-friendly)
     */
    public function requestOtp(Request $request)
    {
        $request->validate([
            'username' => 'required' // mobile or email
        ]);

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

        if (!$user) {
            return response()->json([
                'message' => 'User not registered under any travel agent'
            ], 404);
        }

        // Generate OTP
        $otp = rand(100000, 999999);

        $user->otp = $otp; // store OTP (can hash later)
        $user->otp_expires_at = now()->addMinutes(5);
        $user->save();

        // ====== DEV ONLY ======
        // Skip sending SMS. Return OTP in response for testing.
        return response()->json([
            'message' => 'OTP generated successfully',
            'otp' => $otp, // For dev: use this OTP to login
        ]);
        // =======================
    }

    /**
     * Verify OTP and login
     */
    public function verifyOtp(Request $request)
    {
        $request->validate([
            'username' => 'required',
            'otp' => 'required'
        ]);

        // Eager load the relationship here
        $user = User::with('travelAgent') // <-- MODIFIED
                     ->where('mobile', $request->username)
                     ->orWhere('email', $request->username)
                     ->first();

        if (!$user) return response()->json(['message' => 'User not found'], 404);

        if ($user->otp != $request->otp || now()->gt($user->otp_expires_at)) {
            return response()->json(['message' => 'Invalid or expired OTP'], 401);
        }

        $user->last_login_at = now();
        $user->last_login_method = 'OTP';
        $user->access_expires_at = now()->addDays(30);
        $user->otp = null;
        $user->otp_expires_at = null;
        $user->save();

        $token = $user->createToken('api-token')->plainTextToken;

        // ===== DEV: Skip notifying agent or send fake message =====
        // $this->notifyTravelAgent($user, 'OTP');

        $first_time = is_null($user->pin_code);

        return response()->json([
            'user' => $user,
            'token' => $token,
            'company_name' => $user->travelAgent->name ?? null, // <-- ADDED
            'first_time_login' => $first_time
        ]);
    }

    /**
     * Set PIN
     */
    public function setPin(Request $request)
    {
        $request->validate([
            'pin_code' => 'required|min:4|max:6'
        ]);

        $user = $request->user(); // token authenticated

        $user->pin_code = Hash::make($request->pin_code);
        $user->save();

        return response()->json([
            'message' => 'PIN set successfully'
        ]);
    }

    /**
     * Login with PIN
     */
    public function loginWithPin(Request $request)
    {
        $request->validate([
            'mobile' => 'required',
            'pin_code' => 'required'
        ]);

        // Eager load the relationship
        $user = User::with('travelAgent')->where('mobile', $request->mobile)->first(); // <-- MODIFIED

        if (!$user) return response()->json(['message'=>'User not found'], 404);

        if (!Hash::check($request->pin_code, $user->pin_code)) {
            return response()->json(['message'=>'Invalid PIN'], 401);
        }

        if ($user->access_expires_at && now()->gt($user->access_expires_at)) {
            return response()->json(['message'=>'Access expired, please verify OTP again'], 403);
        }

        $user->last_login_at = now();
        $user->last_login_method = 'PIN';
        $user->save();

        // Delete existing tokens and create a new one
        $user->tokens()->delete();
        $token = $user->createToken('api-token')->plainTextToken;

        // DEV: Skip notifying agent
        // $this->notifyTravelAgent($user, 'PIN');

        return response()->json([
            'user' => $user,
            'token' => $token,
            'travel_agent_id' => $user->travel_agent_id,
            'company_name' => $user->travelAgent->name ?? null, // <-- ADDED
        ]);
    }

    /**
     * Login with Password
     */
    public function loginWithPassword(Request $request)
    {
        $request->validate([
            'email' => 'required',
            'password' => 'required'
        ]);

        $user = User::where('email', $request->email)->first();
        if (!$user || !Hash::check($request->password, $user->password)) {
            return response()->json(['message' => 'Invalid credentials'], 401);
        }

        $user->last_login_at = now();
        $user->last_login_method = 'Password';
        $user->access_expires_at = now()->addDays(30);
        $user->save();

        $token = $user->createToken('api-token')->plainTextToken;

        // DEV: Skip notifying agent
        // $this->notifyTravelAgent($user, 'Password');

        return response()->json([
            'user' => $user,
            'token' => $token
        ]);
    }

    /**
     * Logout
     */
    public function logout(Request $request)
    {
        $request->user()->currentAccessToken()->delete();
        return response()->json(['message'=>'Logged out']);
    }

    public function profile(Request $request)
    {
        $user = $request->user()->load('travelAgent'); // <-- MODIFIED: Eager load the relationship

        return response()->json([
            'id' => $user->id,
            'name' => $user->name,
            'email' => $user->email,
            'mobile' => $user->mobile,
            'travel_agent_id' => $user->travel_agent_id,
            'pin_code' => $user->pin_code,
            'company_name' => $user->travelAgent->name ?? null, // <-- ADDED
        ]);
    }

    /**
     * Notify Travel Agent (DEV: skip for now)
     */
    protected function notifyTravelAgent($user, $method)
    {
        // Skip for development
    }
}