<?php
declare(strict_types=1);

require_once __DIR__ . '/bootstrap.php';
require_once __DIR__ . '/db.php';

function affiliate_send_json(array $payload, int $httpCode = 200): void
{
    http_response_code($httpCode);
    header('Content-Type: application/json; charset=utf-8');
    $json = json_encode($payload, JSON_UNESCAPED_UNICODE);
    if ($json === false) {
        echo '{"ok":false,"error":"server"}';
    } else {
        echo $json;
    }
    exit;
}

try {
    if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
        affiliate_send_json(['ok' => false, 'error' => 'method']);
    }

    mocker_require_csrf_post();

    $uid = isset($_SESSION['mocker_user_id']) ? (int) $_SESSION['mocker_user_id'] : 0;
    if ($uid <= 0) {
        affiliate_send_json(['ok' => false, 'error' => 'auth']);
    }

    $input = json_decode((string) file_get_contents('php://input'), true) ?: [];
    $sponsorId = trim((string) ($input['sponsorId'] ?? ''));
    $sponsorTitle = trim((string) ($input['sponsorTitle'] ?? ''));
    $message = trim((string) ($input['message'] ?? ''));
    $investmentDateRaw = trim((string) ($input['investmentDate'] ?? ''));

    if ($sponsorId === '') {
        affiliate_send_json(['ok' => false, 'error' => 'sponsor']);
    }

    $msgLen = mocker_utf8_len($message);
    if ($message === '' || $msgLen < 8) {
        affiliate_send_json(['ok' => false, 'error' => 'message']);
    }
    if ($msgLen > 2000) {
        affiliate_send_json(['ok' => false, 'error' => 'message_long']);
    }

    $investmentDate = null;
    if ($investmentDateRaw !== '') {
        if (!preg_match('/^(\d{4})-(\d{2})-(\d{2})$/', $investmentDateRaw, $m)) {
            affiliate_send_json(['ok' => false, 'error' => 'investment_date']);
        }
        $y = (int) $m[1];
        $mo = (int) $m[2];
        $d = (int) $m[3];
        if (!checkdate($mo, $d, $y)) {
            affiliate_send_json(['ok' => false, 'error' => 'investment_date']);
        }
        $investmentDate = sprintf('%04d-%02d-%02d', $y, $mo, $d);
    }

    try {
        $pdo = mocker_db();
    } catch (Throwable $e) {
        affiliate_send_json(['ok' => false, 'error' => 'db']);
    }

    $username = '';
    $email = '—';
    $now = time();

    try {
        $stUser = $pdo->prepare('SELECT username, email FROM users WHERE id = :id LIMIT 1');
        $stUser->execute([':id' => $uid]);
        $u = $stUser->fetch();
        if (!$u) {
            affiliate_send_json(['ok' => false, 'error' => 'auth']);
        }

        $username = trim((string) ($u['username'] ?? ''));
        $emailRaw = $u['email'] ?? null;
        $email = is_string($emailRaw) ? trim($emailRaw) : '';
        if ($email === '') {
            $email = '—';
        }

        $ins = $pdo->prepare(
            'INSERT INTO affiliate_requests (user_id, username, email, sponsor_id, sponsor_title, investment_date, message, status, created_at, updated_at)
             VALUES (:uid, :un, :em, :sid, :st, :inv, :msg, :status, :t, :t2)'
        );
        $ins->execute([
            ':uid' => $uid,
            ':un' => $username,
            ':em' => $email,
            ':sid' => $sponsorId,
            ':st' => $sponsorTitle !== '' ? $sponsorTitle : null,
            ':inv' => $investmentDate,
            ':msg' => $message,
            ':status' => 'pending',
            ':t' => $now,
            ':t2' => $now,
        ]);
    } catch (PDOException $e) {
        $em = $e->getMessage();
        $isSchema =
            (strpos($em, 'no such table') !== false) ||
            (strpos($em, 'has no column') !== false);
        affiliate_send_json(['ok' => false, 'error' => $isSchema ? 'schema' : 'save']);
    }

    affiliate_send_json(
        [
            'ok' => true,
            'request' => [
                'id' => (int) $pdo->lastInsertId(),
                'status' => 'pending',
                'createdAt' => $now,
            ],
        ]
    );
} catch (Throwable $e) {
    error_log('user_affiliate_request: ' . $e->getMessage() . ' @' . $e->getFile() . ':' . $e->getLine());
    affiliate_send_json(['ok' => false, 'error' => 'server']);
}
