using System.Collections.Generic;
using AfterHours.Core;
using AfterHours.Data;
using AfterHours.Interaction;
using Unity.Netcode;
using UnityEngine;
namespace AfterHours.Shop
{
///
/// Kasse. Kunden reihen sich ein; ein Spieler scannt Position für Position
/// und schließt ab. Sämtliche Geldbewegung passiert hier auf dem Server.
///
public sealed class CashRegister : NetworkBehaviour, IInteractable
{
[SerializeField] private ProductCatalog _catalog;
[SerializeField] private Transform _queueStart;
[SerializeField] private float _queueSpacing = 0.8f;
/// Server-only. Clients sehen die Schlange über die NPC-Positionen.
private readonly List _queue = new();
private readonly NetworkVariable _pendingTotal = new(0f);
private readonly NetworkVariable _scannedItems = new(0);
public float PendingTotal => _pendingTotal.Value;
public int QueueLength => _queue.Count;
public string GetPrompt(ulong clientId)
{
if (_queue.Count == 0) return "Kasse (frei)";
return _scannedItems.Value > 0
? $"Kassieren — {_pendingTotal.Value:0.00} €"
: "Artikel scannen";
}
/// Server: ein Klick = ein Artikel scannen, oder abschließen wenn fertig.
public void Interact(NetworkObject actor)
{
if (!IsServer || _queue.Count == 0) return;
var customer = _queue[0];
if (customer == null) { _queue.RemoveAt(0); return; }
if (_scannedItems.Value < customer.BasketCount)
{
ScanNext(customer);
return;
}
Finalize(customer);
}
private void ScanNext(Customers.CustomerAgent customer)
{
var line = customer.BasketAt(_scannedItems.Value);
_pendingTotal.Value += line.Price;
_scannedItems.Value++;
}
private void Finalize(Customers.CustomerAgent customer)
{
ShopEconomy.Instance.Earn(_pendingTotal.Value);
ShopEconomy.Instance.RegisterSale(customer.Comfort);
customer.OnPaid();
_queue.RemoveAt(0);
_pendingTotal.Value = 0f;
_scannedItems.Value = 0;
ReflowQueue();
}
/// Server: Kunde stellt sich an. Gibt die Zielposition zurück.
public Vector3 Enqueue(Customers.CustomerAgent customer)
{
if (!IsServer) return _queueStart.position;
if (!_queue.Contains(customer)) _queue.Add(customer);
return SlotPosition(_queue.IndexOf(customer));
}
/// Server: Kunde verlässt die Schlange (z. B. weil er aufgibt).
public void Remove(Customers.CustomerAgent customer)
{
if (!IsServer) return;
if (_queue.Remove(customer)) ReflowQueue();
}
private void ReflowQueue()
{
for (int i = 0; i < _queue.Count; i++)
if (_queue[i] != null) _queue[i].MoveTo(SlotPosition(i));
}
private Vector3 SlotPosition(int index)
{
return _queueStart.position + _queueStart.forward * (-_queueSpacing * index);
}
}
}