<?php

namespace App\Controllers;

use App\Services\Auth\AuthService;

class Auth extends BaseController
{
    private AuthService $auth;

    public function initController(\CodeIgniter\HTTP\RequestInterface $request, \CodeIgniter\HTTP\ResponseInterface $response, \Psr\Log\LoggerInterface $logger)
    {
        parent::initController($request, $response, $logger);
        $this->auth = new AuthService();
    }

    public function showLogin()
    {
        if (session()->get('user_id')) {
            return redirect()->to('/admin');
        }
        return view('auth/login');
    }

    public function login()
    {
        $rules = ['email' => 'required|valid_email', 'password' => 'required'];
        if (! $this->validate($rules)) {
            return redirect()->back()->withInput()->with('error', implode(' ', $this->validator->getErrors()));
        }

        $user = $this->auth->attemptLogin(
            $this->request->getPost('email'),
            $this->request->getPost('password'),
            $this->request->getIPAddress(),
            $this->request->getUserAgent()->getPlatform() ?? 'unknown',
            $this->request->getUserAgent()->getBrowser() ?? 'unknown'
        );

        if (! $user) {
            // Distinguish "right password, just unverified" from "wrong
            // credentials" so a legitimate pending user gets sent to finish
            // verification instead of a generic error that gives no next step.
            $maybeUser = (new \App\Models\UserModel())->findByEmailWithRole($this->request->getPost('email'));
            if ($maybeUser && password_verify($this->request->getPost('password'), $maybeUser->password_hash) && $maybeUser->status === 'pending_verification') {
                session()->set('pending_verify_user_id', $maybeUser->id);
                return redirect()->to('/verify-account')->with('error', 'Please verify your email and mobile number to activate your account.');
            }
            return redirect()->back()->withInput()->with('error', 'Invalid email or password, or your account is not active.');
        }

        session()->set(['user_id' => $user->id, 'user_name' => $user->name, 'role' => $user->role_slug]);

        return redirect()->to('/admin')->with('success', 'Welcome back, ' . $user->name . '!');
    }

    public function showRegister()
    {
        if (session()->get('user_id')) {
            return redirect()->to('/admin');
        }
        return view('auth/register_choice');
    }

    public function showRegisterAgency()
    {
        return view('auth/register_agency');
    }

    public function registerCandidate()
    {
        $rules = [
            'name'     => 'required|min_length[2]|max_length[150]',
            'email'    => 'required|valid_email|is_unique[users.email]',
            'phone'    => 'required|is_unique[users.phone]',
            'password' => 'required|min_length[8]',
        ];
        $messages = ['phone' => ['is_unique' => 'This mobile number is already registered.']];
        if (! $this->validate($rules, $messages)) {
            return redirect()->back()->withInput()->with('error', implode(' ', $this->validator->getErrors()));
        }

        $result = $this->auth->registerCandidate($this->request->getPost());

        if ($result['user']->status === 'active') {
            session()->set(['user_id' => $result['user']->id, 'user_name' => $result['user']->name, 'role' => $result['user']->role_slug]);
            return redirect()->to('/admin')->with('success', 'Welcome to Job Portal! Let\'s build your profile.');
        }

        session()->set('pending_verify_user_id', $result['user']->id);
        if (isset($result['otp']['email']['debug_code']) || isset($result['otp']['mobile']['debug_code'])) {
            session()->setFlashdata('debug_otp', [
                'email'  => $result['otp']['email']['debug_code'] ?? null,
                'mobile' => $result['otp']['mobile']['debug_code'] ?? null,
            ]);
        }

        return redirect()->to('/verify-account')->with('success', 'Account created! Please verify your email and mobile number to continue.');
    }

    public function registerAgency()
    {
        $rules = [
            'owner_name'   => 'required|min_length[2]|max_length[150]',
            'email'        => 'required|valid_email|is_unique[users.email]',
            'phone'        => 'required|is_unique[users.phone]',
            'password'     => 'required|min_length[8]',
            'company_name' => 'required|min_length[2]|max_length[150]',
        ];
        $messages = ['phone' => ['is_unique' => 'This mobile number is already registered.']];
        if (! $this->validate($rules, $messages)) {
            return redirect()->back()->withInput()->with('error', implode(' ', $this->validator->getErrors()));
        }

        $result = $this->auth->registerAgencyOwner($this->request->getPost());

        if ($result['user']->status === 'active') {
            session()->set(['user_id' => $result['user']->id, 'user_name' => $result['user']->name, 'role' => $result['user']->role_slug]);
            return redirect()->to('/admin')->with('success', 'Agency account created! You are on the Free plan — upgrade anytime from Billing.');
        }

        session()->set('pending_verify_user_id', $result['user']->id);
        if (isset($result['otp']['email']['debug_code']) || isset($result['otp']['mobile']['debug_code'])) {
            session()->setFlashdata('debug_otp', [
                'email'  => $result['otp']['email']['debug_code'] ?? null,
                'mobile' => $result['otp']['mobile']['debug_code'] ?? null,
            ]);
        }

        return redirect()->to('/verify-account')->with('success', 'Agency account created! Please verify your email and mobile number to continue.');
    }

    public function showVerifyAccount()
    {
        $userId = session()->get('pending_verify_user_id');
        if (! $userId) {
            return redirect()->to('/login');
        }
        $user = (new \App\Models\UserModel())->find($userId);
        if (! $user || $user->status === 'active') {
            session()->remove('pending_verify_user_id');
            return redirect()->to('/login');
        }
        return view('auth/verify_account', [
            'email'           => $user->email,
            'phone'           => $user->phone,
            'emailVerified'   => (bool) $user->email_verified_at,
            'mobileVerified'  => (bool) $user->mobile_verified_at,
        ]);
    }

    public function verifyOtp()
    {
        $userId = session()->get('pending_verify_user_id');
        if (! $userId) {
            return redirect()->to('/login');
        }

        $channel = $this->request->getPost('channel'); // 'email' or 'mobile'
        $code = $this->request->getPost('code');

        try {
            (new \App\Services\Auth\OtpService())->verify((int) $userId, $channel, $code);
        } catch (\RuntimeException $e) {
            return redirect()->back()->with('error', $e->getMessage());
        }

        $user = (new \App\Models\UserModel())->findWithRole($userId);
        if ($user->status === 'active') {
            session()->remove('pending_verify_user_id');
            session()->set(['user_id' => $user->id, 'user_name' => $user->name, 'role' => $user->role_slug]);
            return redirect()->to('/admin')->with('success', 'Account verified! Welcome to Job Portal.');
        }

        return redirect()->to('/verify-account')->with('success', ucfirst($channel) . ' verified. One more step to go!');
    }

    public function resendOtp()
    {
        $userId = session()->get('pending_verify_user_id');
        if (! $userId) {
            return redirect()->to('/login');
        }

        $channel = $this->request->getPost('channel');
        $user = (new \App\Models\UserModel())->find($userId);
        $destination = $channel === 'mobile' ? $user->phone : $user->email;

        $result = (new \App\Services\Auth\OtpService())->generateAndSend((int) $userId, $channel, $destination);
        if (isset($result['debug_code'])) {
            session()->setFlashdata('debug_otp', [$channel => $result['debug_code']]);
        }

        return redirect()->to('/verify-account')->with('success', 'A new code has been sent.');
    }

    public function showForgotPassword()
    {
        return view('auth/forgot_password');
    }

    public function forgotPassword()
    {
        $email = $this->request->getPost('email');
        if ($email) {
            $this->auth->requestPasswordReset($email);
        }
        return redirect()->to('/login')->with('success', 'If that email exists, a reset link has been sent.');
    }

    public function showResetPassword(string $token)
    {
        return view('auth/reset_password', ['token' => $token]);
    }

    public function resetPassword(string $token)
    {
        $rules = ['password' => 'required|min_length[8]', 'password_confirmation' => 'matches[password]'];
        if (! $this->validate($rules)) {
            return redirect()->back()->with('error', 'Passwords must match and be at least 8 characters.');
        }

        $success = $this->auth->resetPassword($token, $this->request->getPost('password'));

        return $success
            ? redirect()->to('/login')->with('success', 'Password reset successfully. Please log in.')
            : redirect()->back()->with('error', 'This reset link is invalid or has expired.');
    }

    public function showAcceptInvitation(string $token)
    {
        return view('auth/accept_invitation', ['token' => $token]);
    }

    public function acceptInvitation(string $token)
    {
        $rules = ['name' => 'required|min_length[2]', 'password' => 'required|min_length[8]'];
        if (! $this->validate($rules)) {
            return redirect()->back()->with('error', 'Please provide a valid name and password (min 8 characters).');
        }

        try {
            $result = (new \App\Services\Agency\RecruiterManagementService())->acceptInvitation(
                $token, $this->request->getPost('name'), $this->request->getPost('password')
            );
        } catch (\RuntimeException $e) {
            return redirect()->back()->with('error', $e->getMessage());
        }

        session()->set(['user_id' => $result['user_id'], 'user_name' => $this->request->getPost('name'), 'role' => 'recruiter']);

        return redirect()->to('/admin')->with('success', 'Welcome to the team!');
    }

    public function logout()
    {
        if ($userId = session()->get('user_id')) {
            $this->auth->logout($userId);
        }
        session()->destroy();
        return redirect()->to('/login')->with('success', 'You have been logged out.');
    }
}
