<?php

declare(strict_types=1);

namespace App\Controllers;

use App\Helpers\ActivityLogger;
use App\Models\UserModel;
use Core\Auth;
use Core\Request;
use Core\Session;

final class UserController extends BaseController
{
    private UserModel $model;

    public function __construct()
    {
        $this->model = new UserModel();
    }

    // ── List ──────────────────────────────────────────────────────────────────

    public function index(array $params = []): void
    {
        $this->requirePermission('user.view');

        $page  = max(1, (int) Request::get('page', '1'));
        $total = $this->model->count();
        $users = $this->model->all($page);
        $roles = $this->model->staffRoles();

        $this->view('users.index', [
            'pageTitle'   => 'Staff & Users',
            'breadcrumbs' => ['Users' => null],
            'users'       => $users,
            'roles'       => $roles,
            'pagination'  => paginate($total, $page, ITEMS_PER_PAGE, url('users')),
        ]);
    }

    // ── Create ────────────────────────────────────────────────────────────────

    public function create(array $params = []): void
    {
        $this->requirePermission('user.create');

        $this->view('users.form', [
            'pageTitle'   => 'Add Staff User',
            'breadcrumbs' => ['Users' => url('users'), 'Add User' => null],
            'user'        => null,
            'roles'       => $this->model->staffRoles(),
        ]);
    }

    public function store(array $params = []): void
    {
        $this->requirePermission('user.create');
        Request::verifyCsrf();

        $name     = trim(Request::str('name'));
        $email    = trim(Request::str('email'));
        $phone    = trim(Request::str('phone'));
        $roleId   = (int) Request::str('role_id');
        $password = Request::str('password');
        $isActive = Request::str('is_active', '1') === '1' ? 1 : 0;

        if (strlen($name) < 2 || !filter_var($email, FILTER_VALIDATE_EMAIL)) {
            Session::flash('error', 'Please fill all required fields correctly.');
            $this->redirect('/users/create');
        }
        if (strlen($password) < 8) {
            Session::flash('error', 'Password must be at least 8 characters.');
            $this->redirect('/users/create');
        }
        if ($this->model->emailExists($email)) {
            Session::flash('error', 'Email address is already registered.');
            $this->redirect('/users/create');
        }

        $id = $this->model->create([
            'name'          => $name,
            'email'         => $email,
            'phone'         => $phone,
            'role_id'       => $roleId,
            'password_hash' => \password_hash($password, PASSWORD_BCRYPT, ['cost' => BCRYPT_COST]),
            'is_active'     => $isActive,
            'email_verified'=> 1,
        ]);

        ActivityLogger::created('User', $id, $name);
        Session::flash('success', "User '{$name}' created successfully.");
        $this->redirect('/users');
    }

    // ── Edit ──────────────────────────────────────────────────────────────────

    public function edit(array $params = []): void
    {
        $this->requirePermission('user.edit');

        $id   = (int)($params['id'] ?? 0);
        $user = $this->model->find($id);
        if (!$user) {
            Session::flash('error', 'User not found.');
            $this->redirect('/users');
        }

        $this->view('users.form', [
            'pageTitle'   => 'Edit User — ' . $user['name'],
            'breadcrumbs' => ['Users' => url('users'), 'Edit' => null],
            'user'        => $user,
            'roles'       => $this->model->staffRoles(),
        ]);
    }

    public function update(array $params = []): void
    {
        $this->requirePermission('user.edit');
        Request::verifyCsrf();

        $id   = (int)($params['id'] ?? 0);
        $user = $this->model->find($id);
        if (!$user) {
            Session::flash('error', 'User not found.');
            $this->redirect('/users');
        }

        // Prevent editing own role / deactivating self
        $isSelf = ($id === Auth::id());

        $name     = trim(Request::str('name'));
        $email    = trim(Request::str('email'));
        $phone    = trim(Request::str('phone'));
        $roleId   = $isSelf ? (int)$user['role_id'] : (int) Request::str('role_id');
        $isActive = $isSelf ? 1 : (Request::str('is_active', '1') === '1' ? 1 : 0);
        $password = Request::str('password');

        if (strlen($name) < 2 || !filter_var($email, FILTER_VALIDATE_EMAIL)) {
            Session::flash('error', 'Please fill all required fields correctly.');
            $this->redirect('/users/' . $id . '/edit');
        }
        if ($this->model->emailExists($email, $id)) {
            Session::flash('error', 'Email address is already taken.');
            $this->redirect('/users/' . $id . '/edit');
        }

        $data = [
            'name'      => $name,
            'email'     => $email,
            'phone'     => $phone,
            'role_id'   => $roleId,
            'is_active' => $isActive,
        ];
        if ($password !== '') {
            if (strlen($password) < 8) {
                Session::flash('error', 'New password must be at least 8 characters.');
                $this->redirect('/users/' . $id . '/edit');
            }
            $data['password_hash'] = \password_hash($password, PASSWORD_BCRYPT, ['cost' => BCRYPT_COST]);
        }

        $this->model->update($id, $data);
        ActivityLogger::updated('User', $id, $name);
        Session::flash('success', "User '{$name}' updated successfully.");
        $this->redirect('/users');
    }

    // ── Delete ────────────────────────────────────────────────────────────────

    public function delete(array $params = []): void
    {
        $this->requirePermission('user.delete');
        Request::verifyCsrf();

        $id   = (int)($params['id'] ?? 0);
        $user = $this->model->find($id);

        if (!$user || $id === Auth::id()) {
            Session::flash('error', 'Cannot delete this user.');
            $this->redirect('/users');
        }

        $this->model->delete($id);
        ActivityLogger::deleted('User', $id, $user['name']);
        Session::flash('success', "User '{$user['name']}' deleted.");
        $this->redirect('/users');
    }

    // ── Toggle active ─────────────────────────────────────────────────────────

    public function toggle(array $params = []): void
    {
        $this->requirePermission('user.edit');
        Request::verifyCsrf();

        $id   = (int)($params['id'] ?? 0);
        if ($id === Auth::id()) {
            $this->json(['success' => false, 'message' => 'Cannot deactivate yourself.']);
        }

        $user  = $this->model->find($id);
        $state = $this->model->toggle($id);
        ActivityLogger::toggled('User', $id, $user['name'] ?? '', $state ? 'active' : 'inactive');
        $this->json(['success' => true, 'active' => $state]);
    }

    // ── Reset login lock ──────────────────────────────────────────────────────

    public function resetLock(array $params = []): void
    {
        $this->requirePermission('user.edit');
        Request::verifyCsrf();

        $id = (int)($params['id'] ?? 0);
        $this->model->resetLoginAttempts($id);
        Session::flash('success', 'Login lock cleared.');
        $this->redirect('/users');
    }
}
