<?php

declare(strict_types=1);

namespace App\Controllers;

use App\Core\Auth;
use App\Core\Controller;
use App\Core\Csrf;
use App\Core\Response;
use App\Core\Session;
use App\Services\UserService;
use InvalidArgumentException;

final class UserController extends Controller
{
    public function __construct(private ?UserService $service = null)
    {
        $this->service ??= new UserService();
    }

    public function index(): Response
    {
        $result = $this->service->list($_GET);
        return $this->view('users/index', [
            'pageTitle' => 'Users', 'pageDescription' => 'Manage CRM accounts, roles and access status.',
            'users' => $result['items'], 'pagination' => $result,
            'filters' => ['search' => (string) ($_GET['search'] ?? ''), 'status' => (string) ($_GET['status'] ?? ''), 'role' => (string) ($_GET['role'] ?? '')],
            'roles' => $this->service->roles(), 'message' => Session::pull('user_message'), 'error' => Session::pull('user_error'),
        ]);
    }

    public function createForm(): Response
    {
        return $this->view('users/form', ['pageTitle' => 'Create User', 'pageDescription' => 'Create a CRM account and assign its role.', 'roles' => $this->service->roles(), 'user' => null, 'selectedRoles' => [], 'csrf' => Csrf::token(), 'error' => Session::pull('user_error'), 'form' => Session::pull('user_form')]);
    }

    public function create(): Response
    {
        Csrf::verify((string) ($_POST['_csrf'] ?? ''));
        $form = $_POST;
        try {
            $id = $this->service->create((string) ($form['full_name'] ?? ''), (string) ($form['email'] ?? ''), (string) ($form['phone'] ?? ''), (string) ($form['password'] ?? ''), (string) ($form['status'] ?? 'active'), (array) ($form['roles'] ?? []), Auth::id() ?? 0);
            Session::put('user_message', 'User created successfully.');
            return Response::redirect('/crm/public/users/' . $id . '/edit');
        } catch (InvalidArgumentException $e) {
            Session::put('user_error', $e->getMessage()); Session::put('user_form', $form);
            return Response::redirect('/crm/public/users/create');
        }
    }

    public function editForm(int $id): Response
    {
        if (!$this->service->canManage($id, Auth::id() ?? 0)) {
            throw new InvalidArgumentException('You do not have permission to manage this user account.');
        }
        $user = $this->service->find($id);
        return $this->view('users/form', ['pageTitle' => 'Edit User', 'pageDescription' => 'Update account details, status and roles.', 'roles' => $this->service->roles(), 'user' => $user, 'selectedRoles' => array_map(static fn(array $r): int => (int) $r['id'], $user['roles']), 'csrf' => Csrf::token(), 'error' => Session::pull('user_error'), 'message' => Session::pull('user_message'), 'form' => Session::pull('user_form')]);
    }

    public function update(int $id): Response
    {
        Csrf::verify((string) ($_POST['_csrf'] ?? ''));
        $form = $_POST;
        try {
            $this->service->update($id, (string) ($form['full_name'] ?? ''), (string) ($form['email'] ?? ''), (string) ($form['phone'] ?? ''), (string) ($form['status'] ?? 'active'), (array) ($form['roles'] ?? []), ((string) ($form['password'] ?? '')) !== '' ? (string) $form['password'] : null, Auth::id() ?? 0);
            Session::put('user_message', 'User updated successfully.');
            return Response::redirect('/crm/public/users/' . $id . '/edit');
        } catch (InvalidArgumentException $e) {
            Session::put('user_error', $e->getMessage()); Session::put('user_form', $form);
            return Response::redirect('/crm/public/users/' . $id . '/edit');
        }
    }

    public function disable(int $id): Response
    {
        Csrf::verify((string) ($_POST['_csrf'] ?? ''));
        try { $this->service->disable($id, Auth::id() ?? 0); Session::put('user_message', 'User disabled successfully.'); }
        catch (InvalidArgumentException $e) { Session::put('user_error', $e->getMessage()); }
        return Response::redirect('/crm/public/users');
    }
}
