<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class Auth extends MY_Controller {

    public function __construct() {
        parent::__construct();
    }

    /**
     * Login page
     */
    public function login() {
        // Redirect if already logged in
        if ($this->session->userdata('logged_in')) {
            $this->_redirect_after_login();
            return;
        }
        
        $this->data['title'] = 'Login';
        $this->render('auth/login', $this->data);
    }

    /**
     * Process login
     */
    public function do_login() {
        // Only allow POST requests
        if ($this->input->method() !== 'post') {
            redirect('auth/login');
            return;
        }

        $this->form_validation->set_rules('email', 'Email', 'required|valid_email');
        $this->form_validation->set_rules('password', 'Password', 'required');
        
        if (!$this->form_validation->run()) {
            if ($this->input->is_ajax_request()) {
                $this->error('Validation failed', validation_errors());
                return;
            }
            
            $this->session->set_flashdata('error', strip_tags(validation_errors()));
            redirect('auth/login');
            return;
        }
        
        $email = $this->input->post('email', TRUE);
        $password = $this->input->post('password', TRUE);
        $ip_address = $this->input->ip_address();
        $user_agent = $this->input->user_agent();
        
        // Check for too many failed attempts
        $failed_attempts = $this->User_model->count_failed_attempts($email);
        if ($failed_attempts >= 5) {
            $this->User_model->log_login_attempt($email, $ip_address, $user_agent, false);
            $message = 'Too many failed login attempts. Please try again in 30 minutes.';
            
            if ($this->input->is_ajax_request()) {
                $this->error($message);
                return;
            }
            
            $this->session->set_flashdata('error', $message);
            redirect('auth/login');
            return;
        }
        
        // Get user by email
        $user = $this->User_model->get_by_email($email);
        
        if (!$user || !password_verify($password, $user->password)) {
            $this->User_model->log_login_attempt($email, $ip_address, $user_agent, false);
            $message = 'Invalid email or password';
            
            if ($this->input->is_ajax_request()) {
                $this->error($message);
                return;
            }
            
            $this->session->set_flashdata('error', $message);
            redirect('auth/login');
            return;
        }
        
        // Check user status
        if ($user->status === 'pending') {
            $message = 'Your account is pending verification. Please check your email.';
            if ($this->input->is_ajax_request()) {
                $this->error($message);
                return;
            }
            $this->session->set_flashdata('error', $message);
            redirect('auth/login');
            return;
        }
        
        if ($user->status === 'suspended' || $user->status === 'inactive') {
            $message = 'Your account has been suspended. Please contact support.';
            if ($this->input->is_ajax_request()) {
                $this->error($message);
                return;
            }
            $this->session->set_flashdata('error', $message);
            redirect('auth/login');
            return;
        }
        
        // Log successful attempt
        $this->User_model->log_login_attempt($email, $ip_address, $user_agent, true);
        
        // Update last login
        $this->User_model->update_last_login($user->id, $ip_address);
        
        // Set session data
        $this->session->set_userdata([
            'user_id' => $user->id,
            'user_uuid' => $user->uuid,
            'user_type' => $user->user_type,
            'email' => $user->email,
            'first_name' => $user->first_name,
            'last_name' => $user->last_name,
            'logged_in' => true
        ]);
        
        // Send login notification
        $this->Notification_model->send_security_notification($user->id, 'login', [
            'ip_address' => $ip_address,
            'user_agent' => $user_agent,
            'time' => date('Y-m-d H:i:s')
        ]);
        
        // Log audit
        $this->log_audit('login', 'user', $user->id);
        
        if ($this->input->is_ajax_request()) {
            $redirect_url = $user->user_type === 'admin' ? base_url('admin/dashboard') : base_url('dashboard');
            $this->success('Login successful', ['redirect' => $redirect_url]);
            return;
        }
        
        $this->_redirect_after_login();
    }

    /**
     * Register page
     */
    public function register() {
        if ($this->session->userdata('logged_in')) {
            $this->_redirect_after_login();
            return;
        }
        
        // Check if registration is allowed
        if (!$this->get_setting('allow_registration', true)) {
            $this->session->set_flashdata('error', 'Registration is currently disabled.');
            redirect('auth/login');
            return;
        }
        
        $this->data['title'] = 'Register';
        $this->render('auth/register', $this->data);
    }

    /**
     * Process registration
     */
    public function do_register() {
        // Only allow POST requests
        if ($this->input->method() !== 'post') {
            redirect('auth/register');
            return;
        }

        $this->form_validation->set_rules('first_name', 'First Name', 'required|min_length[2]|max_length[100]');
        $this->form_validation->set_rules('last_name', 'Last Name', 'required|min_length[2]|max_length[100]');
        $this->form_validation->set_rules('email', 'Email', 'required|valid_email|is_unique[users.email]');
        $this->form_validation->set_rules('phone', 'Phone', 'required|min_length[10]|max_length[15]|is_unique[users.phone]');
        $this->form_validation->set_rules('password', 'Password', 'required|min_length[8]');
        $this->form_validation->set_rules('confirm_password', 'Confirm Password', 'required|matches[password]');
        
        if (!$this->form_validation->run()) {
            if ($this->input->is_ajax_request()) {
                $this->error('Validation failed', validation_errors());
                return;
            }
            $this->session->set_flashdata('error', validation_errors());
            redirect('auth/register');
            return;
        }
        
        $this->load->model('Account_model');
        
        // Create user
        $user_id = $this->User_model->create([
            'first_name' => $this->input->post('first_name', TRUE),
            'last_name' => $this->input->post('last_name', TRUE),
            'email' => $this->input->post('email', TRUE),
            'phone' => $this->input->post('phone', TRUE),
            'password' => $this->input->post('password'),
            'user_type' => 'user',
            'status' => 'active' // Auto-activate for demo
        ]);
        
        if (!$user_id) {
            $message = 'Registration failed. Please try again.';
            if ($this->input->is_ajax_request()) {
                $this->error($message);
                return;
            }
            $this->session->set_flashdata('error', $message);
            redirect('auth/register');
            return;
        }
        
        // Create KYC record
        $this->db->insert('kyc', [
            'user_id' => $user_id,
            'tier' => 1,
            'verification_status' => 'pending',
            'created_at' => date('Y-m-d H:i:s')
        ]);
        
        // Create default savings account
        $user = $this->User_model->get($user_id);
        $this->Account_model->create([
            'user_id' => $user_id,
            'account_type' => 'savings',
            'account_name' => $user->first_name . ' ' . $user->last_name . ' Savings',
            'currency' => 'USD',
            'tier_id' => 1,
            'status' => 'active',
            'is_primary' => 1
        ]);
        
        // Send welcome notification
        $this->Notification_model->send($user_id, 'Welcome to ' . get_app_name() . '!', 
            'Your account has been created successfully. Complete your KYC to unlock more features.');
        
        // Log audit
        $this->log_audit('register', 'user', $user_id);
        
        // Log in the user automatically
        $this->session->set_userdata([
            'logged_in' => TRUE,
            'user_id' => $user_id,
            'user_type' => 'user'
        ]);
        
        // Redirect to pending activation page
        if ($this->input->is_ajax_request()) {
            $this->success('Registration successful!', ['redirect' => base_url('auth/pending_activation')]);
            return;
        }
        
        redirect('auth/pending_activation');
    }

    /**
     * Pending activation page
     */
    public function pending_activation() {
        // Check if user is logged in
        if (!$this->session->userdata('logged_in')) {
            redirect('auth/login');
            return;
        }
        
        $user_id = $this->session->userdata('user_id');
        $this->user = $this->User_model->get($user_id);
        
        if (!$this->user) {
            $this->session->sess_destroy();
            redirect('auth/login');
            return;
        }
        
        // Get KYC status
        $kyc = $this->db->get_where('kyc', ['user_id' => $this->user->id])->row();
        
        // If KYC is approved or user is admin, redirect to dashboard
        if (!$kyc || $kyc->verification_status !== 'pending' || $this->user->user_type === 'admin') {
            redirect('dashboard');
            return;
        }
        
        $this->data['title'] = 'Pending Activation';
        $this->data['user'] = $this->user;
        $this->render('auth/pending_activation', $this->data);
    }

    /**
     * Logout
     */
    public function logout() {
        $user_id = $this->session->userdata('user_id');
        
        if ($user_id) {
            $this->log_audit('logout', 'user', $user_id);
        }
        
        $this->session->sess_destroy();
        redirect('auth/login');
    }

    /**
     * Forgot password page
     */
    public function forgot_password() {
        if ($this->session->userdata('logged_in')) {
            $this->_redirect_after_login();
            return;
        }
        
        $this->data['title'] = 'Forgot Password';
        $this->render('auth/forgot_password', $this->data);
    }

    /**
     * Process forgot password
     */
    public function do_forgot_password() {
        // Only allow POST requests
        if ($this->input->method() !== 'post') {
            redirect('auth/forgot_password');
            return;
        }

        $this->form_validation->set_rules('email', 'Email', 'required|valid_email');
        
        if (!$this->form_validation->run()) {
            if ($this->input->is_ajax_request()) {
                $this->error('Please enter a valid email address');
                return;
            }
            redirect('auth/forgot_password');
            return;
        }
        
        $email = $this->input->post('email', TRUE);
        $user = $this->User_model->get_by_email($email);
        
        // Always show success to prevent email enumeration
        $message = 'If an account exists with this email, you will receive password reset instructions.';
        
        if ($user) {
            // Generate reset token
            $token = bin2hex(random_bytes(32));
            $expires_at = date('Y-m-d H:i:s', strtotime('+1 hour'));
            
            // Save reset token to database
            $this->db->insert('password_resets', [
                'user_id' => $user->id,
                'email' => $email,
                'token' => $token,
                'expires_at' => $expires_at,
                'created_at' => date('Y-m-d H:i:s')
            ]);
            
            // Send reset email
            $this->load->library('mailer');
            $reset_url = site_url('auth/reset_password/' . $token);
            
            $email_subject = 'Password Reset Request';
            $email_body = "
                <div style='font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;'>
                    <div style='background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); padding: 30px; text-align: center;'>
                        <h1 style='color: white; margin: 0;'>Password Reset</h1>
                    </div>
                    <div style='background: #f8f9fa; padding: 30px;'>
                        <div style='background: white; padding: 25px; border-radius: 10px; margin-bottom: 20px;'>
                            <h3 style='color: #2d3748; margin-top: 0;'>Hello {$user->first_name},</h3>
                            <p style='color: #6c757d; line-height: 1.6;'>
                                We received a request to reset your password. Click the button below to create a new password:
                            </p>
                            <div style='text-align: center; margin: 30px 0;'>
                                <a href='{$reset_url}' style='display: inline-block; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 15px 40px; border-radius: 10px; text-decoration: none; font-weight: 600;'>
                                    Reset Password
                                </a>
                            </div>
                            <p style='color: #6c757d; font-size: 14px; line-height: 1.6;'>
                                Or copy and paste this link in your browser:<br>
                                <a href='{$reset_url}' style='color: #667eea; word-break: break-all;'>{$reset_url}</a>
                            </p>
                            <p style='color: #6c757d; font-size: 14px; line-height: 1.6;'>
                                This link will expire in 1 hour.
                            </p>
                        </div>
                        <div style='background: #fff3cd; border-left: 4px solid #ffc107; padding: 15px; margin: 20px 0;'>
                            <p style='color: #856404; font-size: 14px; margin: 0;'>
                                <strong>⚠️ Security Notice:</strong><br>
                                If you didn't request a password reset, please ignore this email or contact our support team immediately.
                            </p>
                        </div>
                        <div style='text-align: center; margin-top: 20px; color: #6c757d; font-size: 14px;'>
                            <p>This is an automated message, please do not reply.</p>
                        </div>
                    </div>
                </div>
            ";
            
            $this->mailer->send_email($user->email, $email_subject, $email_body);
            
            // Send in-app notification as well
            $this->Notification_model->send($user->id, 'Password Reset Requested',
                'A password reset was requested for your account. If this wasn\'t you, please contact support.');
                
            // Log audit
            $this->log_audit('password_reset_requested', 'user', $user->id);
        }
        
        if ($this->input->is_ajax_request()) {
            $this->success($message);
            return;
        }
        
        $this->session->set_flashdata('success', $message);
        redirect('auth/login');
    }
    
    /**
     * Reset password page
     */
    public function reset_password($token = null) {
        if ($this->session->userdata('logged_in')) {
            $this->_redirect_after_login();
            return;
        }
        
        if (!$token) {
            redirect('auth/forgot_password');
            return;
        }
        
        // Verify token exists and not expired
        $reset = $this->db->where('token', $token)
                          ->where('expires_at >', date('Y-m-d H:i:s'))
                          ->where('used_at', null)
                          ->get('password_resets')
                          ->row();
        
        if (!$reset) {
            $this->session->set_flashdata('error', 'Invalid or expired reset link. Please request a new one.');
            redirect('auth/forgot_password');
            return;
        }
        
        $this->data['title'] = 'Reset Password';
        $this->data['token'] = $token;
        $this->render('auth/reset_password', $this->data);
    }
    
    /**
     * Process reset password
     */
    public function do_reset_password() {
        if ($this->input->method() !== 'post') {
            redirect('auth/forgot_password');
            return;
        }
        
        $this->form_validation->set_rules('token', 'Token', 'required');
        $this->form_validation->set_rules('password', 'Password', 'required|min_length[8]');
        $this->form_validation->set_rules('confirm_password', 'Confirm Password', 'required|matches[password]');
        
        if (!$this->form_validation->run()) {
            $this->session->set_flashdata('error', validation_errors());
            redirect('auth/reset_password/' . $this->input->post('token'));
            return;
        }
        
        $token = $this->input->post('token', TRUE);
        $password = $this->input->post('password');
        
        // Verify token
        $reset = $this->db->where('token', $token)
                          ->where('expires_at >', date('Y-m-d H:i:s'))
                          ->where('used_at', null)
                          ->get('password_resets')
                          ->row();
        
        if (!$reset) {
            $this->session->set_flashdata('error', 'Invalid or expired reset link. Please request a new one.');
            redirect('auth/forgot_password');
            return;
        }
        
        // Update user password
        $this->User_model->update($reset->user_id, [
            'password' => password_hash($password, PASSWORD_DEFAULT)
        ]);
        
        // Mark token as used
        $this->db->where('id', $reset->id)
                 ->update('password_resets', ['used_at' => date('Y-m-d H:i:s')]);
        
        // Get user for notification
        $user = $this->User_model->get($reset->user_id);
        
        // Send confirmation email
        $this->load->library('mailer');
        $email_subject = 'Password Changed Successfully';
        $email_body = "
            <div style='font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;'>
                <div style='background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); padding: 30px; text-align: center;'>
                    <h1 style='color: white; margin: 0;'>Password Changed</h1>
                </div>
                <div style='background: #f8f9fa; padding: 30px;'>
                    <div style='background: white; padding: 25px; border-radius: 10px; margin-bottom: 20px;'>
                        <h3 style='color: #2d3748; margin-top: 0;'>Hello {$user->first_name},</h3>
                        <p style='color: #6c757d; line-height: 1.6;'>
                            Your password has been successfully changed. You can now log in with your new password.
                        </p>
                        <div style='text-align: center; margin: 30px 0;'>
                            <a href='" . site_url('auth/login') . "' style='display: inline-block; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 15px 40px; border-radius: 10px; text-decoration: none; font-weight: 600;'>
                                Login Now
                            </a>
                        </div>
                    </div>
                    <div style='background: #fff3cd; border-left: 4px solid #ffc107; padding: 15px; margin: 20px 0;'>
                        <p style='color: #856404; font-size: 14px; margin: 0;'>
                            <strong>⚠️ Security Notice:</strong><br>
                            If you didn't make this change, please contact our support team immediately.
                        </p>
                    </div>
                </div>
            </div>
        ";
        
        $this->mailer->send_email($user->email, $email_subject, $email_body);
        
        // Send in-app notification
        $this->Notification_model->send($reset->user_id, 'Password Changed',
            'Your password has been successfully changed. If this wasn\'t you, please contact support immediately.');
        
        // Log audit
        $this->log_audit('password_reset_completed', 'user', $reset->user_id);
        
        $this->session->set_flashdata('success', 'Your password has been reset successfully. You can now login with your new password.');
        redirect('auth/login');
    }

    /**
     * Redirect after successful login
     */
    private function _redirect_after_login() {
        $user_type = $this->session->userdata('user_type');
        
        if ($user_type === 'admin') {
            redirect('admin/dashboard');
        } else {
            redirect('dashboard');
        }
    }
}
