<?php

declare(strict_types=1);

require_once __DIR__ . '/config.php';
require_once __DIR__ . '/config_ui.php';
require_once __DIR__ . '/lib/ReferralCreditService.php';

Security::headers(false);


const AFENIXX_TRIAL_COOKIE = 'afenixx_trial_guard';

function af_trial_email_identifier(string $email): string
{
    $email = mb_strtolower(trim($email), 'UTF-8');
    if (!str_contains($email, '@')) {
        return $email;
    }
    [$local, $domain] = array_pad(explode('@', $email, 2), 2, '');
    $local = preg_replace('/\+.*/', '', $local) ?? $local;
    if (in_array($domain, ['gmail.com', 'googlemail.com'], true)) {
        $domain = 'gmail.com';
        $local = str_replace('.', '', $local);
    }
    return $local . '@' . $domain;
}

function af_trial_phone_hash(string $phone): string
{
    $digits = preg_replace('/\D+/', '', $phone) ?? '';
    return strlen($digits) >= 7 ? hash('sha256', $digits) : '';
}

function af_trial_token_bundle(string $cookieValue, string $phone): string
{
    $cookieHash = hash('sha256', $cookieValue);
    $deviceHash = hash('sha256', $cookieValue . '|' . Security::fingerprint() . '|' . (string) ($_SERVER['HTTP_ACCEPT_LANGUAGE'] ?? ''));
    $parts = ['c=' . $cookieHash, 'd=' . $deviceHash];
    $phoneHash = af_trial_phone_hash($phone);
    if ($phoneHash !== '') {
        $parts[] = 'p=' . $phoneHash;
    }
    return implode(';', $parts);
}

$trialCookieValue = (string) ($_COOKIE[AFENIXX_TRIAL_COOKIE] ?? '');
if (!preg_match('/^[a-f0-9]{64}$/', $trialCookieValue)) {
    $trialCookieValue = bin2hex(random_bytes(32));
    setcookie(AFENIXX_TRIAL_COOKIE, $trialCookieValue, [
        'expires' => time() + 400 * 86400,
        'path' => '/',
        'secure' => Security::isHttps(),
        'httponly' => true,
        'samesite' => 'Lax',
    ]);
}

if (!empty($_SESSION['admin']['uid'])) {
    header('Location: admin/index.php');
    exit;
}

$errorMessage = '';
$success = false;
$name = trim((string) ($_POST['nombre'] ?? ''));
$email = trim((string) ($_POST['correo'] ?? ''));
$phone = trim((string) ($_POST['telefono'] ?? ''));
$referralCode = strtoupper(trim((string) ($_GET['ref'] ?? $_POST['ref'] ?? '')));
$referrerId = null;
$referrerName = '';
$freePlan = null;

try {
    $planStmt = $pdo->query("SELECT * FROM planes WHERE nombre_plan = 'Gratis' AND activo = 1 AND es_interno = 0 ORDER BY id ASC LIMIT 1");
    $freePlan = $planStmt ? $planStmt->fetch(PDO::FETCH_ASSOC) : null;
} catch (Throwable $e) {
    error_log('No se pudo cargar el plan gratuito: ' . $e->getMessage());
}

if ($referralCode !== '') {
    try {
        $refStmt = $pdo->prepare('SELECT id, nombre_usuario FROM usuarios WHERE codigo_referido = ? LIMIT 1');
        $refStmt->execute([$referralCode]);
        $referrer = $refStmt->fetch(PDO::FETCH_ASSOC);
        if ($referrer) {
            $referrerId = (int) $referrer['id'];
            $referrerName = (string) $referrer['nombre_usuario'];
        }
    } catch (Throwable $e) {
        error_log('No se pudo validar el referido: ' . $e->getMessage());
    }
}

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    if (!Security::validateCsrf()) {
        $errorMessage = 'La sesión de seguridad venció. Recarga la página e inténtalo nuevamente.';
    } else {
        $password = (string) ($_POST['password'] ?? '');
        $confirmation = (string) ($_POST['confirm_password'] ?? '');
        $acceptedTerms = isset($_POST['accept_terms']);
        $validatedEmail = filter_var($email, FILTER_VALIDATE_EMAIL) ? strtolower($email) : '';
        $trialEmailIdentifier = $validatedEmail !== '' ? af_trial_email_identifier($validatedEmail) : '';
        $trialTokenBundle = af_trial_token_bundle($trialCookieValue, $phone);

        if ($name === '' || $validatedEmail === '' || $password === '' || $confirmation === '') {
            $errorMessage = 'Completa todos los campos obligatorios.';
        } elseif (!$acceptedTerms) {
            $errorMessage = 'Debes aceptar los términos y la política de privacidad para crear la cuenta.';
        } elseif ($password !== $confirmation) {
            $errorMessage = 'Las contraseñas no coinciden.';
        } elseif (strlen($password) < 10) {
            $errorMessage = 'La contraseña debe tener al menos 10 caracteres.';
        } elseif (!preg_match('/[A-Za-z]/', $password) || !preg_match('/\d/', $password)) {
            $errorMessage = 'La contraseña debe incluir letras y números.';
        } elseif ($phone !== '' && !preg_match('/^[0-9+()\-\s]{7,40}$/', $phone)) {
            $errorMessage = 'Ingresa un teléfono válido o deja el campo vacío.';
        } else {
            try {
                $rate = Security::rateLimit('register:' . Security::clientIp(), 4, 3600);
                if (!$rate['allowed']) {
                    throw new RuntimeException('Se alcanzó el límite de registros desde esta conexión. Inténtalo más tarde.');
                }
                if (!$freePlan) {
                    throw new RuntimeException("No se encontró el plan de prueba configurado.");
                }

                $pdo->beginTransaction();

                $exists = $pdo->prepare('SELECT id FROM usuarios WHERE correo = ? LIMIT 1');
                $exists->execute([$validatedEmail]);
                if ($exists->fetchColumn()) {
                    throw new RuntimeException('Este correo ya está registrado. Inicia sesión con tu cuenta.');
                }

                $trialConditions = ['LOWER(TRIM(identificador_correo)) = ?'];
                $trialParams = [$trialEmailIdentifier];
                $clientIp = Security::clientIp();
                if ($clientIp !== '0.0.0.0') {
                    $trialConditions[] = 'ip_address = ?';
                    $trialParams[] = $clientIp;
                }
                foreach (explode(';', $trialTokenBundle) as $tokenPart) {
                    if ($tokenPart !== '') {
                        $trialConditions[] = 'cookie_token LIKE ?';
                        $trialParams[] = '%' . $tokenPart . '%';
                    }
                }
                $trialRegistryCheck = $pdo->prepare(
                    'SELECT id FROM pruebas_gratuitas WHERE ' . implode(' OR ', $trialConditions) . ' LIMIT 1'
                );
                $trialRegistryCheck->execute($trialParams);
                if ($trialRegistryCheck->fetchColumn()) {
                    throw new RuntimeException('Esta conexión, navegador, teléfono o identificador ya utilizó una prueba gratuita. Si se trata de un caso autorizado, el Superadmin debe liberarlo desde el módulo Liberar pruebas.');
                }

                if ($referrerId !== null) {
                    $refCheck = $pdo->prepare('SELECT id FROM usuarios WHERE id = ? AND correo <> ? LIMIT 1');
                    $refCheck->execute([$referrerId, $validatedEmail]);
                    if (!$refCheck->fetchColumn()) {
                        $referrerId = null;
                        $referralCode = '';
                    }
                } elseif ($referralCode !== '') {
                    throw new RuntimeException('El código de referido no es válido o ya no está disponible.');
                }

                $roleStmt = $pdo->prepare("SELECT id FROM roles WHERE nombre_rol = 'Admin' LIMIT 1");
                $roleStmt->execute();
                $adminRole = (int) $roleStmt->fetchColumn();
                if ($adminRole <= 0) throw new RuntimeException("No se encontró el rol 'Admin'.");

                $insertUser = $pdo->prepare(
                    'INSERT INTO usuarios (nombre_usuario, correo, clave, id_rol, id_plan, ip_registro, id_referidor, telefono)
                     VALUES (?, ?, ?, ?, ?, ?, ?, ?)'
                );
                $insertUser->execute([
                    $name,
                    $validatedEmail,
                    password_hash($password, PASSWORD_DEFAULT),
                    $adminRole,
                    (int) $freePlan['id'],
                    Security::clientIp(),
                    $referrerId,
                    $phone !== '' ? $phone : null,
                ]);
                $newUserId = (int) $pdo->lastInsertId();

                // El monedero se crea en saldo cero cuando la migración comercial está instalada.
                // La comprobación evita que un despliegue parcial impida registrar la cuenta.
                $walletTableStmt = $pdo->prepare(
                    "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = DATABASE() AND table_name = 'monederos'"
                );
                $walletTableStmt->execute();
                if ((int) $walletTableStmt->fetchColumn() > 0) {
                    $pdo->prepare(
                        'INSERT INTO monederos (id_usuario, saldo) VALUES (?, 0) '
                        . 'ON DUPLICATE KEY UPDATE id_usuario = VALUES(id_usuario)'
                    )->execute([$newUserId]);
                }

                $days = max(1, (int) ($freePlan['duracion_prueba_dias'] ?? 7));
                $end = (new DateTimeImmutable('now'))->add(new DateInterval('P' . $days . 'D'));
                $insertSubscription = $pdo->prepare(
                    "INSERT INTO suscripciones (id_admin, id_plan, fecha_inicio, fecha_fin, estado, ciclo_facturacion)
                     VALUES (?, ?, NOW(), ?, 'prueba', 'prueba')"
                );
                $insertSubscription->execute([$newUserId, (int) $freePlan['id'], $end->format('Y-m-d H:i:s')]);

                $trialRegistryInsert = $pdo->prepare(
                    'INSERT INTO pruebas_gratuitas (ip_address, cookie_token, identificador_correo, id_usuario_registrado) VALUES (?, ?, ?, ?)'
                );
                $trialRegistryInsert->execute([
                    Security::clientIp(),
                    $trialTokenBundle,
                    $trialEmailIdentifier,
                    $newUserId,
                ]);

                (new ReferralCreditService($pdo))->createReferralCode($newUserId);

                $pdo->commit();
                $success = true;
                $name = $email = $phone = $referralCode = '';
                $referrerId = null;
                $referrerName = '';
            } catch (Throwable $e) {
                if ($pdo->inTransaction()) $pdo->rollBack();
                $errorMessage = $e instanceof RuntimeException ? $e->getMessage() : 'No fue posible crear la cuenta. Inténtalo nuevamente.';
                error_log('Error en registro.php: ' . $e->getMessage());
            }
        }
    }
}

$trialDays = max(1, (int) ($freePlan['duracion_prueba_dias'] ?? 7));
$trialPlanName = (string) ($freePlan['nombre_plan'] ?? 'Inicial');
$authPageTitle = $ui_register_page_title ?? 'Crear cuenta';
$authEyebrow = $ui_register_eyebrow ?? 'EMPIEZA TU OPERACIÓN';
$authTitle = $ui_register_hero_title ?? 'Centraliza tus códigos de acceso y entrégalos de forma automática desde el primer día.';
$authDescription = $ui_register_hero_description ?? 'Configura buzones, dominios y asuntos para entregar códigos con rapidez.';
$authFormTitle = $ui_register_form_title ?? 'Crear mi cuenta';
$authFormDescription = $ui_register_form_description ?? 'Completa tus datos. Los campos de teléfono y referido son opcionales.';
$authFormIcon = 'fas fa-user-plus';
$authBenefits = [
    ['icon' => 'fas fa-user-plus', 'title' => (string) ($ui_register_benefit_1_title ?? 'Registro rápido'), 'text' => (string) ($ui_register_benefit_1_text ?? 'Crea tu cuenta en pocos pasos y entra al panel para comenzar la configuración.')],
    ['icon' => 'fas fa-flask', 'title' => (string) ($ui_register_benefit_2_title ?? 'Prueba gratuita incluida'), 'text' => (string) ($ui_register_benefit_2_text ?? 'Conoce las herramientas disponibles durante el periodo de evaluación configurado para tu cuenta.')],
    ['icon' => 'fas fa-layer-group', 'title' => (string) ($ui_register_benefit_3_title ?? 'Todo listo para organizarte'), 'text' => (string) ($ui_register_benefit_3_text ?? 'Administra clientes, cuentas, buzones y consultas desde una sola plataforma.')],
];
require __DIR__ . '/partials/auth_header.php';
?>

<?php if ($errorMessage !== ''): ?>
    <div class="auth-alert auth-alert--error" role="alert"><i class="fas fa-circle-exclamation"></i><span><?= auth_e($errorMessage) ?></span></div>
<?php elseif ($success): ?>
    <div class="auth-alert auth-alert--success" role="status"><i class="fas fa-circle-check"></i><span><strong>Cuenta creada correctamente.</strong> Ya puedes iniciar sesión y configurar tu operación.</span></div>
<?php endif; ?>

<?php if (!$success): ?>
<form method="post" action="registro.php<?= isset($_GET['ref']) ? '?ref=' . urlencode((string) $_GET['ref']) : '' ?>" class="auth-form" data-auth-form novalidate>
    <?= Security::csrfField() ?>

    <div class="auth-trial-box"><i class="fas fa-wand-magic-sparkles"></i><span><strong>Plan de prueba: <?= auth_e($trialPlanName) ?></strong>Tendrás <?= auth_e($trialDays) ?> días para probar las funciones y límites configurados para este plan.</span></div>
    <div class="auth-guide-box"><i class="fas fa-shield-halved"></i><span><strong>Una prueba gratuita por persona y entorno</strong>Para prevenir el uso repetido, se validan el correo normalizado, la conexión, el navegador y el teléfono cuando se registra.</span></div>

    <?php if ($referrerId !== null): ?>
        <div class="auth-guide-box"><i class="fas fa-gift"></i><span><strong>Invitación de <?= auth_e($referrerName ?: 'un usuario') ?></strong>El beneficio del referente se aplicará únicamente después de confirmar tu primer pago mensual.</span></div>
    <?php endif; ?>

    <div class="auth-grid">
        <div class="auth-field">
            <label for="register-name"><i class="fas fa-user"></i><?= auth_e($ui_register_name_label ?? 'Nombre completo') ?></label>
            <div class="auth-input-wrap"><i class="fas fa-user auth-input-icon"></i><input id="register-name" name="nombre" type="text" autocomplete="name" maxlength="160" placeholder="<?= auth_e($ui_register_name_placeholder ?? 'Nombres y apellidos') ?>" data-clear-placeholder required value="<?= auth_e($name) ?>"></div>
            <small>Escribe el nombre que aparecerá en tu cuenta.</small>
            <div class="field-error" data-error-for="nombre" role="alert"></div>
        </div>
        <div class="auth-field">
            <label for="register-email"><i class="fas fa-envelope"></i><?= auth_e($ui_register_email_label ?? 'Correo electrónico') ?></label>
            <div class="auth-input-wrap"><i class="fas fa-envelope auth-input-icon"></i><input id="register-email" name="correo" type="email" autocomplete="email" maxlength="190" placeholder="<?= auth_e($ui_register_email_placeholder ?? 'correo@dominio.com') ?>" data-clear-placeholder required value="<?= auth_e($email) ?>"></div>
            <small>Se utilizará para iniciar sesión y recuperar el acceso.</small>
            <div class="field-error" data-error-for="correo" role="alert"></div>
        </div>
    </div>

    <div class="auth-field">
        <label for="register-phone"><i class="fas fa-phone"></i><?= auth_e($ui_register_phone_label ?? 'Teléfono') ?> <span class="auth-optional">Opcional</span></label>
            <div class="auth-input-wrap"><i class="fas fa-phone auth-input-icon"></i><input id="register-phone" name="telefono" type="tel" autocomplete="tel" maxlength="40" placeholder="+51 999 999 999" data-clear-placeholder value="<?= auth_e($phone) ?>"></div>
            <small>Permite recibir avisos operativos y contactar por WhatsApp.</small>
            <div class="field-error" data-error-for="telefono" role="alert"></div>
    </div>

    <div class="auth-field">
        <label for="register-password"><i class="fas fa-lock"></i><?= auth_e($ui_register_password_label ?? 'Contraseña') ?></label>
        <div class="auth-input-wrap">
            <i class="fas fa-lock auth-input-icon"></i>
            <input id="register-password" name="password" type="password" autocomplete="new-password" minlength="10" placeholder="Mínimo 10 caracteres" data-clear-placeholder data-password-strength required>
            <button type="button" class="auth-password-toggle" data-password-toggle="register-password" aria-label="Mostrar contraseña"><i class="fas fa-eye"></i></button>
        </div>
        <div class="password-strength"><span data-password-strength-bar></span></div>
        <small data-password-strength-text>Utiliza mayúsculas, minúsculas, números y, de preferencia, un símbolo.</small>
        <div class="field-error" data-error-for="password" role="alert"></div>
    </div>

    <div class="auth-field">
        <label for="register-password-confirmation"><i class="fas fa-shield-halved"></i><?= auth_e($ui_register_confirm_label ?? 'Confirmar contraseña') ?></label>
        <div class="auth-input-wrap">
            <i class="fas fa-shield-halved auth-input-icon"></i>
            <input id="register-password-confirmation" name="confirm_password" type="password" autocomplete="new-password" minlength="10" placeholder="Repite tu contraseña" data-clear-placeholder required>
            <button type="button" class="auth-password-toggle" data-password-toggle="register-password-confirmation" aria-label="Mostrar contraseña"><i class="fas fa-eye"></i></button>
        </div>
        <div class="field-error" data-error-for="confirm_password" role="alert"></div>
    </div>

    <div class="auth-field">
        <label for="referral-code"><i class="fas fa-user-group"></i><?= auth_e($ui_register_referral_label ?? 'Código de referido') ?> <span class="auth-optional">Opcional</span></label>
        <div class="auth-input-wrap"><i class="fas fa-user-group auth-input-icon"></i><input id="referral-code" name="ref" type="text" maxlength="50" placeholder="FENIX-1234" data-clear-placeholder value="<?= auth_e($referralCode) ?>"></div>
        <div class="field-error" data-error-for="ref" role="alert"></div>
    </div>

    <label class="auth-check auth-check--terms"><input type="checkbox" name="accept_terms" value="1" required><span><?= auth_e($ui_register_terms_text ?? 'Acepto los términos de uso y la política de privacidad del servicio.') ?></span></label>

    <button type="submit" class="auth-submit" data-loading-text="Creando cuenta…"><i class="fas fa-user-plus"></i><span><?= auth_e($ui_register_button_text ?? 'Crear mi cuenta') ?></span></button>
    <div class="auth-secondary-link"><?= auth_e($ui_register_existing_text ?? '¿Ya tienes una cuenta?') ?> <a href="login.php"><?= auth_e($ui_register_login_text ?? 'Iniciar sesión') ?></a></div>
</form>
<?php else: ?>
    <div class="auth-form" style="margin-top:24px">
        <a class="auth-submit" href="login.php"><i class="fas fa-right-to-bracket"></i><span>Ir a iniciar sesión</span></a>
        <div class="auth-security-note"><i class="fas fa-shield-halved"></i><span><strong>Siguiente paso</strong>Ingresa al panel y configura tus buzones, dominios y clientes.</span></div>
    </div>
<?php endif; ?>

<?php require __DIR__ . '/partials/auth_footer.php'; ?>
