<?php
declare(strict_types=1);

namespace App\Services;

use App\Core\Auth;
use App\Models\Notification;
use App\Models\Opportunity;
use App\Models\User;

final class NotificationService
{
    public static function send(int $userId, string $title, string $body, string $url, bool $matchBody = false): void
    {
        if ($userId < 1) {
            return;
        }
        $title = self::clip($title, 180);
        $body = self::clip($body, 255);
        $url = self::clip($url, 255);
        if (Notification::existsToday($userId, $title, $url, $matchBody ? $body : null)) {
            return;
        }
        Notification::create([
            'user_id' => $userId,
            'title' => $title,
            'body' => $body !== '' ? $body : null,
            'url' => $url,
        ]);
    }

    public static function taskAssigned(int $ownerId, string $title, ?int $fromUserId = null): void
    {
        $actor = $fromUserId ?? Auth::instance()->id();
        if ($ownerId < 1 || $ownerId === $actor) {
            return;
        }
        self::send($ownerId, 'Task assigned to you', $title, '/tasks', true);
    }

    public static function syncDealNextSteps(): void
    {
        static $ran = false;
        if ($ran) {
            return;
        }
        $ran = true;
        $tenantId = Auth::instance()->tenantId();
        if (!$tenantId) {
            return;
        }
        $managerIds = [];
        foreach (User::managers($tenantId) as $m) {
            $managerIds[] = (int) $m['id'];
        }
        foreach (Opportunity::openNextStepDue() as $deal) {
            $ownerId = (int) ($deal['owner_id'] ?? 0);
            $url = '/opportunities/' . (int) $deal['id'];
            $name = trim((string) ($deal['name'] ?? 'Deal'));
            $step = trim((string) ($deal['next_step'] ?? ''));
            $line = $step !== '' ? $name . ' · ' . $step : $name;
            $dueDay = date('Y-m-d', strtotime((string) $deal['next_step_at']));
            if ($dueDay === date('Y-m-d')) {
                if ($ownerId > 0) {
                    self::send($ownerId, 'Deal next step due today', $line, $url);
                }
                continue;
            }
            if ($ownerId > 0) {
                self::send($ownerId, 'Deal next step overdue', $line, $url);
            }
            $ownerName = trim((string) ($deal['owner_name'] ?? ''));
            $managerLine = $ownerName !== '' ? $ownerName . ': ' . $line : $line;
            foreach ($managerIds as $mid) {
                if ($mid === $ownerId) {
                    continue;
                }
                self::send($mid, 'Deal next step overdue', $managerLine, $url);
            }
        }
    }

    private static function clip(string $text, int $max): string
    {
        if (function_exists('mb_substr')) {
            return mb_substr($text, 0, $max);
        }
        return substr($text, 0, $max);
    }
}
