<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\User;
use App\Models\EmployerProfile;
use App\Models\Sponsor;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Str;

class EmployerAuthController extends Controller
{
    /**
     * Authenticate an employer and return a secure Bearer token.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function login(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'email'    => 'nullable|string',
            'mobile'   => 'nullable|string',
            'password' => 'required|string',
        ]);

        $validator->after(function ($validator) use ($request) {
            if (!$request->filled('email') && !$request->filled('mobile')) {
                $validator->errors()->add('mobile', 'Either mobile number or email is required.');
            }
        });

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

        try {
            $loginValue = $request->input('mobile') ?? $request->input('email');

            $sponsor = Sponsor::where('mobile', $loginValue)
                ->orWhere('email', $loginValue)
                ->first();

            if ($sponsor) {
                $user = User::where('email', $sponsor->email)
                    ->where('role', 'employer')
                    ->first();
            } else {
                $user = User::where('email', $loginValue)
                    ->where('role', 'employer')
                    ->first();
            }

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

            $passwordHash = $sponsor ? $sponsor->password : $user->password;

            if (!Hash::check($request->password, $passwordHash)) {
                return response()->json([
                    'success' => false,
                    'message' => 'Invalid credentials.'
                ], 401);
            }

            if ($sponsor && $sponsor->status === 'suspended') {
                return response()->json([
                    'success' => false,
                    'message' => 'Your account has been suspended. Please contact support.'
                ], 403);
            }

            $apiToken = Str::random(80);

            if ($user) {
                // Employer account
                $profile = EmployerProfile::where('user_id', $user->id)->first();
                $verification_status = $profile ? $profile->verification_status : 'approved';

                if ($verification_status === 'pending') {
                    return response()->json([
                        'success' => false,
                        'message' => 'Your account is pending verification.'
                    ], 403);
                }

                if ($verification_status === 'rejected') {
                    return response()->json([
                        'success' => false,
                        'message' => 'Your account verification has been rejected.',
                        'reason'  => $profile->rejection_reason ?? 'Verification rejected.'
                    ], 403);
                }

                $user->update(['api_token' => $apiToken]);
                if ($sponsor) {
                    $sponsor->update([
                        'api_token'     => $apiToken,
                        'last_login_at' => now(),
                    ]);
                }

                return response()->json([
                    'success' => true,
                    'message' => 'Login successful.',
                    'role'    => 'employer',
                    'data'    => [
                        'employer' => $user->load('employerProfile'),
                        'token'    => $apiToken
                    ]
                ], 200);
            } else {
                // Pure Sponsor account
                $sponsor->update([
                    'api_token'     => $apiToken,
                    'last_login_at' => now(),
                ]);

                return response()->json([
                    'success' => true,
                    'message' => 'Login successful.',
                    'role'    => 'sponsor',
                    'data'    => [
                        'sponsor' => $sponsor->makeHidden(['password', 'api_token']),
                        'token'   => $apiToken
                    ]
                ], 200);
            }

        } catch (\Exception $e) {
            logger()->error('Mobile Login Failure: ' . $e->getMessage());

            return response()->json([
                'success' => false,
                'message' => 'An error occurred during login. Please try again.',
                'error'   => app()->environment('local') ? $e->getMessage() : 'Internal Server Error'
            ], 500);
        }
    }

    /**
     * Register a new employer via API.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function register(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'name' => 'required|string|max:255',
            'email' => 'required|string|email|max:255|unique:users,email',
            'phone' => 'required|string|max:50',
        ]);

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

        try {
            $otp = '111111'; // default development OTP
            if (app()->environment('production')) {
                $otp = strval(rand(100000, 999999));
            }

            \Illuminate\Support\Facades\Cache::put('employer_otp_' . $request->email, [
                'code' => $otp,
                'expires_at' => now()->addMinutes(10)->timestamp
            ], 600);

            // Create inactive User
            $user = User::create([
                'name' => $request->name,
                'email' => $request->email,
                'password' => Hash::make(Str::random(16)), // temporary password
                'role' => 'employer',
                'subscription_status' => 'none',
                'subscription_expires_at' => null,
            ]);

            // Create pending Profile
            EmployerProfile::create([
                'user_id' => $user->id,
                'company_name' => $request->name . ' Household',
                'phone' => $request->phone,
                'country' => 'United Arab Emirates',
                'verification_status' => 'pending',
                'language' => 'English',
                'notifications' => true,
            ]);

            // Create unverified Sponsor
            \App\Models\Sponsor::create([
                'full_name' => $request->name,
                'email' => $request->email,
                'mobile' => $request->phone,
                'password' => $user->password,
                'country_code' => 'AE',
                'subscription_status' => 'none',
                'subscription_plan' => null,
                'subscription_start_date' => null,
                'subscription_end_date' => null,
                'payment_status' => 'unpaid',
                'is_verified' => false,
                'otp_verified_at' => null,
                'status' => 'inactive',
            ]);

            // Try sending email
            try {
                \Illuminate\Support\Facades\Mail::to($request->email)->send(new \App\Mail\EmployerOtpMail(
                    $otp, 
                    $request->name . ' Household', 
                    $request->name
                ));
            } catch (\Exception $mailEx) {
                logger()->error('API Sponsor Registration Mail Failure: ' . $mailEx->getMessage());
            }

            return response()->json([
                'success' => true,
                'message' => 'Verification code sent to email successfully.',
                'email' => $request->email
            ], 201);

        } catch (\Exception $e) {
            logger()->error('API Sponsor Registration Failure: ' . $e->getMessage());
            return response()->json([
                'success' => false,
                'message' => 'Registration failed. Please try again.',
                'error' => app()->environment('local') ? $e->getMessage() : 'Internal Server Error'
            ], 500);
        }
    }

    public function verify(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'email' => 'required|email',
            'otp' => 'required|string|size:6',
        ]);

        if ($validator->fails()) {
            return response()->json([
                'success' => false,
                'errors' => $validator->errors()
            ], 422);
        }
        $cachedData = \Illuminate\Support\Facades\Cache::get('employer_otp_' . $request->email);

        if (!$cachedData || !isset($cachedData['code']) || !isset($cachedData['expires_at'])) {
            return response()->json([
                'success' => false,
                'message' => 'Invalid or expired verification code.'
            ], 400);
        }

        // Handle any dirty/legacy cache objects gracefully
        if (is_object($cachedData['expires_at']) || $cachedData['expires_at'] instanceof \__PHP_Incomplete_Class) {
            \Illuminate\Support\Facades\Cache::forget('employer_otp_' . $request->email);
            return response()->json([
                'success' => false,
                'message' => 'Session expired. Please request a new verification code.'
            ], 400);
        }

        if ($cachedData['code'] !== $request->otp || now()->timestamp > $cachedData['expires_at']) {
            return response()->json([
                'success' => false,
                'message' => 'Invalid or expired verification code.'
            ], 400);
        }

        try {
            // Update Sponsor verification status
            $sponsor = \App\Models\Sponsor::where('email', $request->email)->first();
            if ($sponsor) {
                $sponsor->update([
                    'is_verified' => true,
                    'otp_verified_at' => now(),
                ]);
            }

            // Clear Cache
            \Illuminate\Support\Facades\Cache::forget('employer_otp_' . $request->email);

            return response()->json([
                'success' => true,
                'message' => 'Email verified successfully. Proceed to payment selection.',
                'email' => $request->email
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Verification failed. Please try again.'
            ], 500);
        }
    }

    public function payment(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'email' => 'required|email',
            'plan_id' => 'required|string',
            'amount_aed' => 'required|numeric',
            'paytabs_transaction_id' => 'required|string',
        ]);

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

        try {
            $user = User::where('email', $request->email)->first();
            $sponsor = \App\Models\Sponsor::where('email', $request->email)->first();

            if (!$user || !$sponsor) {
                return response()->json([
                    'success' => false,
                    'message' => 'User account not found.'
                ], 404);
            }

            if (!$sponsor->is_verified) {
                return response()->json([
                    'success' => false,
                    'message' => 'Please verify your email before initiating payment.'
                ], 403);
            }

            \Illuminate\Support\Facades\DB::transaction(function () use ($request, $user, $sponsor) {
                // Update User subscription
                $user->update([
                    'subscription_status' => 'active',
                    'subscription_expires_at' => now()->addDays(30),
                ]);

                // Update Sponsor status
                $sponsor->update([
                    'subscription_status' => 'active',
                    'subscription_plan' => $request->plan_id,
                    'subscription_start_date' => now(),
                    'subscription_end_date' => now()->addDays(30),
                    'payment_status' => 'paid',
                ]);

                // Insert into subscriptions table
                \Illuminate\Support\Facades\DB::table('subscriptions')->insert([
                    'user_id' => $user->id,
                    'plan_id' => $request->plan_id,
                    'amount_aed' => $request->amount_aed,
                    'starts_at' => now(),
                    'expires_at' => now()->addDays(30),
                    'paytabs_transaction_id' => $request->paytabs_transaction_id,
                    'status' => 'active',
                    'created_at' => now(),
                    'updated_at' => now(),
                ]);
            });

            return response()->json([
                'success' => true,
                'message' => 'Subscription payment processed and activated successfully.',
                'email' => $request->email
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Payment processing failed. Please try again.'
            ], 500);
        }
    }

    public function password(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'email' => 'required|email',
            'password' => 'required|string|min:8|confirmed',
        ]);

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

        try {
            $user = User::where('email', $request->email)->first();
            $sponsor = \App\Models\Sponsor::where('email', $request->email)->first();

            if (!$user || !$sponsor) {
                return response()->json([
                    'success' => false,
                    'message' => 'User account not found.'
                ], 404);
            }

            if ($sponsor->payment_status !== 'paid') {
                return response()->json([
                    'success' => false,
                    'message' => 'Please complete subscription payment first.'
                ], 403);
            }

            // Generate API Bearer token
            $apiToken = Str::random(80);

            \Illuminate\Support\Facades\DB::transaction(function () use ($request, $user, $sponsor, $apiToken) {
                $hashedPassword = Hash::make($request->password);

                $user->update([
                    'password' => $hashedPassword,
                    'api_token' => $apiToken,
                ]);

                $sponsor->update([
                    'password' => $hashedPassword,
                    'status' => 'active',
                ]);

                // Approve profile verification
                $profile = EmployerProfile::where('user_id', $user->id)->first();
                if ($profile) {
                    $profile->update([
                        'verification_status' => 'approved'
                    ]);
                }
            });

            return response()->json([
                'success' => true,
                'message' => 'Password created successfully. Registration finalized.',
                'data' => [
                    'sponsor' => $user->load('employerProfile'),
                    'token' => $apiToken
                ]
            ]);

        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to set password. Please try again.'
            ], 500);
        }
    }

    public function plans()
    {
        return response()->json([
            'success' => true,
            'data' => [
                'plans' => [
                    [
                        'id' => 'basic',
                        'name' => 'Basic Search',
                        'price' => 99.00,
                        'currency' => 'AED',
                        'period' => 'month',
                        'features' => ['Browse 500+ verified workers', 'Shortlist up to 10 candidates', 'Standard OCR verification'],
                        'popular' => false,
                    ],
                    [
                        'id' => 'premium',
                        'name' => 'Premium Employer Pass',
                        'price' => 199.00,
                        'currency' => 'AED',
                        'period' => 'month',
                        'features' => ['Unlimited shortlisting', 'Direct candidate messaging', 'Priority interview scheduling', 'Dedicated support'],
                        'popular' => true,
                    ],
                    [
                        'id' => 'enterprise',
                        'name' => 'VIP Concierge',
                        'price' => 499.00,
                        'currency' => 'AED',
                        'period' => 'month',
                        'features' => ['All Premium features', 'Assigned recruitment manager', 'Background medical verification guarantee', 'Free replacement within 30 days'],
                        'popular' => false,
                    ]
                ]
            ]
        ]);
    }

    public function forgotPassword(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'email' => 'required|email',
        ]);

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

        try {
            $user = User::where('email', $request->email)->where('role', 'employer')->first();
            if (!$user) {
                return response()->json([
                    'success' => false,
                    'message' => 'No employer account found with this email address.'
                ], 404);
            }

            $otp = '111111'; // default development OTP
            if (app()->environment('production')) {
                $otp = strval(rand(100000, 999999));
            }

            \Illuminate\Support\Facades\Cache::put('employer_reset_otp_' . $request->email, [
                'code' => $otp,
                'expires_at' => now()->addMinutes(10)->timestamp
            ], 600);

            // Send reset OTP email
            try {
                \Illuminate\Support\Facades\Mail::to($request->email)->send(new \App\Mail\EmployerResetOtpMail(
                    $otp,
                    $user->name
                ));
            } catch (\Exception $mailEx) {
                logger()->error('API Employer Forgot Password Mail Failure: ' . $mailEx->getMessage());
            }

            return response()->json([
                'success' => true,
                'message' => 'Password reset verification code sent to email successfully.',
                'email' => $request->email
            ], 200);

        } catch (\Exception $e) {
            logger()->error('API Employer Forgot Password Failure: ' . $e->getMessage());
            return response()->json([
                'success' => false,
                'message' => 'An error occurred. Please try again.',
                'error' => app()->environment('local') ? $e->getMessage() : 'Internal Server Error'
            ], 500);
        }
    }

    public function resetPassword(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'email' => 'required|email',
            'otp' => 'required|string|size:6',
            'password' => 'required|string|min:8|confirmed',
        ]);

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

        $cachedData = \Illuminate\Support\Facades\Cache::get('employer_reset_otp_' . $request->email);

        if (!$cachedData || !isset($cachedData['code']) || !isset($cachedData['expires_at'])) {
            return response()->json([
                'success' => false,
                'message' => 'Invalid or expired verification code.'
            ], 400);
        }

        if ($cachedData['code'] !== $request->otp || now()->timestamp > $cachedData['expires_at']) {
            return response()->json([
                'success' => false,
                'message' => 'Invalid or expired verification code.'
            ], 400);
        }

        try {
            $user = User::where('email', $request->email)->where('role', 'employer')->first();
            $sponsor = \App\Models\Sponsor::where('email', $request->email)->first();

            if (!$user || !$sponsor) {
                return response()->json([
                    'success' => false,
                    'message' => 'User account not found.'
                ], 404);
            }

            $apiToken = Str::random(80);

            \Illuminate\Support\Facades\DB::transaction(function () use ($request, $user, $sponsor, $apiToken) {
                $hashedPassword = Hash::make($request->password);

                $user->update([
                    'password' => $hashedPassword,
                    'api_token' => $apiToken,
                ]);

                $sponsor->update([
                    'password' => $hashedPassword,
                ]);
            });

            \Illuminate\Support\Facades\Cache::forget('employer_reset_otp_' . $request->email);

            return response()->json([
                'success' => true,
                'message' => 'Password reset successfully.',
                'data' => [
                    'employer' => $user->load('employerProfile'),
                    'token' => $apiToken
                ]
            ], 200);

        } catch (\Exception $e) {
            logger()->error('API Employer Reset Password Failure: ' . $e->getMessage());
            return response()->json([
                'success' => false,
                'message' => 'Failed to reset password. Please try again.',
                'error' => app()->environment('local') ? $e->getMessage() : 'Internal Server Error'
            ], 500);
        }
    }
}
