<?php

namespace Modules\Users\Controllers;

use core\Controller;
use core\Auth;
use core\Database;
use core\Security;
use core\Session;

class UserController extends Controller
{
    public function index(): void
    {
        $this->requirePermission('users_view');

        $db = Database::getInstance();
        $search = $this->request->get('search', '');
        $status = $this->request->get('status', '');
        $roleId = $this->request->get('role_id', '');
        $page = max(1, (int)$this->request->get('page', 1));
        $perPage = PAGINATION_LIMIT;

        $query = $db->table('users u')
            ->select('u.*, r.name as role_name, b.name as branch_name')
            ->leftJoin('roles r', 'u.role_id', '=', 'r.id')
            ->leftJoin('branches b', 'u.branch_id', '=', 'b.id');

        if (!empty($search)) {
            $query->where(function ($q) use ($search) {
                $q->where('u.first_name', 'LIKE', '%' . $search . '%')
                  ->orWhere('u.last_name', 'LIKE', '%' . $search . '%')
                  ->orWhere('u.email', 'LIKE', '%' . $search . '%')
                  ->orWhere('u.username', 'LIKE', '%' . $search . '%');
            });
        }

        if (!empty($status)) {
            $query->where('u.status', $status);
        }

        if (!empty($roleId)) {
            $query->where('u.role_id', (int)$roleId);
        }

        $users = $query->orderBy('u.id', 'DESC')->paginate($perPage, $page);

        $roles = $db->table('roles')->orderBy('name', 'ASC')->get();
        $branches = $db->table('branches')->where('deleted_at', 'IS', null)->orderBy('name', 'ASC')->get();

        $this->view('Users/index', [
            'title' => 'Users',
            'breadcrumb' => ['Users' => url('users')],
            'users' => $users,
            'roles' => $roles,
            'branches' => $branches,
            'search' => $search,
            'status' => $status,
            'roleId' => $roleId,
        ]);
    }

    public function create(): void
    {
        $this->requirePermission('users_create');

        $db = Database::getInstance();
        $roles = $db->table('roles')->orderBy('name', 'ASC')->get();
        $branches = $db->table('branches')->where('deleted_at', 'IS', null)->orderBy('name', 'ASC')->get();

        $this->view('Users/create', [
            'title' => 'Create User',
            'breadcrumb' => [
                'Users' => url('users'),
                'Create' => url('users/create'),
            ],
            'roles' => $roles,
            'branches' => $branches,
        ]);
    }

    public function store(): void
    {
        $this->requirePermission('users_create');

        if (!Security::validateCsrfToken($this->request->post(CSRF_TOKEN_NAME))) {
            Session::setAlert('danger', 'Invalid security token.');
            $this->back();
            return;
        }

        $firstName = trim($this->request->post('first_name', ''));
        $lastName = trim($this->request->post('last_name', ''));
        $email = trim($this->request->post('email', ''));
        $username = trim($this->request->post('username', ''));
        $password = $this->request->post('password', '');
        $roleId = $this->request->post('role_id');
        $branchId = $this->request->post('branch_id');
        $phone = trim($this->request->post('phone', ''));
        $status = $this->request->post('status', 'active');
        $isSuperadmin = $this->request->post('is_superadmin', '0');

        if (empty($firstName) || empty($lastName) || empty($email) || empty($username) || empty($password)) {
            Session::setAlert('danger', 'First name, last name, email, username and password are required.');
            $this->back();
            return;
        }

        if (strlen($password) < 8) {
            Session::setAlert('danger', 'Password must be at least 8 characters.');
            $this->back();
            return;
        }

        if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
            Session::setAlert('danger', 'Invalid email address.');
            $this->back();
            return;
        }

        $db = Database::getInstance();

        $existing = $db->table('users')->where('email', $email)->first();
        if ($existing) {
            Session::setAlert('danger', 'Email already in use.');
            $this->back();
            return;
        }

        $existing = $db->table('users')->where('username', $username)->first();
        if ($existing) {
            Session::setAlert('danger', 'Username already taken.');
            $this->back();
            return;
        }

        $userId = $db->table('users')->insert([
            'first_name' => $firstName,
            'last_name' => $lastName,
            'email' => $email,
            'username' => $username,
            'password' => Security::hashPassword($password),
            'role_id' => $roleId ?: null,
            'branch_id' => $branchId ?: null,
            'phone' => $phone,
            'status' => $status,
            'is_superadmin' => $isSuperadmin === '1' ? 1 : 0,
            'created_at' => date(DATE_TIME_FORMAT),
            'updated_at' => date(DATE_TIME_FORMAT),
        ]);

        Auth::logActivity('user_create', 'Created user: ' . $firstName . ' ' . $lastName);
        Session::setAlert('success', 'User created successfully.');
        $this->redirect(url('users'));
    }

    public function edit(int $id): void
    {
        $this->requirePermission('users_edit');

        $db = Database::getInstance();
        $user = $db->table('users')->find($id);

        if (!$user) {
            Session::setAlert('danger', 'User not found.');
            $this->redirect(url('users'));
            return;
        }

        $roles = $db->table('roles')->orderBy('name', 'ASC')->get();
        $branches = $db->table('branches')->where('deleted_at', 'IS', null)->orderBy('name', 'ASC')->get();

        $this->view('Users/edit', [
            'title' => 'Edit User',
            'breadcrumb' => [
                'Users' => url('users'),
                'Edit' => url('users/edit/' . $id),
            ],
            'user' => $user,
            'roles' => $roles,
            'branches' => $branches,
        ]);
    }

    public function update(int $id): void
    {
        $this->requirePermission('users_edit');

        if (!Security::validateCsrfToken($this->request->post(CSRF_TOKEN_NAME))) {
            Session::setAlert('danger', 'Invalid security token.');
            $this->back();
            return;
        }

        $db = Database::getInstance();
        $user = $db->table('users')->find($id);

        if (!$user) {
            Session::setAlert('danger', 'User not found.');
            $this->redirect(url('users'));
            return;
        }

        $firstName = trim($this->request->post('first_name', ''));
        $lastName = trim($this->request->post('last_name', ''));
        $email = trim($this->request->post('email', ''));
        $username = trim($this->request->post('username', ''));
        $password = $this->request->post('password', '');
        $roleId = $this->request->post('role_id');
        $branchId = $this->request->post('branch_id');
        $phone = trim($this->request->post('phone', ''));
        $status = $this->request->post('status', 'active');
        $isSuperadmin = $this->request->post('is_superadmin', '0');

        if (empty($firstName) || empty($lastName) || empty($email) || empty($username)) {
            Session::setAlert('danger', 'First name, last name, email and username are required.');
            $this->back();
            return;
        }

        if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
            Session::setAlert('danger', 'Invalid email address.');
            $this->back();
            return;
        }

        $existing = $db->table('users')->where('email', $email)->where('id', '!=', $id)->first();
        if ($existing) {
            Session::setAlert('danger', 'Email already in use by another user.');
            $this->back();
            return;
        }

        $existing = $db->table('users')->where('username', $username)->where('id', '!=', $id)->first();
        if ($existing) {
            Session::setAlert('danger', 'Username already taken.');
            $this->back();
            return;
        }

        $data = [
            'first_name' => $firstName,
            'last_name' => $lastName,
            'email' => $email,
            'username' => $username,
            'role_id' => $roleId ?: null,
            'branch_id' => $branchId ?: null,
            'phone' => $phone,
            'status' => $status,
            'is_superadmin' => $isSuperadmin === '1' ? 1 : 0,
            'updated_at' => date(DATE_TIME_FORMAT),
        ];

        if (!empty($password)) {
            if (strlen($password) < 8) {
                Session::setAlert('danger', 'Password must be at least 8 characters.');
                $this->back();
                return;
            }
            $data['password'] = Security::hashPassword($password);
        }

        $db->table('users')->where('id', $id)->update($data);

        Auth::logActivity('user_update', 'Updated user: ' . $firstName . ' ' . $lastName);
        Session::setAlert('success', 'User updated successfully.');
        $this->redirect(url('users'));
    }

    public function delete(int $id): void
    {
        $this->requirePermission('users_delete');

        if (!Security::validateCsrfToken($this->request->post(CSRF_TOKEN_NAME))) {
            Session::setAlert('danger', 'Invalid security token.');
            $this->back();
            return;
        }

        $db = Database::getInstance();
        $user = $db->table('users')->find($id);

        if (!$user) {
            Session::setAlert('danger', 'User not found.');
            $this->redirect(url('users'));
            return;
        }

        if ($user->is_superadmin) {
            Session::setAlert('danger', 'Superadmin users cannot be deleted.');
            $this->redirect(url('users'));
            return;
        }

        $db->table('users')->where('id', $id)->delete();

        Auth::logActivity('user_delete', 'Deleted user: ' . ($user->first_name ?? '') . ' ' . ($user->last_name ?? ''));
        Session::setAlert('success', 'User deleted successfully.');
        $this->redirect(url('users'));
    }
}
