<?php
namespace App\Controllers;

class Auth extends BaseController
{
    public function login()
    {
        if (session()->get('logged_in')) {
            return redirect()->to(base_url('dashboard'));
        }
        return view('auth/login', [
            'settings'       => $this->settings,
            'companyLogoUrl' => $this->logoUrl(),
            'title'          => 'Login',
        ]);
    }

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

        $email    = $this->request->getPost('email');
        $password = $this->request->getPost('password');

        $user = $this->db->table('users u')
            ->select('u.*, r.name as role_name, r.display_name as role_display')
            ->join('roles r', 'r.id = u.role_id', 'left')
            ->where('u.email', $email)
            ->where('u.status', 'active')
            ->get()->getRowArray();

        if (! $user || ! password_verify($password, $user['password'])) {
            $this->logLoginAttempt($email, false);
            return redirect()->back()->withInput()
                ->with('error', 'Invalid email or password. Please try again.');
        }

        $this->logLoginAttempt($email, true);

        session()->set([
            'logged_in'    => true,
            'user_id'      => (int) $user['id'],
            'user_name'    => $user['name'],
            'user_email'   => $user['email'],
            'user_role'    => $user['role_name'],
            'role_display' => $user['role_display'],
            'company_id'   => $user['company_id'] ?? null,
        ]);

        // Flush session to disk before redirect
        session()->regenerate(false);

        $this->db->table('users')->where('id', $user['id'])
            ->update(['last_login' => date('Y-m-d H:i:s')]);

        return redirect()->to(base_url('dashboard'));
    }

    public function logout()
    {
        session()->destroy();
        return redirect()->to(base_url('login'))
            ->with('success', 'You have been logged out successfully.');
    }

    public function register()
    {
        if (session()->get('logged_in')) {
            return redirect()->to(base_url('dashboard'));
        }
        return view('auth/register', [
            'settings'       => $this->settings,
            'companyLogoUrl' => $this->logoUrl(),
            'title'          => 'Register',
        ]);
    }

    public function doRegister()
    {
        $rules = [
            'name'             => 'required|min_length[2]',
            'email'            => 'required|valid_email|is_unique[users.email]',
            'password'         => 'required|min_length[8]',
            'confirm_password' => 'required|matches[password]',
        ];
        $messages = [
            'email'            => ['is_unique' => 'This email is already registered.'],
            'confirm_password' => ['matches'   => 'Passwords do not match.'],
        ];
        if (! $this->validate($rules, $messages)) {
            return redirect()->back()->withInput()->with('errors', $this->validator->getErrors());
        }

        $clientRoleId = $this->roleIdByName('client');
        if (!$clientRoleId) {
            return redirect()->back()->with('error', 'Client role is not configured. Contact administrator.');
        }
        $this->db->table('users')->insert([
            'role_id'  => $clientRoleId,
            'name'     => esc($this->request->getPost('name')),
            'email'    => $this->request->getPost('email'),
            'password' => password_hash($this->request->getPost('password'), PASSWORD_BCRYPT),
            'status'   => 'active',
        ]);

        return redirect()->to(base_url('login'))
            ->with('success', 'Account created! You can now log in.');
    }

    private function logLoginAttempt(string $email, bool $success): void
    {
        try {
            if ($this->db->tableExists('login_attempts')) {
                $this->db->table('login_attempts')->insert([
                    'email'      => strtolower(trim($email)),
                    'ip_address' => $this->request->getIPAddress(),
                    'success'    => $success ? 1 : 0,
                    'created_at' => date('Y-m-d H:i:s'),
                ]);
            }
        } catch (\Throwable $e) {
            log_message('error', 'login_attempt log failed: ' . $e->getMessage());
        }
    }
}
