<?php
// ============================================================
//  signup-validate.php — AJAX endpoint
// ============================================================
//
//  Called when the user clicks "Continue to payment" on the
//  signup wizard. Does ALL the heavy work upfront:
//    1. Validates the form fields
//    2. Checks for local duplicate email
//    3. Checks for existing Zoho contact (by email)
//    4. Tries to create the Zoho contact NOW
//       — if Zoho rejects (invalid email, etc.) we abort and
//         the wizard stays on Step 2 with an inline error
//    5. Creates the local member row, linked to the Zoho contact
//    6. Logs the user in
//
//  Returns JSON:
//    {ok: true}                                  → advance to Step 3
//    {ok: false, error: 'invalid_email', ...}    → show inline error on Step 2
//
//  After this returns ok=true, the member exists, is logged in,
//  and the wizard's Step 3 just needs to redirect to PayFast.
// ============================================================

require_once __DIR__ . '/includes/db.php';
require_once __DIR__ . '/includes/csrf.php';
require_once __DIR__ . '/includes/session.php';
require_once __DIR__ . '/includes/config.php';

header('Content-Type: application/json');

function reply(array $data): void {
    echo json_encode($data, JSON_UNESCAPED_SLASHES);
    exit;
}

// Method check
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    http_response_code(405);
    reply(['ok'=>false, 'error'=>'method_not_allowed']);
}

// CSRF
try {
    csrf_verify();
} catch (Throwable $e) {
    http_response_code(400);
    reply(['ok'=>false, 'error'=>'csrf', 'message'=>'Session expired. Refresh the page and try again.']);
}

// Required fields
$required = ['first_name','last_name','email','business','industry','password','password_confirm','tier'];
foreach ($required as $f) {
    if (!isset($_POST[$f]) || trim((string)$_POST[$f]) === '') {
        reply(['ok'=>false, 'error'=>'missing', 'field'=>$f, 'message'=>'Please fill in all required fields.']);
    }
}

$email     = strtolower(trim($_POST['email']));
$password  = (string)$_POST['password'];
$password2 = (string)$_POST['password_confirm'];
$tier      = trim($_POST['tier']);

if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
    reply(['ok'=>false, 'error'=>'invalid_email', 'field'=>'email', 'message'=>'Please enter a valid email address.']);
}
if (strlen($password) < 8) {
    reply(['ok'=>false, 'error'=>'weak_password', 'field'=>'password', 'message'=>'Password must be at least 8 characters.']);
}
if ($password !== $password2) {
    reply(['ok'=>false, 'error'=>'password_mismatch', 'field'=>'password2', 'message'=>'Passwords don\'t match.']);
}
if (!in_array($tier, ['Bronze','Silver','Gold','Platinum','Diamond'], true)) {
    reply(['ok'=>false, 'error'=>'invalid_tier', 'message'=>'Please select a valid package.']);
}

// ── Local duplicate ──────────────────────────────────────────
if (db_row('SELECT id FROM members WHERE email=:e', ['e'=>$email])) {
    reply(['ok'=>false, 'error'=>'exists', 'field'=>'email',
           'message'=>'That email is already registered with us. Please log in or reset your password.']);
}

// ── Zoho-side validation BEFORE any local writes ─────────────
require_once __DIR__ . '/includes/zoho.php';

$zoho_contact_id = null;
$zoho_skipped    = false;

if (zoho_is_configured()) {
    // Lookup existing customer
    $existing_zoho = null;
    try {
        $existing_zoho = zoho_find_contact_by_email($email);
    } catch (Throwable $e) {
        app_log('Zoho lookup threw during signup-validate: ' . $e->getMessage());
        $zoho_skipped = true;
    }

    if ($existing_zoho) {
        app_log("Signup blocked: $email already exists in Zoho as contact " . ($existing_zoho['contact_id'] ?? '?'));
        reply(['ok'=>false, 'error'=>'zoho_exists', 'field'=>'email',
               'message'=>'We already have a customer record with this email address. Please log in or reset your password.']);
    }

    // Try to create the Zoho contact NOW
    if (!$zoho_skipped) {
        $zoho_payload = [
            'contact_name'    => trim($_POST['business']) ?: trim($_POST['first_name'] . ' ' . $_POST['last_name']),
            'company_name'    => trim($_POST['business']) ?: null,
            'contact_type'    => 'customer',
            'contact_persons' => [[
                'first_name'         => trim($_POST['first_name']),
                'last_name'          => trim($_POST['last_name']),
                'email'              => $email,
                'phone'              => trim($_POST['phone'] ?? ''),
                'is_primary_contact' => true,
            ]],
            'billing_address' => ['country' => 'South Africa'],
            'notes' => 'Buy Local tier: ' . $tier,
        ];

        try {
            $r = zoho_request('POST', '/contacts', $zoho_payload);
        } catch (Throwable $e) {
            $r = ['ok'=>false, 'status'=>0, 'data'=>null, 'raw'=>$e->getMessage()];
        }

        if ($r['ok'] && !empty($r['data']['contact']['contact_id'])) {
            $zoho_contact_id = (string)$r['data']['contact']['contact_id'];
        } else {
            $zoho_code = (int)($r['data']['code'] ?? 0);
            $zoho_msg  = (string)($r['data']['message'] ?? '');

            if (
                stripos($zoho_msg, 'email') !== false &&
                (stripos($zoho_msg, 'invalid') !== false || stripos($zoho_msg, 'not valid') !== false)
            ) {
                app_log("Signup aborted: Zoho rejected email '$email' — $zoho_msg");
                reply(['ok'=>false, 'error'=>'invalid_email', 'field'=>'email',
                       'message'=>'That email address didn\'t pass validation. Please check the spelling and try again.']);
            }

            if ($zoho_code === 3062 || stripos($zoho_msg, 'already') !== false) {
                app_log("Signup aborted: Zoho says contact already exists for $email");
                reply(['ok'=>false, 'error'=>'zoho_exists', 'field'=>'email',
                       'message'=>'We already have a customer record with this email address. Please log in or reset your password.']);
            }

            // Some other Zoho failure — log it but allow signup to proceed
            app_log("Zoho contact-create failed during signup-validate (allowing): code=$zoho_code msg='$zoho_msg' raw=" . substr($r['raw'] ?? '', 0, 300));
            $zoho_skipped = true;
        }
    }
}

// ── Create the local member ──────────────────────────────────
$password_hash = password_hash($password, PASSWORD_BCRYPT, ['cost' => AUTH_BCRYPT_COST]);

try {
    $member_id = db_insert('members', [
        'email'           => $email,
        'password_hash'   => $password_hash,
        'first_name'      => trim($_POST['first_name']),
        'last_name'       => trim($_POST['last_name']),
        'phone'           => trim($_POST['phone'] ?? '') ?: null,
        'business_name'   => trim($_POST['business']),
        'industry'        => trim($_POST['industry']),
        'tier'            => $tier,
        'status'          => 'pending',
        'join_date'       => date('Y-m-d'),
        'renewal_date'    => date('Y-m-d', strtotime('+1 month')),
        'zoho_contact_id' => $zoho_contact_id,
    ]);
} catch (Throwable $e) {
    app_log('Member insert failed during signup-validate: ' . $e->getMessage());
    reply(['ok'=>false, 'error'=>'db_error', 'message'=>'Something went wrong creating your account. Please try again.']);
}

$member = db_row('SELECT * FROM members WHERE id=:id', ['id'=>$member_id]);
app_log("New signup (DB id $member_id): {$member['business_name']} <$email>, tier {$member['tier']}"
    . ($zoho_contact_id ? " — Zoho contact $zoho_contact_id" : ' — no Zoho link'));

// Member history — first event in their timeline
require_once __DIR__ . '/includes/member_history.php';
member_history_log(
    (int)$member_id,
    'signup',
    "Signed up — {$member['tier']} tier, business: {$member['business_name']}",
    [
        'tier'    => $member['tier'],
        'email'   => $email,
        'zoho'    => $zoho_contact_id ? 'linked' : 'not linked',
    ],
    ['actor_type' => 'member', 'actor_id' => (int)$member_id, 'actor_name' => trim($member['first_name'].' '.$member['last_name'])]
);

// ── Welcome email ────────────────────────────────────────────
require_once __DIR__ . '/includes/mailer.php';
try {
    email_enqueue('member_welcome', $email,
        trim($member['first_name'] . ' ' . $member['last_name']),
        [
            'first_name'    => $member['first_name'],
            'last_name'     => $member['last_name'],
            'business_name' => $member['business_name'],
            'tier'          => $member['tier'],
            'email'         => $email,
        ]
    );
} catch (Throwable $e) {
    app_log('Welcome email enqueue failed: ' . $e->getMessage());
}

// ── Retry Zoho if upfront was skipped ────────────────────────
if ($zoho_skipped && zoho_is_configured()) {
    try {
        zoho_sync_member((int)$member_id);
    } catch (Throwable $e) {
        app_log("Zoho retry sync failed for new member $member_id: " . $e->getMessage());
    }
}

// ── Auto-login ───────────────────────────────────────────────
session_start_once();
session_regenerate_id(true);
$_SESSION['member_id']    = (int)$member_id;
$_SESSION['member_email'] = $email;
csrf_rotate();
db_exec('UPDATE members SET last_login_at=NOW() WHERE id=:id', ['id'=>$member_id]);

reply(['ok'=>true, 'member_id'=>(int)$member_id]);