<?php
declare(strict_types=1);

if (!defined('ABSPATH')) { exit; }

/**
 * Login form element renderer (shared).
 *
 * Phase 1, step 13.
 *
 * Pre-extraction, the editor and frontend versions had drifted into
 * two visually different forms:
 *
 *   - **Editor** rendered the polished version: auto-contrast against
 *     parent_bg, Google sign-in button (when SocialLoginService is
 *     enabled), autofill/focus/checkbox inline CSS, divider between
 *     Google button and email form, `wp_lostpassword_url()` for the
 *     forgot-password link.
 *
 *   - **Frontend** rendered the older version: simpler form with no
 *     Google option, no autofill CSS, `#` href on the forgot-password
 *     link, no auto-contrast.
 *
 * Sergei's principle is "frontend should render exactly the same as
 * the editor", so this unification adopts the editor's polished
 * version as canonical and the frontend gains every improvement. The
 * frontend additionally keeps its security extras: a WordPress nonce
 * field and the Security::honeypotField() anti-bot trap (these
 * remain frontend-only because the editor preview is admin-gated
 * and doesn't post the form).
 *
 * Pre-extraction defaults that drifted (resolved to editor canonical):
 *   - field_radius default: 6 (frontend) / 4 (editor) → 4
 *   - button_bg default: #1d2327 (frontend) / #1c2226 (editor) → #1c2226
 *   - field_gap, sectionMaxWidth, etc. — already aligned.
 *
 * @param array|object $el       Element node.
 * @param array        $settings Element settings.
 * @param string       $context  'frontend' or 'editor'.
 *
 * @return string Inner HTML.
 *
 * @sideeffect Primes $GLOBALS['impulse_needs_forms'] on frontend so
 *             the forms JS asset enqueues. Emits inline CSS via
 *             wp_add_inline_style for placeholders/focus/autofill/
 *             checkbox styling (was editor-only pre-extraction; now
 *             shared so frontend autofill state stops looking out of
 *             place under custom field backgrounds).
 */
function impulse_element_render_login($el, array $settings, string $context): string {
    if (is_object($el)) $el = (array) $el;
    $isEditor = ($context === 'editor');
    $device   = $isEditor ? ($GLOBALS['impulse_preview_device'] ?? 'desktop') : 'desktop';
    $elId     = preg_replace('/[^A-Za-z0-9_-]/', '', (string) ($el['id'] ?? '0'));

    $read = function (string $key, $default) use ($settings, $isEditor, $device) {
        if ($isEditor && function_exists('impulse_device_val')) {
            return impulse_device_val($settings, $key, $device, $default);
        }
        return $settings[$key] ?? $default;
    };

    $fieldGap         = intval($read('field_gap',    16));
    $fieldRadius      = intval($read('field_radius',  4));
    $sectionMaxWidth  = intval($settings['section_max_width']   ?? 400);
    $fieldBg          = (string) ($settings['field_bg']           ?? '#f5f5f5');
    $fieldBorderColor = (string) ($settings['field_border_color'] ?? '#e0e0e0');
    $fieldBorderWidth = intval($settings['field_border_width']    ?? 1);
    $buttonBg         = (string) ($settings['button_bg']          ?? '#1c2226');
    $buttonColor      = (string) ($settings['button_color']       ?? '#ffffff');
    $buttonText       = (string) ($settings['button_text']        ?? 'Log In');
    $showRemember     = ($settings['show_remember']     ?? true) !== false;
    $showLostPassword = ($settings['show_lost_password'] ?? true) !== false;
    $showGoogleBtn    = ($settings['show_google']       ?? true) !== false;
    $redirectUrl      = (string) ($settings['redirect_url']       ?? '');

    if (!$isEditor) $GLOBALS['impulse_needs_forms'] = true;

    // ── Auto-contrast based on parent bg ─────────────────────────
    $parentBg = (string) ($GLOBALS['impulse_parent_bg'] ?? ($GLOBALS['impulse_current_section_bg'] ?? ($GLOBALS['impulse_page_bg_color'] ?? '#ffffff')));
    $autoText = function_exists('impulse_contrast_color') ? impulse_contrast_color($parentBg) : '#1d2327';
    $isLight  = ($autoText === '#111827' || $autoText === '#1d2327');
    $autoMid     = $isLight ? '#666'    : 'rgba(255,255,255,0.5)';
    $autoDivider = $isLight ? '#e0e0e0' : 'rgba(255,255,255,0.15)';
    $fieldText  = function_exists('impulse_contrast_color') ? impulse_contrast_color($fieldBg) : '#111827';
    $fieldIsLight = ($fieldText === '#111827' || $fieldText === '#1d2327');
    $fieldPlaceholder = $fieldIsLight ? '#86868b' : 'rgba(255,255,255,0.45)';
    $checkBg   = $isLight ? '#1d2327' : '#ffffff';
    $checkMark = $isLight ? '#fff'    : '#1d2327';

    $inputStyle = 'width:100%;padding:12px 16px;background:' . esc_attr($fieldBg) . ';border:' . $fieldBorderWidth . 'px solid ' . esc_attr($fieldBorderColor) . ';border-radius:' . $fieldRadius . 'px;font-size:14px;color:' . esc_attr($fieldText) . ';outline:none;box-sizing:border-box;transition:border-color 0.15s';

    // v2.1.1401: optional Label colour override (placeholder text). Matches
    // the same setting key used by the contact / register / checkout blocks.
    $fieldLabelColor = trim((string) ($settings['field_label_color'] ?? ''));

    // ── Inline CSS: placeholders, focus, autofill, checkboxes ────
    if (function_exists('wp_add_inline_style')) {
        $css  = '.impulse-login-form input::placeholder{color:' . $fieldPlaceholder . ';opacity:1}';
        $css .= '.impulse-login-form input:focus{border-color:#888!important;outline:none!important;box-shadow:none!important}';
        $css .= '.impulse-login-form input:-webkit-autofill,.impulse-login-form input:-webkit-autofill:hover,.impulse-login-form input:-webkit-autofill:focus{-webkit-box-shadow:0 0 0 1000px ' . esc_attr($fieldBg) . ' inset!important;-webkit-text-fill-color:' . esc_attr($fieldText) . '!important}';
        $css .= '.impulse-login-form input[type="checkbox"]{-webkit-appearance:none!important;appearance:none!important;width:16px!important;height:16px!important;border:1px solid ' . $autoDivider . '!important;border-radius:3px!important;background:transparent!important;cursor:pointer;flex-shrink:0;position:relative;padding:0!important;margin:0!important}';
        $css .= '.impulse-login-form input[type="checkbox"]:checked{background:' . $checkBg . '!important;border-color:' . $checkBg . '!important}';
        $css .= '.impulse-login-form input[type="checkbox"]:checked::after{content:"";position:absolute;left:5px;top:2px;width:4px;height:8px;border:solid ' . $checkMark . ';border-width:0 2px 2px 0;transform:rotate(45deg)}';
        if ($fieldLabelColor !== '' && $elId) {
            $_sel = '.impulse-el[data-id="' . intval($elId) . '"]';
            $css .= $_sel . ' .impulse-login-form input::placeholder{color:' . esc_attr($fieldLabelColor) . '!important;opacity:1!important}';
        }
        wp_add_inline_style('instinctor-page-inline', $css);
    }

    // ── Compose HTML ─────────────────────────────────────────────
    $wrapStyle = 'display:flex;justify-content:center;width:100%;margin:0 auto'
               . ($sectionMaxWidth > 0 ? ';max-width:' . $sectionMaxWidth . 'px' : '');

    ob_start();
    echo '<div style="' . esc_attr($wrapStyle) . '">';
    echo '<div class="impulse-login-wrapper" style="width:100%;color:' . esc_attr($autoText) . '">';

    // Google sign-in removed 2026-07-05: it was Platform-mediated (OAuth ran on
    // platform.instinctor.com, then handed back an HMAC token) and could not
    // function on a non-Platform install, while carrying wp_set_auth_cookie —
    // exactly what the WP.org review prohibits. Email/password only now.

    echo '<form class="impulse-login-form" autocomplete="off" style="display:flex;flex-direction:column;gap:' . esc_attr((string) $fieldGap) . 'px" data-redirect="' . esc_attr($redirectUrl) . '">';

    // Frontend security: nonce + honeypot (admin-gated editor doesn't post).
    if (!$isEditor) {
        if (function_exists('wp_nonce_field')) wp_nonce_field('instinctor_frontend', 'nonce', true, true);
        // Security::honeypotField() returns the plugin's own honeypot markup
        // (a hidden wrapper div + two form inputs, all attribute values
        // esc_attr()'d internally). input/div aren't SVG-allowlist tags, so
        // route it through a bespoke form-control allowlist for phpcs.
        if (class_exists('\\Instinctor\\Core\\Security')) echo wp_kses(\Instinctor\Core\Security::honeypotField(), [
            'div'   => ['style' => true, 'aria-hidden' => true],
            'input' => ['type' => true, 'name' => true, 'value' => true, 'tabindex' => true, 'autocomplete' => true],
        ]);
    }

    echo '<input type="text" name="username" placeholder="Email or Username" autocomplete="one-time-code" tabindex="-1" style="' . esc_attr($inputStyle) . '" required>';
    echo '<input type="password" name="password" placeholder="Password" autocomplete="new-password" tabindex="-1" style="' . esc_attr($inputStyle) . '" required>';

    if ($showRemember || $showLostPassword) {
        echo '<div style="display:flex;flex-wrap:wrap;justify-content:space-between;align-items:center;gap:6px;font-size:13px">';
        if ($showRemember) {
            echo '<label style="display:flex;align-items:center;gap:6px;cursor:pointer;white-space:nowrap"><input type="checkbox" name="remember"> Remember me</label>';
        } else {
            echo '<span></span>';
        }
        if ($showLostPassword) {
            $lostUrl = function_exists('wp_lostpassword_url') ? wp_lostpassword_url() : '#';
            echo '<a href="' . esc_url($lostUrl) . '" class="impulse-lost-password-link" style="color:' . esc_attr($autoMid) . ';text-decoration:none;white-space:nowrap">Forgot password?</a>';
        }
        echo '</div>';
    }

    echo '<button type="submit" class="impulse-form-submit" style="background:' . esc_attr($buttonBg) . ';color:' . esc_attr($buttonColor) . ';padding:14px 28px;border:none;border-radius:' . esc_attr((string) $fieldRadius) . 'px;font-size:15px;font-weight:600;cursor:pointer">' . esc_html($buttonText) . '</button>';
    echo '<div class="impulse-form-message" style="display:none;padding:12px;border-radius:6px;font-size:14px;text-align:center"></div>';
    echo '</form>';
    echo '</div></div>';

    return ob_get_clean();
}
