<?php

namespace App\Services;

use App\Models\MexcoNotificationLog;
use App\Models\MexcoNotificationTemplate;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Mail;

class NotificationService
{
    public function send(
        string $templateCode,
        string $recipient,
        array $variables = [],
        ?string $entityType = null,
        ?string $entityId = null,
        array $metadata = [],
    ): MexcoNotificationLog {
        $template = MexcoNotificationTemplate::query()
            ->where('code', $templateCode)
            ->where('is_active', true)
            ->first();

        $subject = $this->render($template?->subject ?? $templateCode, $variables);
        $body = $this->render($template?->body ?? 'Notification: '.$templateCode, $variables);
        $channel = $template?->channel ?? 'email';

        $log = MexcoNotificationLog::query()->create([
            'template_id' => $template?->id,
            'template_code' => $templateCode,
            'recipient' => $recipient,
            'subject' => $subject,
            'body' => $body,
            'channel' => $channel,
            'status' => MexcoNotificationLog::STATUS_LOGGED,
            'entity_type' => $entityType,
            'entity_id' => $entityId,
            'metadata' => $metadata,
        ]);

        if ($channel === 'email' && filter_var($recipient, FILTER_VALIDATE_EMAIL)) {
            try {
                if (config('mail.default') && config('mail.default') !== 'log') {
                    Mail::raw($body, function ($message) use ($recipient, $subject) {
                        $message->to($recipient)->subject($subject);
                    });
                    $log->update([
                        'status' => MexcoNotificationLog::STATUS_SENT,
                        'sent_at' => now(),
                    ]);
                }
            } catch (\Throwable $e) {
                Log::warning('Notification send failed', [
                    'template' => $templateCode,
                    'recipient' => $recipient,
                    'error' => $e->getMessage(),
                ]);
                $log->update(['status' => MexcoNotificationLog::STATUS_FAILED]);
            }
        }

        return $log->fresh();
    }

    public function render(string $text, array $variables): string
    {
        foreach ($variables as $key => $value) {
            $text = str_replace('{{'.$key.'}}', (string) $value, $text);
        }

        return $text;
    }
}
