<?php

namespace App\Domain\Shared\Helpers;

class CredentialNormalizer
{
    /**
     * Canonical storage form for an email address: trimmed and lowercased.
     *
     * Mailbox providers we serve treat addresses case-insensitively, but
     * Postgres '=' does not. Storing one canonical form is what stops a
     * stored capital from locking someone out of their own account.
     */
    public static function email(?string $email): ?string
    {
        $email = trim((string) $email);

        return $email === '' ? null : mb_strtolower($email, 'UTF-8');
    }

    /**
     * Canonical storage form for a phone number: digits only, local format.
     *
     * Accepts the shapes people actually type — '+20 101 408 7672',
     * '0 11 41078754' — and returns '01014087672'. Egypt country code is
     * stripped so that the local and international forms of one number
     * cannot end up as two different accounts.
     */
    public static function phone(?string $phone): ?string
    {
        $digits = preg_replace('/[^0-9]/', '', (string) $phone) ?? '';

        if ($digits === '') {
            return null;
        }

        if (str_starts_with($digits, '20') && strlen($digits) === 12) {
            $digits = '0' . substr($digits, 2);
        }

        return $digits;
    }

    /**
     * Every stored shape a typed phone number might match.
     *
     * Lookups use this rather than the canonical form alone so that logins
     * keep working on rows written before normalisation ran — including on
     * client databases where the migration has not been applied yet.
     *
     * @return array<int, string>
     */
    public static function phoneVariants(?string $phone): array
    {
        $local = self::phone($phone);

        if ($local === null) {
            return [];
        }

        $variants = [$local, trim((string) $phone)];

        if (str_starts_with($local, '0')) {
            $bare = substr($local, 1);
            $variants[] = '+20' . $bare;
            $variants[] = '20' . $bare;
        }

        return array_values(array_unique(array_filter($variants)));
    }
}
