<?php
declare(strict_types=1);

namespace App\Contact;

use App\Support\TranslatableException;
use InvalidArgumentException;
use PDO;

final class ContactService
{
    public function __construct(private readonly PDO $pdo)
    {
    }

    public function create(string $name, string $email, string $subject, string $message, string $locale, ?string $ip = null): int
    {
        $name = trim($name);
        $email = strtolower(trim($email));
        $subject = trim($subject);
        $message = trim($message);
        $locale = strtolower(str_replace('_', '-', trim($locale)));

        if ($name === '' || (function_exists('mb_strlen') ? mb_strlen($name, 'UTF-8') : strlen($name)) > 120) {
            throw new TranslatableException('contact.validation_name');
        }
        if (filter_var($email, FILTER_VALIDATE_EMAIL) === false || strlen($email) > 191) {
            throw new TranslatableException('contact.validation_email');
        }
        if ($message === '' || (function_exists('mb_strlen') ? mb_strlen($message, 'UTF-8') : strlen($message)) > 5000) {
            throw new TranslatableException('contact.validation_message');
        }
        if ((function_exists('mb_strlen') ? mb_strlen($subject, 'UTF-8') : strlen($subject)) > 191) {
            throw new TranslatableException('contact.validation_subject_too_long');
        }

        $statement = $this->pdo->prepare(
            'INSERT INTO contact_messages (name, email, subject, message, locale, status, ip_hash, created_at, updated_at)
             VALUES (:name, :email, :subject, :message, :locale, :status, :ip_hash, NOW(), NOW())'
        );
        $statement->execute([
            'name' => $name,
            'email' => $email,
            'subject' => $subject === '' ? null : $subject,
            'message' => $message,
            'locale' => $locale === '' ? 'ar' : $locale,
            'status' => 'open',
            'ip_hash' => $ip === null || trim($ip) === '' ? null : hash('sha256', trim($ip)),
        ]);

        return (int) $this->pdo->lastInsertId();
    }
}
