<?php

use App\Src\Encryption;
use Mtc\Core\Admin\TotpService;
use Mtc\Core\Permissions;
use Mtc\Core\RateLimit;

$path = '../../../';
require $path . 'core/includes/header.inc.php';

init_request_values([
    'page' => null,
    'credentials' => null,
]);

//initialize variables
if (!isset($_REQUEST['id'])) {
    $_REQUEST['id'] = null;
}
if (!isset($_REQUEST['action'])) {
    $_REQUEST['action'] = null;
}
$errors = [];

//only mtcadmin can edit mtcadmin
if ($_REQUEST['id'] == MTCADMIN_USERID && $adminuser->user['id'] != MTCADMIN_USERID) {
    header("Location: /admin/index.php?access=none");
    exit();
}

$can_manage_user_roles = AdminUser::can(10, $adminuser->user['id']);
if ($_REQUEST['id'] != $adminuser->user['id'] && !$can_manage_user_roles) {
    header("Location: /admin/index.php?access=none");
    exit();
}

if ($_REQUEST['id'] > 0) {
    $add_or_edit = 'Update';
    $edit_id = $_REQUEST['id'];
} else {
    $add_or_edit = 'Add';
    $edit_id = 0;
}

// Sudo mode: require 2FA re-verification when editing OTHER users
$sudo_required = false;
$sudo_verified = false;
$editing_other_user = $edit_id > 0 && (int) $edit_id !== (int) $adminuser->user['id'];

if ($editing_other_user && !TotpService::isExempt($adminuser->user['username'] ?? '')) {
    $currentAdminModel = \Mtc\Core\AdminUser::query()->find($adminuser->user['id']);
    if ($currentAdminModel && !empty($currentAdminModel->totp_secret)) {
        $sudo_required = true;
        $sudo_timeout = 300; // 5 minutes

        // Check if sudo is still valid
        if (!empty($_SESSION['admin_2fa_sudo_at']) && (time() - $_SESSION['admin_2fa_sudo_at']) < $sudo_timeout) {
            $sudo_verified = true;
        }

        // Handle sudo verification POST
        $sudoRateLimitKey = '2fa_sudo_' . $adminuser->user['id'];
        $sudoMaxAttempts = 5;
        $sudoLockoutSeconds = 120;

        if (!$sudo_verified && $_REQUEST['action'] === 'sudo_verify' && $_SERVER['REQUEST_METHOD'] === 'POST') {
            if (RateLimit::isLocked($sudoRateLimitKey, $sudoLockoutSeconds, $sudoMaxAttempts)) {
                $errors[] = 'Too many failed attempts. Please wait 2 minutes before trying again.';
            } elseif (!CSRF::checkToken('admin_sudo_2fa')) {
                $errors[] = 'Verification failed, please try again.';
            } else {
                $code = preg_replace('/\s+/', '', $_POST['totp_code'] ?? '');
                $service = new TotpService();
                $timestamp = !empty($code)
                    ? $service->verifyCode($currentAdminModel->totp_secret, $code, $currentAdminModel->totp_last_used_at)
                    : false;
                if ($timestamp !== false) {
                    // Save the timestamp to reject replay of this code
                    $currentAdminModel->forceFill(['totp_last_used_at' => $timestamp])->save();
                    $_SESSION['admin_2fa_sudo_at'] = time();
                    $sudo_verified = true;
                    // Redirect to remove the action from the URL
                    header('Location: ' . \Util::add_query_arg(['id' => $edit_id]));
                    exit();
                } else {
                    RateLimit::logAttempt($sudoRateLimitKey);
                    $errors[] = 'Invalid 2FA code. Please try again.';
                }
            }
        }
    }
}

$pagename = 'Admin User';
$table = 'admin_users';
$page_meta['title'] = $add_or_edit . ' ' . $pagename;

$display_form = !$sudo_required || $sudo_verified;

// initialise temp user to use for adding/updating/getting details
$tmp_user = new AdminUser();

$user = [
    'name' => '',
    'username' => '',
    'email' => '',
];

$admin_eloquent = null;
$can_manage_category_restrictions = false;

if ($edit_id > 0) {
    $user = $tmp_user->get_user($edit_id);
    /** @var \Mtc\Core\Admin\User $admin_eloquent */
    $admin_eloquent = \Mtc\Core\Admin\User::find($user['id']);
    $can_manage_category_restrictions = Permissions::can(Permissions::RESTRICTED_ORDER_CATEGORIES, $tmp_user->user['id']) && $user['id'] !== $adminuser->user['id'];
}


/*
 * Reset 2FA
 */
if ($_REQUEST['action'] === 'reset_2fa' && $edit_id > 0 && $_SERVER['REQUEST_METHOD'] === 'POST') {
    if (!CSRF::checkToken('reset_2fa_' . $edit_id)) {
        $errors[] = 'Request failed, please try again.';
    } else {
        $isSelf = $edit_id === (int) $adminuser->user['id'];
        $canResetOthers = $adminuser->isMtcAdmin() || Permissions::can(Permissions::RESET_2FA);

        if ($isSelf || $canResetOthers) {
            \Mtc\Core\AdminUser::query()
                ->where('id', $edit_id)
                ->update(['totp_secret' => null]);

            // Audit log: record who reset whose 2FA
            RateLimit::log('2fa_reset_by_' . $adminuser->user['id'] . '_for_' . $edit_id, 'Admin 2FA reset', 999, 1, false);

            // If resetting own 2FA, clear sudo session so they re-auth fresh
            if ($isSelf) {
                unset($_SESSION['admin_2fa_sudo_at']);
            }

            // Redirect to refresh the page state
            header('Location: ' . \Util::add_query_arg(['id' => $edit_id, '2fa_reset' => 1]));
            exit();
        }
    }
}

/*
 * Add
 */
if ($_REQUEST['action'] == 'update') {
    // do add/edit
    // set data
    $user['name'] = !empty($edit_id) ?
        $_REQUEST['name'] :
        $_REQUEST['firstname'] . ' ' . $_REQUEST['lastname'];
    $user['username'] = $_REQUEST['username'];
    $user['email'] = $_REQUEST['email'];
    $user['credentials'] = $_REQUEST['credentials'];

    // if editor can change the role of this user
    if ($can_manage_user_roles) {
        $user['role'] = $_REQUEST['role'];
    }

    if (!empty($_FILES['userfile']['size'])) {
        $file_data = upload_image('userfile', $image_folders['signature']);
        if (!empty($file_data['name']) && empty($file_data['error'])) {
            $user['signature'] = $file_data['name'];
        }
    } elseif (!empty($_POST['delete_image'])) {
        $user['signature'] = '';
    }

    // error reporting
    $usernameExists = \Mtc\Core\AdminUser::query()
        ->where('username_hash', Encryption::makeHash($user['username']))
        ->where('id', '<>', $_REQUEST['id'])
        ->exists();
    if ($usernameExists) {
        $errors[] = "This username is already in use. Please choose another.";
    }

    $emailExists = \Mtc\Core\AdminUser::query()
        ->where('email_hash', Encryption::makeHash($user['email']))
        ->where('id', '<>', $_REQUEST['id'])
        ->exists();
    if ($emailExists) {
        $errors[] = "This email address is already in use.";
    }


    // check if password is suposed to get updated or not
    if (($_REQUEST['id'] == '' && $_REQUEST['password'] == '')) {
        $errors[] = "You must enter a password";
    } elseif ($_REQUEST['password'] != $_REQUEST['password2']) {
        $errors[] = "Your passwords did not match";
    } elseif ($_REQUEST['password'] != '' && strlen($_REQUEST['password']) < 6) {
        $errors[] = "Your password must be at least 6 characters.";
    }
    if ($_REQUEST['password'] != '') {
        $user['password'] = $tmp_user->encrypt_pass($_REQUEST['password'], $user['username']);
    }

    // if no errors do the update / insert
    if (empty($errors)) {
        if ($_REQUEST['id'] != '') {
            // update
            $tmp_user->update($user);
            $success = "The user " . clean_page($user['username']) . " has been updated.";
        } else {
            // insert
            $user['id'] = $tmp_user->create($user);
            $add_or_edit = 'Update';
            $_REQUEST['id'] = $user['id'];
            $success = "The user " . clean_page($user['username']) . " has been added.";
        }

        if ($can_manage_category_restrictions) {
            if (empty($admin_eloquent)) {
                $admin_eloquent = \Mtc\Core\Admin\User::find($user['id']);
            }
            $admin_eloquent->setRestrictedCategories($_POST['restricted_categories'] ?? []);
        }

        if (isset($_REQUEST['policies'])) {
            $admin_eloquent->confirmedPolicies()->sync($_REQUEST['policies']);
        }

        $updated = true;
    }
}

if (! isset($user_permissions)) {
    $user_permissions = [];
}

$policies = \Mtc\Modules\DoctorPolicy\Classes\DoctorPolicy::all();
$user_policies = [];
if ($admin_eloquent) {
    $user_policies = optional($admin_eloquent->confirmedPolicies)->keyBy('id') ?? [];
}

require_once $path . 'core/admin/templates/adminheader.html.php';

?>
    <ul class="breadcrumbs el">
        <li><a href="/admin/">Home</a> /</li>
        <li class="end"><?= $add_or_edit ?> <?= $pagename ?></li>
    </ul>

    <h1><?= $add_or_edit ?> <?= $pagename ?></h1>

<?php

include __DIR__ . '/tabnav.php';

if (!empty($updated) && empty($errors) && isset($_REQUEST['action'])) {
    echo showmsg($pagename . " updated", "success", $path);
}

if (!empty($_REQUEST['2fa_reset'])) {
    echo showmsg("2FA has been reset for this user. They will be required to set it up again on next login.", "success", $path);
}

if (!empty($errors)) {
    showerrors($errors);
}

if ($sudo_required && !$sudo_verified) {
    // Show 2FA re-verification form
    ?>
    <div class="tfa-container tfa-sudo-container">
        <div class="tfa-card">
            <div class="tfa-icon">
                <i class="fa fa-lock"></i>
            </div>
            <h1>Confirm Your Identity</h1>
            <p>Enter your 2FA code to access user management.</p>

            <form action="<?= \Util::add_query_arg(['id' => $edit_id]) ?>" method="POST" id="tfaForm">
                <div class="tfa-digits" id="tfaDigits">
                    <input type="text" class="tfa-digit" data-index="0" inputmode="numeric" maxlength="1" autocomplete="off" autofocus />
                    <input type="text" class="tfa-digit" data-index="1" inputmode="numeric" maxlength="1" autocomplete="off" />
                    <input type="text" class="tfa-digit" data-index="2" inputmode="numeric" maxlength="1" autocomplete="off" />
                    <div class="tfa-digit-separator"></div>
                    <input type="text" class="tfa-digit" data-index="3" inputmode="numeric" maxlength="1" autocomplete="off" />
                    <input type="text" class="tfa-digit" data-index="4" inputmode="numeric" maxlength="1" autocomplete="off" />
                    <input type="text" class="tfa-digit" data-index="5" inputmode="numeric" maxlength="1" autocomplete="off" />
                </div>
                <input type="hidden" name="totp_code" id="totp_code" value="" />
                <?= CSRF::token('admin_sudo_2fa') ?>
                <input type="hidden" name="action" value="sudo_verify" />
                <input type="hidden" name="id" value="<?= $edit_id ?>" />
            </form>

            <p class="tfa-help"><i class="fa fa-info-circle"></i> Verification is valid for 5 minutes</p>
        </div>
    </div>
    <?php
}

if ($display_form) {
    ?>
    <form action="<?= \Util::add_query_arg(['id' => $edit_id]) ?>" method="POST" enctype="multipart/form-data"
          class="style">

        <fieldset class="show">
            <h1><a class="show el">Information <i class="fa fa-caret-right"></i></a></h1>

            <?php
            if ($can_manage_user_roles) {
                ?>
                <div class="row">
                    <label for="role">
                        Role
                    </label>
                    <select name="role" id="role">
                        <option value="0">Choose Role</option>
                        <?php
                        foreach (\Mtc\Core\Admin\Role::all() as $role) {
                            ?>
                            <option value="<?= (int)$role->id ?>" <?= ($user['role'] ?? null) == $role->id ? 'selected' : '' ?>>
                                <?= clean_page($role->name) ?>
                            </option>
                            <?php
                        }
                        ?>
                    </select>
                </div>
                <?php
            }

            if (!empty($edit_id)) {
            ?>
                <div class="row">
                    <label for="name">Name</label>
                    <input type="text" name="name" id="name" value="<?php echo $user['name']; ?>" class="INPUT1">
                </div>
            <?php
            } else {
            ?>
                <div class="row">
                    <label for="firstname">First Name</label>
                    <input type="text" name="firstname" id="firstname" value="" class="INPUT1">
                </div>
                <div class="row">
                    <label for="lastname">Last Name</label>
                    <input type="text" name="lastname" id="lastname" value="" class="INPUT1">
                </div>
            <?php
            }
            ?>

            <div class="row">
                <label for="username">Username</label>
                <input type="text" name="username" id="username" value="<?php echo $user['username']; ?>"
                       class="INPUT1" <?= ($add_or_edit == 'Update') ? 'readonly' : '' ?>>
            </div>

            <div class="row">
                <label for="email">Email Address</label>
                <input type="text" name="email" id="email" value="<?php echo $user['email']; ?>" class="INPUT1">
            </div>

            <div class="row">
                <label for="password">Password</label>
                <input type="password" name="password" id="password" value="" class="INPUT1">
            </div>

            <div class="row">
                <label for="password2">Confirm Password</label>
                <input type="password" name="password2" id="password2" value="" class="INPUT1">
            </div>

            <?php
            if (Permissions::can(Permissions::DOCTOR_SIGNATURE)) {
                ?>

                <div class="row">
                    <label for="credentials">Credentials</label>
                    <textarea name="credentials" id="credentials"><?= clean_page($user['credentials']) ?></textarea>
                </div>

                <?php
                if (!empty($user['signature'])) {
                    ?>

                    <div class="row">
                        <label>Signature</label>
                        <img src="/<?= clean_page($image_folders['signature']['thumb']['path']) ?>/<?= clean_page($user['signature']) ?>"
                             alt="Signature"/>
                    </div>

                    <div class="row">
                        <label for="delete_image">
                            Remove Signature
                        </label>
                        <input type="checkbox"
                               id="delete_image"
                               name="delete_image"/>
                    </div>
                    <?php
                }
                ?>
                <div class="row">
                    <label for="image">
                        Upload Signature
                    </label>
                    <input id="image"
                           type="file"
                           name="userfile"/>
                </div>

                <?php
            } else {
                ?>

                <div class="row">
                    <label>Signature</label>
                    <?php

                    if (!empty($user['signature'])) {
                        ?>
                        <img src="/<?= clean_page($image_folders['signature']['thumb']['path']) ?>/<?= clean_page($user['signature']) ?>"
                             alt="Signature"/>

                        <?php
                    } else {
                        echo "Signature not uploaded for user";
                    }
                    ?>
                </div>
                <?php

            }

            // Doctors have limited access to orders by categories
            if ($can_manage_category_restrictions) {
                $selected = [];
                if (!empty($admin_eloquent->allowedCategories)) {
                    $selected = $admin_eloquent->allowedCategories
                        ->pluck('category_id')
                        ->toArray();
                }
                ?>
                <div class="row">
                    <label for="restricted_categories">
                        Allowed Categories
                    </label>
                    <select name="restricted_categories[]" id="restricted_categories" multiple>
                        <?= get_the_categories($selected) ?>
                    </select>
                    <div class="hint el">
                        <i class="fa fa-info-circle"></i>
                        <div class="text">
                            Use Cmd/Ctrl key to select/deselect multiple items
                        </div>
                    </div>
                </div>

                <?php
            }

            if ($policies->isNotEmpty()) {
                $disabled = $admin_eloquent->id != $adminuser->user['id'];
                ?>
                <h4>Policies</h4>
                <p>You must agree to following policies:</p>
                <?php
                foreach ($policies as $policy) {
                    $link = " ( <a href='{$policy->url}' target='_blank'>{$policy->url}</a> )";
                    if (!empty($user_policies[$policy->id])) {
                        $signed_date = $user_policies[$policy->id]->pivot->created_at;
                        $link .= " <em>Signed on {$signed_date}</em>";
                    }
                    echo \Mtc\Core\FormField::renderField([
                        'type' => 'checkbox',
                        'name' => "policies[]",
                        'disabled' => $disabled,
                        'id' => "policy_{$policy->id}",
                        'row_class' => 'checkboxRow',
                        'label' =>  ' ' . $policy->name . $link,
                        'value' => !empty($user_policies[$policy->id]) ? $policy->id : 0,
                        'field_value' => $policy->id
                    ], $twig);
                }
            }
            ?>
        </fieldset>

        <?php
        if ($admin_eloquent && Permissions::can(Permissions::REVIEW_DOCTOR_ORDERS)) { ?>
            <fieldset>
                <h1><a class="show el">Prescription history <i class="fa fa-caret-right"></i></a></h1>

                <table class="manage-items">
                    <thead>
                        <tr>
                            <th>Order</th>
                            <th>Item</th>
                            <th>Approved at</th>
                        </tr>
                    </thead>
                    <?php
                    $pageNum = $_REQUEST['page'] ?: 1;
                    $rowsPerPage = 100;
                    $totalnumrows = ApprovalLog::whereUserId($admin_eloquent->id)->count();
                    $append = '&id=' . $_REQUEST['id'];
                    $items = ApprovalLog::whereUserId($admin_eloquent->id)
                        ->orderBy('id', 'desc')
                        ->take($rowsPerPage)
                        ->offset($rowsPerPage * ($pageNum - 1))
                        ->get();
                    foreach ($items as $item) {
                        $order = Mtc\Shop\Order::query()->whereHas('items', function ($query) use ($item) {
                            $query->where('id', '=', $item->order_item_id);
                        })->first();
                        if ($order && $order->items) {
                            $item_data = $order->items->reject(function ($value, $key) use ($item) {
                                return $value->id !== $item->order_item_id;
                            })->first();

                            $item_object = new Item($item_data->item_id);
                            ?>
                            <tr>
                                <td>
                                    <a href="/shop/admin/orders/manage.order.php?id=<?php echo $order->id; ?>">#<?php echo $order->id; ?></a>
                                </td>
                                <td>
                                    <a href="/shop/admin/products/item.php?id=<?php echo $item_object->id; ?>"><?php echo $item_object->name; ?></a>
                                </td>
                                <td><?php echo $item->created_at; ?></td>
                            </tr>
                            <?php

                        }
                    }
                    ?>
                </table>
                <?php

                require $path . 'core/admin/templates/pagination.php';
                ?>
            </fieldset>
        <?php } ?>

        <input type="hidden" name="action" value="update"/>
        <input type="hidden" name="id" value="<?php echo $_REQUEST['id']; ?>"/>

        <div class="row"><input type="submit" value="Save"/></div>

    </form>

    <?php
    // 2FA Management Section — visible when editing self, or others with RESET_2FA permission
    $isSelf2fa = $edit_id > 0 && (int) $edit_id === (int) $adminuser->user['id'];
    $canManage2fa = $edit_id > 0
        && ($isSelf2fa || $adminuser->isMtcAdmin() || Permissions::can(Permissions::RESET_2FA));

    if ($canManage2fa) {
        $tfaUser = \Mtc\Core\AdminUser::query()->find($edit_id);
        $has2fa = $tfaUser && !empty($tfaUser->totp_secret);
        $confirmMsg = $isSelf2fa
            ? 'This will reset your 2FA. You will need to set up a new authenticator on your next login. Do you want to proceed?'
            : 'This will clear 2FA for this user. They will need to set up a new authenticator on their next login. Do you want to proceed?';
        ?>
        <fieldset class="show">
            <h1><a class="show el">Two-Factor Authentication <i class="fa fa-caret-right"></i></a></h1>
            <div class="tfa-reset-section">
                <div class="tfa-status">
                    <?php if ($has2fa) { ?>
                        <i class="fa fa-check-circle"></i>
                        <span>2FA is <strong>configured</strong><?= $isSelf2fa ? '' : ' for this user' ?>.</span>
                    <?php } else { ?>
                        <i class="fa fa-times-circle"></i>
                        <span>2FA is <strong>not configured</strong>. <?= $isSelf2fa ? 'You will be prompted to set it up on next login.' : 'User will be prompted to set it up on next login.' ?></span>
                    <?php } ?>
                </div>
                <?php if ($has2fa) { ?>
                    <form action="<?= \Util::add_query_arg(['id' => $edit_id]) ?>" method="POST" class="style" id="reset2faForm">
                        <?= CSRF::token('reset_2fa_' . $edit_id) ?>
                        <input type="hidden" name="action" value="reset_2fa" />
                        <input type="hidden" name="id" value="<?= $edit_id ?>" />
                        <a href="#" class="btn" id="reset2faBtn"
                           onclick="if(confirm('<?= $confirmMsg ?>')){document.getElementById('reset2faForm').submit();}return false;">
                            <i class="fa fa-refresh"></i> Reset 2FA
                        </a>
                    </form>
                <?php } ?>
            </div>
        </fieldset>
        <?php
    }
}



require_once $path . 'core/admin/templates/adminfooter.html.php';
