<?php

namespace App\Services\Notifications;

use App\Models\Notification;
use App\Models\UserNotification;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class NotificationSendService
{
    public function __construct(
        private NotificationRecipientService $recipients,
        private NotificationDispatchService $dispatcher
    ) {
    }

    public function send(array $payload, int $actorId): array
    {
        $channels = $payload['channels'] ?? ['in_app'];
        $channels = array_values(array_unique(array_map('strtolower', (array) $channels)));
        if (empty($channels)) {
            $channels = ['in_app'];
        }

        return DB::transaction(function () use ($payload, $channels, $actorId) {
            $notification = Notification::query()->create([
                'title' => $payload['title'],
                'message' => $payload['message'],
                'target_group' => $payload['target_group'],
                'delivery_channels' => $channels,
                'priority' => $payload['priority'] ?? null,
                'status' => $payload['status'] ?? null,
                'action_url' => $payload['action_url'] ?? null,
                'attachment_path' => $payload['attachment_path'] ?? null,
                'scheduled_at' => $payload['scheduled_at'] ?? now(),
                'sent_at' => in_array('in_app', $channels, true) ? now() : null,
                'expires_at' => $payload['expires_at'] ?? null,
                'school_year' => $payload['school_year'] ?? null,
                'semester' => $payload['semester'] ?? null,
                'created_at' => utc_now(),
                'updated_at' => utc_now(),
            ]);

            $users = $this->recipients->getRecipients((string) $payload['target_group']);
            $created = 0;

            foreach ($users as $user) {
                UserNotification::query()->create([
                    'notification_id' => (int) $notification->id,
                    'user_id' => (int) ($user['id'] ?? 0),
                    'is_read' => false,
                    'delivered' => in_array('in_app', $channels, true),
                    'delivered_at' => in_array('in_app', $channels, true) ? now() : null,
                    'school_year' => $payload['school_year'] ?? null,
                    'semester' => $payload['semester'] ?? null,
                ]);
                $created++;

                if (in_array('email', $channels, true) && !empty($user['email'])) {
                    $this->dispatcher->sendEmail((string) $user['email'], (string) $payload['title'], (string) $payload['message']);
                }

                if (in_array('sms', $channels, true) && !empty($user['phone'])) {
                    $this->dispatcher->sendSms((string) $user['phone'], (string) $payload['message']);
                }
            }

            Log::info('Notification dispatched.', [
                'notification_id' => (int) $notification->id,
                'target_group' => $payload['target_group'],
                'channels' => $channels,
                'recipients' => $created,
                'actor_id' => $actorId,
            ]);

            return [
                'ok' => true,
                'notification' => $notification,
                'recipient_count' => $created,
            ];
        });
    }
}
