<?php
declare(strict_types=1);

namespace App\Controllers;

require_once BASE_PATH . '/app/helpers/permissions.php';

use App\Core\Controller;
use App\Models\User;
use App\Models\Role;

final class UserController extends Controller
{
    public function index(): void
    {
        require_permission('users.manage');

        $userModel = new User();

        $this->view('admin/users/index', [
            'users' => $userModel->all(),
        ]);
    }

    public function create(): void
    {
        require_permission('users.create');

        $roleModel = new Role();
        $userModel = new User();

        if ($this->isPost()) {
            csrf_check();

            $firstName = trim((string) ($_POST['first_name'] ?? ''));
            $lastName = trim((string) ($_POST['last_name'] ?? ''));
            $email = trim((string) ($_POST['email'] ?? ''));
            $password = (string) ($_POST['password'] ?? '');
            $confirmPassword = (string) ($_POST['confirm_password'] ?? '');
            $roleId = (int) ($_POST['role_id'] ?? 5);
            $preferredLang = (string) ($_POST['preferred_lang'] ?? 'en');
            $isActive = isset($_POST['is_active']) ? 1 : 0;

            set_old($_POST);

            if ($firstName === '' || $lastName === '' || $email === '' || $password === '' || $confirmPassword === '') {
                flash('danger', trans('required_fields'));
                redirect('admin/users/create');
            }

            if ($password !== $confirmPassword) {
                flash('danger', trans('password_mismatch'));
                redirect('admin/users/create');
            }

            if ($userModel->emailExists($email)) {
                flash('danger', trans('email_exists'));
                redirect('admin/users/create');
            }

            $newId = $userModel->create([
                'role_id' => $roleId,
                'first_name' => $firstName,
                'last_name' => $lastName,
                'email' => $email,
                'password_hash' => password_hash($password, PASSWORD_DEFAULT),
                'preferred_lang' => in_array($preferredLang, ['ar', 'en'], true) ? $preferredLang : 'en',
                'is_active' => $isActive,
            ]);

            audit_log('create', 'users', $newId, ['email' => $email, 'role_id' => $roleId]);

            clear_old();
            flash('success', trans('user_created_success'));
            redirect('admin/users');
        }

        $this->view('admin/users/create', [
            'roles' => $roleModel->all(),
        ]);
    }

    public function edit(): void
    {
        require_permission('users.edit');

        $id = (int) ($_GET['id'] ?? 0);
        if ($id <= 0) {
            redirect('admin/users');
        }

        $roleModel = new Role();
        $userModel = new User();
        $user = $userModel->findById($id);

        if (!$user) {
            redirect('admin/users');
        }

        if ($this->isPost()) {
            csrf_check();

            $firstName = trim((string) ($_POST['first_name'] ?? ''));
            $lastName = trim((string) ($_POST['last_name'] ?? ''));
            $email = trim((string) ($_POST['email'] ?? ''));
            $password = (string) ($_POST['password'] ?? '');
            $confirmPassword = (string) ($_POST['confirm_password'] ?? '');
            $roleId = (int) ($_POST['role_id'] ?? $user['role_id']);
            $preferredLang = (string) ($_POST['preferred_lang'] ?? 'en');
            $isActive = isset($_POST['is_active']) ? 1 : 0;

            if ($firstName === '' || $lastName === '' || $email === '') {
                flash('danger', trans('required_fields'));
                redirect('admin/users/edit?id=' . $id);
            }

            if ($password !== '' && $password !== $confirmPassword) {
                flash('danger', trans('password_mismatch'));
                redirect('admin/users/edit?id=' . $id);
            }

            if ($userModel->emailExists($email, $id)) {
                flash('danger', trans('email_exists'));
                redirect('admin/users/edit?id=' . $id);
            }

            $userModel->update($id, [
                'role_id' => $roleId,
                'first_name' => $firstName,
                'last_name' => $lastName,
                'email' => $email,
                'preferred_lang' => in_array($preferredLang, ['ar', 'en'], true) ? $preferredLang : 'en',
                'is_active' => $isActive,
                'password_hash' => $password !== '' ? password_hash($password, PASSWORD_DEFAULT) : null,
            ]);

            audit_log('update', 'users', $id, ['email' => $email, 'role_id' => $roleId, 'is_active' => $isActive]);

            if (auth_id() === $id) {
                $freshUser = $userModel->findById($id);
                $freshPermissions = $userModel->getPermissionsByUserId($id);

                $_SESSION['user'] = [
                    'id' => (int) $freshUser['id'],
                    'role_id' => (int) $freshUser['role_id'],
                    'role_code' => (string) $freshUser['role_code'],
                    'role_name' => (string) $freshUser['role_name'],
                    'first_name' => (string) $freshUser['first_name'],
                    'last_name' => (string) $freshUser['last_name'],
                    'email' => (string) $freshUser['email'],
                    'preferred_lang' => (string) $freshUser['preferred_lang'],
                    'permissions' => $freshPermissions,
                ];

                $_SESSION['lang'] = (string) $freshUser['preferred_lang'];
            }

            flash('success', trans('user_updated_success'));
            redirect('admin/users');
        }

        $this->view('admin/users/edit', [
            'userRow' => $user,
            'roles' => $roleModel->all(),
        ]);
    }

    public function toggle(): void
    {
        require_permission('users.toggle');

        if (!$this->isPost()) {
            redirect('admin/users');
        }

        csrf_check();

        $id = (int) ($_POST['id'] ?? 0);
        if ($id <= 0) {
            redirect('admin/users');
        }

        $userModel = new User();
        $user = $userModel->findById($id);

        if (!$user) {
            redirect('admin/users');
        }

        $newStatus = ((int) $user['is_active'] === 1) ? 0 : 1;
        $userModel->setActive($id, $newStatus);

        audit_log('toggle_status', 'users', $id, ['is_active' => $newStatus]);

        if (auth_id() === $id && $newStatus === 0) {
            $_SESSION = [];
            session_destroy();
            redirect('login');
        }

        flash('success', trans('user_status_updated'));
        redirect('admin/users');
    }
    public function bulkReviewers(): void
    {
        require_permission('reviewers.bulk_import');

        if ($this->isPost()) {
            csrf_check();

            if (empty($_FILES['csv_file']['name'])) {
                flash('danger', trans('required_fields'));
                redirect('admin/users/reviewers-bulk');
            }

            try {
                $upload = handle_uploaded_submission_file($_FILES['csv_file'], 'imports/reviewers');
                $path = storage_path($upload['relative_path']);

                $roleId = $this->reviewerRoleId();
                if ($roleId <= 0) {
                    flash('danger', 'Reviewer role not found.');
                    redirect('admin/users/reviewers-bulk');
                }

                $created = 0;
                $updated = 0;

                if (($fh = fopen($path, 'r')) !== false) {
                    $header = fgetcsv($fh);
                    while (($row = fgetcsv($fh)) !== false) {
                        $data = array_combine($header, $row);
                        if (!$data || empty($data['email'])) {
                            continue;
                        }

                        $email = trim((string) $data['email']);
                        $firstName = trim((string) ($data['first_name'] ?? 'Reviewer'));
                        $lastName = trim((string) ($data['last_name'] ?? 'User'));
                        $mobile = trim((string) ($data['mobile'] ?? ''));
                        $password = trim((string) ($data['password'] ?? 'Review@12345'));
                        $preferredLang = trim((string) ($data['preferred_lang'] ?? 'en'));

                        $existing = $this->userModel()->findByEmail($email);

                        if ($existing) {
                            $this->userModel()->update((int) $existing['id'], [
                                'role_id' => $roleId,
                                'first_name' => $firstName,
                                'last_name' => $lastName,
                                'email' => $email,
                                'mobile' => $mobile,
                                'preferred_lang' => in_array($preferredLang, ['ar','en'], true) ? $preferredLang : 'en',
                                'is_active' => 1,
                            ]);
                            $updated++;
                        } else {
                            $this->userModel()->create([
                                'role_id' => $roleId,
                                'first_name' => $firstName,
                                'last_name' => $lastName,
                                'email' => $email,
                                'password_hash' => password_hash($password, PASSWORD_DEFAULT),
                                'mobile' => $mobile,
                                'preferred_lang' => in_array($preferredLang, ['ar','en'], true) ? $preferredLang : 'en',
                                'is_active' => 1,
                                'job_title' => null,
                            ]);
                            $created++;
                        }
                    }
                    fclose($fh);
                }

                audit_log('bulk_import_reviewers', 'users', null, ['created' => $created, 'updated' => $updated]);
                flash('success', trans('reviewers_imported_success') . ' Created: ' . $created . ' Updated: ' . $updated);
                redirect('admin/users');
            } catch (\Throwable $e) {
                flash('danger', $e->getMessage());
                redirect('admin/users/reviewers-bulk');
            }
        }

        $this->view('admin/users/reviewers_bulk');
    }

    private function reviewerRoleId(): int
    {
        try {
            $db = \App\Core\Database::getInstance();
            $stmt = $db->query("SELECT id FROM roles WHERE code = 'reviewer' LIMIT 1");
            $id = $stmt->fetchColumn();
            return $id ? (int) $id : 0;
        } catch (\Throwable $e) {
            return 0;
        }
    }

    private function userModel(): \App\Models\User
    {
        return new \App\Models\User();
    }


}
