<?php
declare(strict_types=1);
session_start();
require_once __DIR__ . '/functions.php';

$errors = [];
$success = false;

$mathA = random_int(2, 8);
$mathB = random_int(2, 8);
$mathExpected = hash('sha256', (string)($mathA + $mathB) . 'corner-store-moveout-form');

function old_moveout(string $key): string {
    return e((string)($_POST[$key] ?? ''));
}

function normalise_au_mobile_for_sms(string $phone): string {
    $phone = normalise_phone($phone);

    if ($phone === '') {
        return '';
    }

    if (str_starts_with($phone, '+')) {
        return $phone;
    }

    if (str_starts_with($phone, '04')) {
        return '+61' . substr($phone, 1);
    }

    if (str_starts_with($phone, '614')) {
        return '+' . $phone;
    }

    if (str_starts_with($phone, '61')) {
        return '+' . $phone;
    }

    return $phone;
}

function send_moveout_sms_to(string $to, string $message): void {
    if (!function_exists('curl_init')) {
        throw new RuntimeException('PHP cURL extension is required for Twilio SMS.');
    }

    $url = 'https://api.twilio.com/2010-04-01/Accounts/' . rawurlencode(TWILIO_ACCOUNT_SID) . '/Messages.json';
    $payload = http_build_query([
        'To' => $to,
        'From' => TWILIO_FROM_NUMBER,
        'Body' => $message,
    ]);

    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_POST => true,
        CURLOPT_POSTFIELDS => $payload,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_USERPWD => TWILIO_ACCOUNT_SID . ':' . TWILIO_AUTH_TOKEN,
        CURLOPT_HTTPAUTH => CURLAUTH_BASIC,
        CURLOPT_TIMEOUT => 20,
    ]);

    $response = curl_exec($ch);
    $status = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $error = curl_error($ch);
    curl_close($ch);

    if ($response === false || $status < 200 || $status >= 300) {
        throw new RuntimeException('Twilio SMS failed. HTTP ' . $status . ' ' . $error . ' ' . (string)$response);
    }
}

function send_moveout_email(string $to, array $cc, string $subject, string $html): void {
    $headers = [
        'Date: ' . date(DATE_RFC2822),
        'From: ' . FROM_NAME . ' <' . FROM_EMAIL . '>',
        'To: ' . $to,
        'Subject: ' . mb_encode_mimeheader($subject, 'UTF-8'),
        'MIME-Version: 1.0',
        'Content-Type: text/html; charset=UTF-8',
    ];

    if ($cc) {
        $headers[] = 'Cc: ' . implode(', ', $cc);
    }

    $message = implode("\r\n", $headers) . "\r\n\r\n" . $html;

    $socket = stream_socket_client('tcp://' . SENDGRID_SMTP_HOST . ':' . SENDGRID_SMTP_PORT, $errno, $errstr, 20);
    if (!$socket) {
        throw new RuntimeException("Could not connect to SendGrid SMTP: {$errstr} ({$errno})");
    }

    smtp_read($socket);
    smtp_command($socket, 'EHLO ' . ($_SERVER['SERVER_NAME'] ?? 'localhost'), [250]);
    smtp_command($socket, 'STARTTLS', [220]);

    if (!stream_socket_enable_crypto($socket, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)) {
        throw new RuntimeException('Could not start TLS for SMTP.');
    }

    smtp_command($socket, 'EHLO ' . ($_SERVER['SERVER_NAME'] ?? 'localhost'), [250]);
    smtp_command($socket, 'AUTH LOGIN', [334]);
    smtp_command($socket, base64_encode(SENDGRID_SMTP_USERNAME), [334]);
    smtp_command($socket, base64_encode(SENDGRID_SMTP_PASSWORD), [235]);
    smtp_command($socket, 'MAIL FROM:<' . FROM_EMAIL . '>', [250]);
    smtp_command($socket, 'RCPT TO:<' . $to . '>', [250, 251]);

    foreach ($cc as $ccEmail) {
        smtp_command($socket, 'RCPT TO:<' . $ccEmail . '>', [250, 251]);
    }

    smtp_command($socket, 'DATA', [354]);
    fwrite($socket, $message . "\r\n.\r\n");
    $response = smtp_read($socket);

    if ((int)substr($response, 0, 3) !== 250) {
        throw new RuntimeException('SMTP DATA failed: ' . $response);
    }

    smtp_command($socket, 'QUIT', [221]);
    fclose($socket);
}

function build_moveout_data(array $post): array {
    return [
        'Full Name' => clean_text($post['full_name'] ?? ''),
        'Shed Number' => clean_text($post['shed_number'] ?? ''),
        'Email' => clean_email($post['email'] ?? ''),
        'Phone' => normalise_phone($post['phone'] ?? ''),
        'Move Out Date' => clean_text($post['move_out_date'] ?? ''),
        'Confirmed' => !empty($post['confirm_vacate']) ? 'Yes' : 'No',
        'Submitted At' => date('d/m/Y g:i A'),
    ];
}

function moveout_email_body(array $data): string {
    $rows = '';
    foreach ($data as $key => $value) {
        $rows .= '<tr><th style="text-align:left;padding:10px;border-bottom:1px solid #e6eef5;background:#f8fbff;width:220px;">' . e($key) . '</th><td style="padding:10px;border-bottom:1px solid #e6eef5;">' . e($value) . '</td></tr>';
    }

    return '<!doctype html><html><body style="font-family:Arial,Helvetica,sans-serif;background:#f3f7fb;margin:0;padding:24px;color:#17324d;">'
        . '<table role="presentation" width="100%" cellpadding="0" cellspacing="0"><tr><td align="center">'
        . '<table role="presentation" width="680" cellpadding="0" cellspacing="0" style="max-width:680px;background:#ffffff;border-radius:16px;overflow:hidden;border:1px solid #dce8f2;">'
        . '<tr><td style="padding:22px 24px;text-align:center;background:#ffffff;"><img src="' . e(BUSINESS_LOGO_URL) . '" alt="' . e(BUSINESS_NAME) . '" style="max-width:210px;height:auto;"></td></tr>'
        . '<tr><td style="padding:24px;"><h1 style="font-size:22px;margin:0 0 8px;">Storage Move Out Notice Received</h1>'
        . '<p style="margin:0 0 18px;color:#4f6378;">A storage move out notice has been submitted.</p>'
        . '<table width="100%" cellpadding="0" cellspacing="0" style="border-collapse:collapse;border:1px solid #e6eef5;border-radius:12px;overflow:hidden;">' . $rows . '</table>'
        . '<p style="margin:18px 0 0;color:#4f6378;">Your storage shed is to be returned in a clean state, with the lock removed and having been swept. In the event cleaning is required for your shed, a cleaning fee will be charged.</p>'
        . '<p style="margin:12px 0 0;color:#4f6378;">Sheds are inspected and your deposit is refunded to your payment card within 7 days of vacate.</p>'
        . '</td></tr></table></td></tr></table></body></html>';
}

function validate_moveout(array $post): array {
    $errors = [];

    if (!verify_csrf($post['csrf_token'] ?? null)) {
        $errors[] = 'Your session expired. Please refresh and try again.';
    }

    if (!empty($post['website'] ?? '')) {
        $errors[] = 'Spam check failed.';
    }

    $started = (int)($post['form_started'] ?? 0);
    $minSeconds = defined('MIN_FORM_SECONDS') ? MIN_FORM_SECONDS : 3;
    if ($started <= 0 || time() - $started < $minSeconds) {
        $errors[] = 'Please take a moment to complete the form before submitting.';
    }

    $mathAnswer = (string)($post['confirm_answer'] ?? '');
    $mathExpected = (string)($post['confirm_expected'] ?? '');
    if ($mathAnswer === '' || $mathExpected === '' || !hash_equals($mathExpected, hash('sha256', $mathAnswer . 'corner-store-moveout-form'))) {
        $errors[] = 'Please complete the confirmation question correctly.';
    }

    $required = [
        'full_name' => 'Full Name',
        'shed_number' => 'Shed Number',
        'email' => 'Email',
        'phone' => 'Phone',
        'move_out_date' => 'Move Out Date',
    ];

    foreach ($required as $field => $label) {
        if (clean_text($post[$field] ?? '') === '') {
            $errors[] = $label . ' is required.';
        }
    }

    if (!filter_var(clean_email($post['email'] ?? ''), FILTER_VALIDATE_EMAIL)) {
        $errors[] = 'A valid email address is required.';
    }

    if (normalise_au_mobile_for_sms((string)($post['phone'] ?? '')) === '') {
        $errors[] = 'A valid phone number is required.';
    }

    $moveOutDate = clean_text($post['move_out_date'] ?? '');
    if ($moveOutDate !== '') {
        $dt = DateTime::createFromFormat('Y-m-d', $moveOutDate);
        if (!$dt || $dt->format('Y-m-d') !== $moveOutDate) {
            $errors[] = 'Move Out Date must be a valid date.';
        } else {
            $today = new DateTime('today');
            $minimum = (clone $today)->modify('+7 days');
            if ($dt < $minimum) {
                $errors[] = '7 days notice is required. Please select a move out date at least 7 days from today.';
            }
        }
    }

    if (empty($post['confirm_vacate'])) {
        $errors[] = 'Please confirm that you will be vacating your shed on the selected date.';
    }

    return $errors;
}

function log_moveout(array $data, string $status): void {
    $logDir = '/home/dcmgaus/private/logs';
    if (!is_dir($logDir)) {
        @mkdir($logDir, 0755, true);
    }

    $line = json_encode([
        'time' => date(DATE_ATOM),
        'status' => $status,
        'data' => $data,
        'ip' => $_SERVER['REMOTE_ADDR'] ?? '',
    ], JSON_UNESCAPED_SLASHES) . PHP_EOL;

    @file_put_contents($logDir . '/moveouts.log', $line, FILE_APPEND);
}

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $errors = validate_moveout($_POST);

    if (!$errors) {
        $data = build_moveout_data($_POST);

        try {
            $subject = 'Storage Move Out Notice - Shed ' . $data['Shed Number'] . ' - ' . $data['Full Name'];
            $html = moveout_email_body($data);

            send_moveout_email(ADMIN_EMAIL, [$data['Email']], $subject, $html);

            $customerPhone = normalise_au_mobile_for_sms($data['Phone']);
            $noticeDate = $data['Move Out Date'];
            $customerSms = 'The Corner Store: Your move out notice has been received for ' . $noticeDate . '. Please ensure your shed is clean, swept and the lock removed.';
            send_moveout_sms_to($customerPhone, $customerSms);

            $adminTo = defined('TWILIO_ALERT_TO') ? TWILIO_ALERT_TO : '+61402145361';
            if (!str_starts_with($adminTo, '+')) {
                $adminTo = '+' . $adminTo;
            }
            $adminSms = 'New move out notice: ' . $data['Full Name'] . ', Shed ' . $data['Shed Number'] . ', vacating ' . $noticeDate . '. Phone: ' . $customerPhone;
            send_moveout_sms_to($adminTo, $adminSms);

            log_moveout($data, 'sent');
            $success = true;
            $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
        } catch (Throwable $ex) {
            log_moveout($data ?? [], 'error: ' . $ex->getMessage());
            $errors[] = 'Your move out notice was received, but the notification could not be sent. Please contact us directly.';
        }
    }
}

$minMoveOutDate = (new DateTime('today'))->modify('+7 days')->format('Y-m-d');
?>
<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>Move Out Notice | The Corner Store</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="style.css?v=1.0.0">
</head>
<body>
<main class="page">
    <section class="card">
        <header class="hero">
            <img src="<?= e(BUSINESS_LOGO_URL) ?>" alt="The Corner Store" class="logo">
            <p class="eyebrow">Storage Move Out Notice</p>
            <h1>Move Out Form</h1>
            <p class="intro">Please complete this form to provide notice that you will be vacating your storage shed.</p>
        </header>

        <?php if ($success): ?>
            <div class="success">
                <h2>Move out notice received</h2>
                <p>Thank you. Your move out notice has been submitted. A confirmation has been sent to you.</p>
            </div>
        <?php else: ?>
            <?php if ($errors): ?>
                <div class="errors">
                    <strong>Please check the following:</strong>
                    <ul>
                        <?php foreach ($errors as $error): ?>
                            <li><?= e($error) ?></li>
                        <?php endforeach; ?>
                    </ul>
                </div>
            <?php endif; ?>

            <form method="post" class="signup-form" id="moveoutForm" novalidate>
                <input type="hidden" name="csrf_token" value="<?= e(csrf_token()) ?>">
                <input type="hidden" name="form_started" value="<?= time() ?>">
                <input type="hidden" name="confirm_expected" value="<?= e($mathExpected) ?>">

                <div class="bot-field" aria-hidden="true">
                    <label>Website <input type="text" name="website" tabindex="-1" autocomplete="off"></label>
                </div>

                <div class="grid">
                    <label>
                        <span>Full Name *</span>
                        <input type="text" name="full_name" value="<?= old_moveout('full_name') ?>" autocomplete="name" required>
                    </label>

                    <label>
                        <span>Shed Number *</span>
                        <input type="text" name="shed_number" value="<?= old_moveout('shed_number') ?>" required>
                    </label>

                    <label>
                        <span>Email *</span>
                        <input type="email" name="email" value="<?= old_moveout('email') ?>" autocomplete="email" required>
                    </label>

                    <label>
                        <span>Phone *</span>
                        <input type="tel" name="phone" value="<?= old_moveout('phone') ?>" autocomplete="tel" required>
                    </label>

                    <label class="full">
                        <span>Move Out Date *</span>
                        <input type="date" name="move_out_date" id="move_out_date" value="<?= old_moveout('move_out_date') ?>" min="<?= e($minMoveOutDate) ?>" required>
                        <small>7 days notice is required.</small>
                    </label>

                    <div class="full contract-note">
                        <p><strong>Move out notes:</strong></p>
                        <p>Your storage shed is to be returned in a clean state, with the lock removed and having been swept. In the event cleaning is required for your shed a cleaning fee will be charged.</p>
                        <p>Sheds are inspected and your deposit is refunded to your payment card within 7 days of vacate.</p>
                    </div>

                    <label class="full confirmation">
                        <span>Confirmation *</span>
                        <input type="number" name="confirm_answer" inputmode="numeric" placeholder="What is <?= $mathA ?> + <?= $mathB ?>?" required>
                    </label>

                    <label class="full confirmation" style="display:flex;grid-template-columns:auto 1fr;align-items:flex-start;gap:12px;">
                        <input type="checkbox" name="confirm_vacate" value="1" <?= !empty($_POST['confirm_vacate']) ? 'checked' : '' ?> required style="width:auto;margin-top:3px;">
                        <span>I confirm that I will be vacating my shed on the above date, and understand that my shed is to be returned in a clean state.</span>
                    </label>
                </div>

                <button type="submit" class="submit-btn">Submit Move Out Notice</button>
            </form>
        <?php endif; ?>
    </section>
</main>
<script>
(function () {
    const form = document.getElementById('moveoutForm');
    const moveOutDate = document.getElementById('move_out_date');

    if (!form || !moveOutDate) return;

    form.addEventListener('submit', function (event) {
        if (!moveOutDate.value) return;

        const selected = new Date(moveOutDate.value + 'T00:00:00');
        const today = new Date();
        today.setHours(0, 0, 0, 0);
        const minimum = new Date(today);
        minimum.setDate(minimum.getDate() + 7);

        if (selected < minimum) {
            event.preventDefault();
            alert('7 days notice is required. Please select a move out date at least 7 days from today.');
            moveOutDate.focus();
        }
    });
})();
</script>
</body>
</html>
