<?php
// app/Controllers/Frontend/AuthController.php

namespace App\Controllers\Frontend;

use App\Controllers\BaseController;
use App\Models\UserModel;
use App\Models\VerificationTokenModel;
use App\Models\PasswordResetTokenModel;
use App\Libraries\EmailService;
use App\Libraries\WhatsappService;

class AuthController extends BaseController
{
    /**
     * Menampilkan halaman formulir login.
     */
    public function showLoginForm()
    {
        return view('frontend/auth/login');
    }

    /**
     * Memproses percobaan login dari pengguna.
     * Mengarahkan ke verifikasi jika akun belum terverifikasi.
     */
    public function processLogin()
    {
        $rules = ['email' => 'required|valid_email', 'password' => 'required'];
        if (! $this->validate($rules)) {
            return redirect()->back()->withInput()->with('errors', $this->validator->getErrors());
        }

        $userModel = new UserModel();
        $user = $userModel->where('email', $this->request->getPost('email'))->first();

        if (!$user || !password_verify($this->request->getPost('password'), $user->password)) {
            return redirect()->back()->withInput()->with('error', lang('Login.errorInvalid'));
        }
        
        // Cek jika user sudah terverifikasi
        if ($user->email_verified_at !== null || $user->phone_verified_at !== null) {
            $this->logUserIn($user);
            return redirect()->to(route_to('dashboard.show'))->with('success', lang('Dashboard.welcomeBack', [$user->name]));
        }

        // Jika belum, mulai alur verifikasi
        session()->setTempdata('verifying_user_id', $user->id, 300); // Sesi verifikasi berlaku 5 menit
        return redirect()->to(route_to('verify.choice'));
    }

    /**
     * Menghancurkan sesi (logout).
     */
    public function logout()
    {
        session()->destroy();
        return redirect()->to(route_to('login.show'))->with('success', lang('Login.successLogout'));
    }
    
    // --- ALUR VERIFIKASI ---

    /**
     * Menampilkan halaman pilihan metode verifikasi.
     * Mengirimkan data 'cooldown' ke view jika diperlukan.
     */
    public function showVerificationChoice()
    {
        if (session()->getTempdata('verifying_user_id') === null) {
            return redirect()->to(route_to('login.show'))->with('error', lang('Verification.errorSessionExpired'));
        }

        $data = [];
        $lastSentTime = session()->get('last_verification_sent_at');
        
        // Cek apakah user sedang dalam masa jeda
        if ($lastSentTime && (time() - $lastSentTime < 60)) {
            $data['cooldown'] = 60 - (time() - $lastSentTime);
        }
        
        return view('frontend/auth/verify_choice', $data);
    }

    /**
     * Membuat dan mengirim LINK verifikasi ke media yang dipilih.
     * Termasuk logika jeda waktu (cooldown).
     */
    public function sendVerificationLink()
    {
        $userId = session()->getTempdata('verifying_user_id');
        $medium = $this->request->getPost('medium');

        if (!$userId || !in_array($medium, ['email', 'whatsapp'])) {
            return redirect()->to(route_to('login.show'))->with('error', lang('Verification.errorInvalidRequest'));
        }

        // --- Logika Jeda Waktu (Server-side) ---
        $lastSentTime = session()->get('last_verification_sent_at');
        if ($lastSentTime && (time() - $lastSentTime < 60)) {
            $remaining = 60 - (time() - $lastSentTime);
            // Tambahkan pesan ini ke file lang/Verification.php jika belum ada
            return redirect()->back()->with('error', "Please wait {$remaining} more seconds before requesting a new link.");
        }
        // --- Akhir Logika Jeda Waktu ---

        $userModel = new UserModel();
        $user = $userModel->find($userId);

        $tokenModel = new VerificationTokenModel();
        $tokenModel->where('user_id', $userId)->delete(); // Hapus token lama

        $token = bin2hex(random_bytes(32));
        $tokenModel->insert([
            'user_id'    => $userId,
            'token'      => $token,
            'medium'     => $medium,
            'expires_at' => date('Y-m-d H:i:s', time() + 3600) // Token berlaku 1 jam
        ]);

        $verificationLink = site_url(route_to('verify.link', $token));

        $isSent = false;
        if ($medium === 'email') {
            $emailService = new EmailService();
            $isSent = $emailService->sendVerificationLink($user->email, $verificationLink);
        } elseif ($medium === 'whatsapp') {
            $whatsappService = new WhatsappService();
            $isSent = $whatsappService->sendVerificationLink($user->phone_number, $verificationLink);
        }

        if (!$isSent) {
            return redirect()->back()->with('error', lang('Verification.errorFailedToSendLink'));
        }
        
        // Simpan waktu pengiriman terakhir ke sesi
        session()->set('last_verification_sent_at', time());

        return redirect()->to(route_to('verify.choice'))
                         ->with('success', lang('Verification.successLinkSent', [$medium]));
    }

    /**
     * Memproses link verifikasi yang diklik oleh pengguna.
     */
    public function processVerificationLink(string $token)
    {
        if (empty($token)) {
            return redirect()->to(route_to('login.show'))->with('error', lang('Verification.errorInvalidToken'));
        }

        $tokenModel = new VerificationTokenModel();
        $storedToken = $tokenModel->where('token', $token)
                                  ->where('expires_at >', date('Y-m-d H:i:s'))
                                  ->first();

        if (!$storedToken) {
            return redirect()->to(route_to('login.show'))->with('error', lang('Verification.errorInvalidOrExpiredToken'));
        }

        $userId = $storedToken->user_id;
        $medium = $storedToken->medium;

        $userModel = new UserModel();
        $userModel->update($userId, [
            ($medium === 'email' ? 'email_verified_at' : 'phone_verified_at') => date('Y-m-d H:i:s')
        ]);
        
        $tokenModel->delete($storedToken->id);

        $user = $userModel->find($userId);
        $this->logUserIn($user);

        return redirect()->to(route_to('dashboard.show'))->with('success', lang('Verification.successVerified'));
    }

    // --- HELPER METHODS ---

    /**
     * Membuat sesi login untuk pengguna.
     */
    private function logUserIn(object $user): void
    {
        $sessionData = [
            'user_id'    => $user->id,
            'user_name'  => $user->name,
            'user_email' => $user->email,
            'user_type'  => 'user',
            'isLoggedIn' => true,
        ];

        session()->set($sessionData);
    }

    // --- FORGOT PASSWORD ---

    public function showForgotPasswordForm()
    {
        return view('frontend/auth/forgot');
    }

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

        $userModel = new UserModel();
        $user = $userModel->where('email', $this->request->getPost('email'))->first();

        if ($user) {
            $tokenModel = new PasswordResetTokenModel();
            $tokenModel->where('user_id', $user->id)->delete();

            $token = bin2hex(random_bytes(32));
            $tokenModel->insert([
                'user_id'    => $user->id,
                'token'      => $token,
                'expires_at' => date('Y-m-d H:i:s', time() + 3600)
            ]);
            
            $emailService = new EmailService();
            $resetLink = site_url(route_to('reset.form', $token));
            $emailService->sendPasswordResetLink($user->email, $resetLink);
        } else {
            // Untuk keamanan, jangan beri tahu jika email tidak ada.
            // Cukup tampilkan pesan yang sama.
            log_message('info', 'Password reset requested for non-existent email: ' . $this->request->getPost('email'));
        }

        return redirect()->route('forgot.form')->with('success', lang('Forgot.successLinkSent'));
    }

    public function showResetForm(string $token)
    {
        $tokenModel = new PasswordResetTokenModel();
        $storedToken = $tokenModel->where('token', $token)
                                  ->where('expires_at >', date('Y-m-d H:i:s'))
                                  ->first();
        
        if (!$storedToken) {
            return redirect()->to(route_to('login.show'))->with('error', lang('Forgot.errorLinkInvalid'));
        }

        return view('frontend/auth/reset', ['token' => $token]);
    }

    public function processReset()
    {
        $rules = [
            'token' => 'required',
            'password' => 'required|min_length[8]',
            'password_confirm' => 'required|matches[password]'
        ];
        if (!$this->validate($rules)) {
            return redirect()->back()->withInput()->with('errors', $this->validator->getErrors());
        }

        $tokenModel = new PasswordResetTokenModel();
        $storedToken = $tokenModel->where('token', $this->request->getPost('token'))
                                  ->where('expires_at >', date('Y-m-d H:i:s'))
                                  ->first();
                                  
        if (!$storedToken) {
            return redirect()->to(route_to('login.show'))->with('error', lang('Forgot.errorLinkInvalid'));
        }

        // Update password user
        $userModel = new UserModel();
        $userModel->update($storedToken->user_id, [
            'password' => $this->request->getPost('password') // Model akan hash otomatis
        ]);

        // Hapus token setelah dipakai
        $tokenModel->delete($storedToken->id);
        
        return redirect()->to(route_to('login.show'))->with('success', lang('Forgot.successPasswordReset'));
    }
}
