<?php

namespace App\Services\Email;

use Illuminate\Support\Facades\DB;

class EmailExtractorService
{
    public function listEmails(): array
    {
        $users = [];
        $parents = [];

        $userRows = DB::table('users')->select('email')->get();
        foreach ($userRows as $row) {
            $email = strtolower(trim((string) ($row->email ?? '')));
            if ($email !== '' && filter_var($email, FILTER_VALIDATE_EMAIL)) {
                $users[] = $email;
            }
        }
        $users = array_values(array_unique($users));

        $parentRows = DB::table('parents')->select('secondparent_email')->get();
        foreach ($parentRows as $row) {
            $email = strtolower(trim((string) ($row->secondparent_email ?? '')));
            if ($email !== '' && filter_var($email, FILTER_VALIDATE_EMAIL)) {
                $parents[] = $email;
            }
        }
        $parents = array_values(array_unique($parents));

        return [
            'users' => $users,
            'parents' => $parents,
        ];
    }

    public function compare(array $csvEmails): array
    {
        $emails = $this->listEmails();
        $users = $emails['users'];
        $parents = $emails['parents'];

        $csvEmails = $this->normalizeEmailArray($csvEmails);

        $csvSet = array_flip(array_values(array_unique($csvEmails)));
        $dbUnion = array_values(array_unique(array_merge($users, $parents)));
        $dbSet = array_flip($dbUnion);

        $existed = [];
        foreach ($csvSet as $email => $_) {
            if (isset($dbSet[$email])) {
                $existed[] = $email;
            }
        }
        sort($existed);

        $needToAdd = [];
        foreach ($dbSet as $email => $_) {
            if (!isset($csvSet[$email])) {
                $needToAdd[] = $email;
            }
        }
        sort($needToAdd);

        return [
            'existed' => $existed,
            'needToAdd' => $needToAdd,
            'counts' => [
                'csv' => count($csvEmails),
                'db' => count($dbUnion),
                'users' => count($users),
                'parents' => count($parents),
            ],
        ];
    }

    public function normalizeEmailArray(array $arr): array
    {
        $out = [];
        foreach ($arr as $e) {
            $email = strtolower(trim((string) $e));
            if ($email !== '' && filter_var($email, FILTER_VALIDATE_EMAIL)) {
                $out[] = $email;
            }
        }
        return array_values(array_unique($out));
    }

    public function extractEmailsFromText(string $text): array
    {
        $pattern = '/[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}/i';
        preg_match_all($pattern, $text, $matches);
        $emails = $matches[0] ?? [];
        return $this->normalizeEmailArray($emails);
    }
}
