<?php
declare(strict_types=1);

namespace App\Services;

use App\Core\Auth;
use App\Core\Database;
use App\Models\AuditLog;
use App\Models\Lead;
use App\Models\Notification;
use App\Models\Territory;
use App\Models\User;

final class AssignmentService
{
    public static function assign(int $leadId, string $method, ?int $userId, ?int $territoryId): array
    {
        $lead = Lead::find($leadId);
        if (!$lead) {
            return ['ok' => false, 'error' => 'Lead not found.'];
        }
        $ownerId = null;
        if ($method === 'manual') {
            $ownerId = $userId;
        } elseif ($method === 'territory') {
            $tid = $territoryId ?: (int) ($lead['territory_id'] ?? 0);
            if (!$tid) {
                return ['ok' => false, 'error' => 'This lead has no territory.'];
            }
            $people = Territory::usersIn($tid);
            if ($people === []) {
                return ['ok' => false, 'error' => 'No salesperson in that territory.'];
            }
            $ownerId = (int) $people[0]['id'];
        } elseif ($method === 'round_robin') {
            $ownerId = self::nextRoundRobin();
            if (!$ownerId) {
                return ['ok' => false, 'error' => 'No salespeople available.'];
            }
        }
        if (!$ownerId) {
            return ['ok' => false, 'error' => 'Pick a salesperson.'];
        }
        Lead::update($leadId, ['owner_id' => $ownerId]);
        Notification::create([
            'user_id' => $ownerId,
            'title' => 'New lead assigned',
            'body' => trim($lead['first_name'] . ' ' . $lead['last_name']) . ' was assigned to you.',
            'url' => '/leads/' . $leadId,
        ]);
        AuditLog::write('lead.assign', 'lead', $leadId, ['owner_id' => $ownerId, 'method' => $method]);
        return ['ok' => true];
    }

    private static function nextRoundRobin(): ?int
    {
        $tenantId = Auth::instance()->tenantId();
        $people = User::salespeople($tenantId);
        if ($people === []) {
            return null;
        }
        $ids = array_map(static fn($p) => (int) $p['id'], $people);
        $row = Database::instance()->fetch(
            'SELECT last_user_id FROM assignment_cursors WHERE tenant_id = :tid',
            ['tid' => $tenantId]
        );
        $last = $row ? (int) $row['last_user_id'] : 0;
        $next = $ids[0];
        $found = false;
        foreach ($ids as $id) {
            if ($found) {
                $next = $id;
                break;
            }
            if ($id === $last) {
                $found = true;
            }
        }
        if ($row) {
            Database::instance()->query(
                'UPDATE assignment_cursors SET last_user_id = :uid WHERE tenant_id = :tid',
                ['uid' => $next, 'tid' => $tenantId]
            );
        } else {
            Database::instance()->query(
                'INSERT INTO assignment_cursors (tenant_id, last_user_id) VALUES (:tid, :uid)',
                ['tid' => $tenantId, 'uid' => $next]
            );
        }
        return $next;
    }
}
