<?php

use App\Controllers\PublicController;

/**
 * Contact form endpoint.
 *
 *   POST /api/contact/submit — accept a message, store it in cja_contact
 *
 * The router does `new Contact(...)`, so this is a GLOBAL class in
 * public/controllers/ (not namespaced), matching account.php / health.php.
 * The base class it extends is the namespaced one autoloaded by composer.
 *
 * Public, so it guards origin and rate-limits. Validation is server-side and
 * authoritative; the browser's `required` attributes are a convenience only.
 */
class Contact extends PublicController
{
    /** Subjects the form offers. The slug is stored; the label is display-only. */
    private const SUBJECTS = [
        'automation'          => 'Automation',
        'website-design'      => 'Website Design',
        'digital-marketing'   => 'Digital Marketing',
        'fractional-cto'      => 'Fractional CTO',
        'other'               => 'Other',
    ];

    public function submit(): void
    {
        // 5 submissions per 10 minutes per IP — generous for a human, useless
        // for a script.
        $this->guardPublic('contact_submit', 5, 600);

        if (($_SERVER['REQUEST_METHOD'] ?? 'GET') !== 'POST') {
            $this->json(null, 405, ['code' => 'method_not_allowed', 'message' => 'POST only']);
        }

        $in = $this->readBody();

        // Honeypot: a field hidden from humans. A bot fills everything, so any
        // value here is spam. Answer 200 so it cannot tell it was caught, but
        // write nothing.
        if (trim((string) ($in['company'] ?? '')) !== '') {
            $this->json(['received' => true]);
        }

        $name    = trim((string) ($in['name'] ?? ''));
        $email   = trim((string) ($in['email'] ?? ''));
        $subject = trim((string) ($in['subject'] ?? 'other'));
        $message = trim((string) ($in['message'] ?? ''));

        $errors = [];
        if ($name === '' || mb_strlen($name) > 160) {
            $errors['name'] = 'Please enter your name.';
        }
        if ($email === '' || !filter_var($email, FILTER_VALIDATE_EMAIL) || mb_strlen($email) > 255) {
            $errors['email'] = 'Please enter a valid email address.';
        }
        if (!isset(self::SUBJECTS[$subject])) {
            // Unknown subject is coerced, not rejected — never trust the
            // client's list, but do not fail a real person over it either.
            $subject = 'other';
        }
        if (mb_strlen($message) < 10) {
            $errors['message'] = 'Please add a little more detail (10 characters or more).';
        }
        if (mb_strlen($message) > 5000) {
            $errors['message'] = 'That message is a bit long — please keep it under 5000 characters.';
        }

        if ($errors) {
            $this->json(null, 422, [
                'code'    => 'validation_failed',
                'message' => 'Please check the highlighted fields.',
                'fields'  => $errors,
            ]);
        }

        \Db::insert('cja_contact', [
            'name'       => $name,
            'email'      => $email,
            'subject'    => $subject,
            'message'    => $message,
            'status'     => 'new',
            'ip'         => $_SERVER['REMOTE_ADDR'] ?? null,
            'user_agent' => mb_substr((string) ($_SERVER['HTTP_USER_AGENT'] ?? ''), 0, 255),
            'referrer'   => mb_substr((string) ($_SERVER['HTTP_REFERER'] ?? ''), 0, 255),
            'created_at' => date('Y-m-d H:i:s'),
        ]);

        // TODO: notify. A mailer helper exists (app/Helpers/Mailer.php, Brevo);
        // wire it once a from-address and API key are configured. The row is
        // saved regardless, so a mail outage never loses a lead.

        $this->json([
            'received' => true,
            'message'  => "Thanks — I'll get back to you shortly.",
        ]);
    }

    /** Read a JSON body, falling back to form-encoded POST. */
    private function readBody(): array
    {
        $raw = file_get_contents('php://input');
        if ($raw !== '' && $raw !== false) {
            $decoded = json_decode($raw, true);
            if (is_array($decoded)) {
                return $decoded;
            }
        }
        return $_POST ?: [];
    }
}
