using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using GTANetworkAPI;
using Newtonsoft.Json;
using ReallifeGamemode.Database.Entities;
using ReallifeGamemode.Database.Models;
using ReallifeGamemode.Server.Extensions;
using ReallifeGamemode.Server.Job;
using ReallifeGamemode.Server.Services;
using ReallifeGamemode.Server.Util;
using ReallifeGamemode.Services;
using ReallifeGamemode.Server.Types;



namespace ReallifeGamemode.Server.Managers
{
  public class JobManager : Script
  {
    private static List<JobBase> _jobs = new List<JobBase>();

    public static void LoadJobs()
    {
      IEnumerable<Type> jobTypes = Assembly.GetExecutingAssembly().GetTypes().Where(t => t.IsSubclassOf(typeof(JobBase)) && !t.IsAbstract);

      foreach (var type in jobTypes)
      {
        var instance = Activator.CreateInstance(type) as JobBase;
        if (GetJob(instance.Id) != null)
        {
          throw new InvalidOperationException($"Double Job ID found: {instance.Id} | {instance.Name}");
        }
        _jobs.Add(instance);
        NAPI.Util.ConsoleOutput($"Loading job {instance.Name}");
      }
      NAPI.Util.ConsoleOutput($"Loaded {_jobs.Count} jobs");
    }

    public static JobBase GetJob(int id) => _jobs.Where(j => j.Id == id).FirstOrDefault();

    public static T GetJob<T>() where T : JobBase
    {
      return _jobs.Where(j => j.GetType() == typeof(T)).FirstOrDefault() as T;
    }

    public static List<JobBase> GetJobs() => _jobs.OrderBy(j => j.Id).ToList();

    public static Dictionary<Player, PlayerTimer> playerTimersJobVehicleRespawn = new Dictionary<Player, PlayerTimer>();

    [RemoteEvent("CLIENT:JobCenter_CancelJob")]
    public void CancelJobEvent(Player player)
    {
      using (var dbContext = new DatabaseContext())
      {
        User u = player.GetUser(dbContext);

        if (u == null) return;

        if (u.JobId == null)
        {
          ChatService.ErrorMessage(player, "Du hast momentan keinen Job, den du kündigen könntest.");
          return;
        }

        u.JobId = null;

        ChatService.SendMessage(player, "~y~[JOBCENTER]~s~ Du hast deinen Job erfolgreich gekündigt.");

        dbContext.SaveChanges();
      }
    }

    [RemoteEvent("CLIENT:JobCenter_AcceptJob")]
    public void AcceptJobEvent(Player player, int jobId)
    {
      using (var dbContext = new DatabaseContext())
      {
        User u = player.GetUser(dbContext);

        if (u == null) return;

        if (u.JobId != null)
        {
          ChatService.ErrorMessage(player, "Du musst deinen alten Job kündigen, bevor du einen neuen ausüben kannst");
          return;
        }

        JobBase job = JobManager.GetJob(jobId);

        if (job == null)
        {
          ChatService.ErrorMessage(player, "Bei der Job-Annahme ist ein Fehler aufgetretet: Dieser Job wurde nicht gefunden");
          return;
        }

        ChatService.SendMessage(player, $"~y~[JOBCENTER]~s~ Du hast erfolgreich deinen neuen Job: ~o~{job.Name}~s~ angenommen.");

        u.JobId = jobId;

        dbContext.SaveChanges();
      }
    }

    [RemoteEvent("CLIENT:JobManager_ShowJobMenu")]
    public void ShowJobMenuEvent(Player player)
    {
      User u = player.GetUser();

      if (u.JobId == null) return;

      JobBase job = GetJob(u.JobId.Value);

      dynamic data = null;

      if (job.Id == 1 && job.GetUsersInJob().Contains(player))
      {
        var taxiCalls = JobManager.GetJob<TaxiDriverJob>().TaxiContracts;
        if (!taxiCalls.Any(t => t.Driver?.Handle == player.Handle)) // Spieler in keiner aktiven Fahrt
        {
          data = new
          {
            job.Id,
            Status = 0,
            JobData = new
            {
              TaxiCalls = taxiCalls
                  .Where(t => t.Driver == null)
                  .Select(t => new
                  {
                    t.Name,
                    Distance = Math.Round(t.Position.DistanceTo(player.Position), 0)
                  })
                  .OrderBy(t => t.Distance)
            }
          };
        }
        else // Spieler in aktiver Fahrt
        {
          data = new
          {
            job.Id,
            Status = 1,
            JobData = new
            {
              taxiCalls.Where(t => t.Driver.Handle == player.Handle).First().Name
            }
          };
        }
      }
      //JobPoint nearJobPoint = PositionManager.JobPoints.Find(p => p.Position.DistanceTo(player.Position) <= 2);
      if (u.JobId == 2 || u.JobId == 3 || u.JobId == 4)
      {
        return;
      }

      var json = JsonConvert.SerializeObject(data);

      player.TriggerEvent("SERVER:Job_ShowJobMenu", job.Name, json);
    }

    [RemoteEvent("CLIENT:Job_StartJob")]
    public void StartJobEvent(Player player)
    {
      User u = player.GetUser();

      if (u.JobId == null) return;

      JobBase job = GetJob(u.JobId.Value);

      if (job.GetUsersInJob().Contains(player))
      {
        ChatService.ErrorMessage(player, "Du bist schon in deinem Job aktiv");
        return;
      }

      if (job.NeedVehicleToStart && !job.GetJobVehicles().Any(v => v.GetVehicle().Handle.Value == player.Vehicle?.Handle.Value))
      {
        ChatService.ErrorMessage(player, "Zum Start dieses Jobs musst du in einem Jobfahrzeug sein");
        return;
      }

      job.StartJob(player);
    }
    [ServerEvent(Event.PlayerExitVehicle)]
    public void JobManagerPlayerExitVehicle(Player player, Vehicle veh)
    {
      ServerVehicle sVeh = VehicleManager.GetServerVehicleFromVehicle(veh);
      User u = player.GetUser();

      if (u.JobId == null) return;

      JobBase job = GetJob(u.JobId.Value);
      if (veh.GetServerVehicle() is JobVehicle vehJ && player.VehicleSeat == 0)
      {
        if (vehJ.GetJob().GetUsersInJob().Contains(player))
        {
          if (u.JobId != 2)
          {
            if (!player.HasData("JobVehicleFrei") || player.GetData<bool>("JobVehicleFrei") == false)
            {
              player.SetData("DelayTime", 30000);
              veh.SetData("timerJobVehicleRespawn", true);
              player.SetData("LastVehicle", veh);
              player.SetData("LastSVehicle", sVeh);
              if (playerTimersJobVehicleRespawn.ContainsKey(player))
              {
                playerTimersJobVehicleRespawn[player].Stop();
              }
              PlayerTimer playerTimer = new PlayerTimer(player, veh, 30000);
              playerTimer.Elapsed += PlayerTimer_Elapsed;
              playerTimersJobVehicleRespawn[player] = playerTimer;
              player.SendChatMessage("~y~[JOB] ~w~Du hast das Fahrzeug verlassen,");
              player.SendChatMessage("~y~[JOB] ~w~Bist du nicht in 30 Sekunden zurück, ~r~wird der Job beendet!");
              //job.StopJob(player);
              return;
            }
            if (player.HasData("JobVehicleFrei") && player.GetData<bool>("JobVehicleFrei") == true)
            {
              player.SetData("JobVehicleFrei", false);
              return;
            }
          }
          if (u.JobId == 2)
          {
            if (!player.HasData("JobVehicleFrei") || player.GetData<bool>("JobVehicleFrei") == false)
            {
              player.SetData("DelayTime", 60000 * 5);
              veh.SetData("timerJobVehicleRespawn", true);
              player.SetData("LastVehicle", veh);
              player.SetData("LastSVehicle", sVeh);
              if (playerTimersJobVehicleRespawn.ContainsKey(player))
              {
                playerTimersJobVehicleRespawn[player].Stop();
              }
              PlayerTimer playerTimer = new PlayerTimer(player, veh, 60000 * 5);
              playerTimer.Elapsed += PlayerTimer_Elapsed;
              playerTimersJobVehicleRespawn[player] = playerTimer;
              //player.SendChatMessage("~y~[JOB] ~w~Du hast das Fahrzeug verlassen,");
              //player.SendChatMessage("~y~[JOB] ~w~Bist du nicht in 30 Sekunden zurück, ~r~wird der Job beendet!");
              //job.StopJob(player);
              return;
            }
            if (player.HasData("JobVehicleFrei") && player.GetData<bool>("JobVehicleFrei") == true)
            {
              player.SetData("JobVehicleFrei", false);
              return;
            }
          }
        }
      }
    }

    private void PlayerTimer_Elapsed(Player player, Vehicle veh)
    {
      NAPI.Task.Run(() =>
      {
        //Vehicle LastVehicle = player.GetData<Vehicle>("LastVehicle");
        Vehicle LastVehicle = veh;
        JobBase job = GetJob(player.GetUser().JobId ?? -1);
        if (LastVehicle.GetServerVehicle() is JobVehicle vehJ)
        {
          if (LastVehicle.GetData<bool>("timerJobVehicleRespawn") == true)
          {
            if (vehJ.GetJob().GetUsersInJob().Contains(player))
            {
              if (LastVehicle != null)
              {
                LastVehicle.ResetData("timerJobVehicleRespawn");
                ServerVehicle sVeh = VehicleManager.GetServerVehicleFromVehicle(LastVehicle);
                ServerVehicleExtensions.Spawn(sVeh, LastVehicle);
                job.StopJob(player);
                ChatService.SendMessage(player, $"~y~[JOB]~s~ Du hast deinen Job ~o~{job.Name}~s~ beendet.");
                CheckPointHandle.DeleteCheckpoints(player);
                if (!player.HasData("isDead") || player.GetData<bool>("isDead") == false)
                {
                  if (player.GetUser().JobId == 1)//Taxifahrer
                  {
                    player.TriggerEvent("CLIENT:stopFare");
                    player.Position = new Vector3(-628.598388671875, -2107.609130859375, 6.072586536407471);
                    player.Heading = (-171.50303649902344f);
                  }
                  if (player.GetUser().JobId == 2)//Müllmann
                  {
                    player.Position = new Vector3(485.4114685058594, -2173.25, 5.918273448944092);
                    player.Heading = (-15.922085762023926f);
                  }
                  if (player.GetUser().JobId == 3)//Pilot
                  {
                    if (!player.HasData("PilotenBase") || player.GetData<int>("PilotenBase") == 1) //Sandyshores
                    {
                      player.Position = new Vector3(1707.2711181640625, 3276.216064453125, 41.155494689941406);
                      player.Heading = (-154.65234375f);
                    }
                    if (player.HasData("PilotenBase") && player.GetData<int>("PilotenBase") == 2) //LS Airport
                    {
                      player.Position = new Vector3(-1622.48, -3151.58, 13);
                      player.Heading = (48.44f);
                    }
                  }
                  if (player.GetUser().JobId == 4)//Busfahrer
                  {
                    player.Position = new Vector3(-535.46, -2144.97, 5.95);
                    player.Heading = (57.03f);
                  }
                }
              }
            }
          }
        }
      });
    }
    [RemoteEvent("CLIENT:Job_StopJob")]
    public void StopJob(Player player)
    {
      User u = player.GetUser();

      if (u.JobId == null) return;

      JobBase job = GetJob(u.JobId.Value);

      if (!job.GetUsersInJob().Contains(player))
      {
        ChatService.ErrorMessage(player, "Du führst deinen Job momentan nicht aus");
        return;
      }

      if (job.NeedVehicleToStart && player.Vehicle != null)
      {
        VehicleStreaming.SetEngineState(player.Vehicle, false);
      }

      job.StopJob(player);
      if (player.GetUser().JobId == 1)//Taxifahrer
      {
        player.Position = new Vector3(-628.598388671875, -2107.609130859375, 6.072586536407471);
        player.Heading = (-171.50303649902344f);

      }
      if (player.GetUser().JobId == 2)//Müllmann
      {
        player.Position = new Vector3(485.4114685058594, -2173.25, 5.918273448944092);
        player.Heading = (-15.922085762023926f);
      }
      if (player.GetUser().JobId == 3)//Pilot
      {
        if (player.HasData("PilotenBase") || player.GetData<int>("PilotenBase") == 1) //Sandyshores
        {
          player.Position = new Vector3(1707.2711181640625, 3276.216064453125, 41.155494689941406);
          player.Heading = (-154.65234375f);
          player.GetUser().SetData("PilotenBase", 0);
        }
        if (player.HasData("PilotenBase") && player.GetData<int>("PilotenBase") == 2) //LS Airport
        {
          player.Position = new Vector3(-1622.48, -3151.58, 13);
          player.Heading = (48.44f);
          player.GetUser().SetData("PilotenBase", 0);
        }
      }
      if (player.GetUser().JobId == 4)//Busfahrer
      {
        player.Position = new Vector3(-535.46, -2144.97, 5.95);
        player.Heading = (57.03f);
      }
      Vehicle LastVehicle = player.GetData<Vehicle>("LastVehicle");
      if (LastVehicle != null)
      {
        LastVehicle.ResetData("timerJobVehicleRespawn");
        ServerVehicle sVeh = VehicleManager.GetServerVehicleFromVehicle(LastVehicle);
        ServerVehicleExtensions.Spawn(sVeh, LastVehicle);
      }
      if (playerTimersJobVehicleRespawn.ContainsKey(player))
      {
        playerTimersJobVehicleRespawn[player].Stop();
      }
      CheckPointHandle.DeleteCheckpoints(player);
      ChatService.SendMessage(player, $"~y~[JOB]~s~ Du hast deinen Job ~o~{job.Name}~s~ beendet.");
    }

    [ServerEvent(Event.PlayerEnterVehicle)]
    public void JobManagerPlayerEnterVehicle(Player player, Vehicle veh, sbyte seat)
    {
      ServerVehicle sVeh = veh.GetServerVehicle();
      //if (sVeh == null) return;
      if (seat != 0)
      {
        if (sVeh is JobVehicle jV && jV.JobId == 1) // Spieler steigt in Taxi ein
        {
          var taxiJob = JobManager.GetJob<TaxiDriverJob>();

          Player driver = veh.GetDriver();
          if (!driver.HasData("DriverPrice")) return;
          int taxiPrice = driver.GetData<int>("DriverPrice");
          float km = 0;
          if (!driver.HasData("FareKm")) { driver.SetData<float>("FareKm", km); }
          km = driver.GetData<float>("FareKm");
          if (driver.HasData("Passager")) return;
          driver.SetData<int>("Passager", player.GetUser().Id);
          driver.SetData<bool>("hasPassager", true);
          /*  using (var dbContext = new DatabaseContext())
            {
              int amount = (int)Math.Round(km * taxiPrice);
              User contractUser = player.GetUser(dbContext);
              contractUser.Handmoney -= amount;
              driver.GetUser(dbContext).Wage += amount;
              dbContext.SaveChanges();
              //contractUser.Player.TriggerEvent("SERVER:SET_HANDMONEY", contractUser.Handmoney);
            } */
          player.TriggerEvent("CLIENT:startCustomerFare", taxiPrice, km);

          var taxiContracts = taxiJob.TaxiContracts.Where(t => t.Name == player.Name);
          if (taxiContracts.Count() == 0) return;

          var contract = taxiContracts.First();
          taxiJob.TaxiContracts.Remove(contract);

          if (driver != null && contract.Driver != null && contract.Driver.Handle != veh.GetDriver().Handle)
          {
            ChatService.SendMessage(contract.Driver, $"!{{02FCFF}}{player.Name} ist in ein Taxi eingestiegen, der Auftrag wurde beendet.");
            ChatService.SendMessage(player, $"!{{02FCFF}}Du bist in ein Taxi eingestiegen, der Auftrag wurde beendet.");
          }
        }
      }
      JobBase job = GetJob(player.GetUser().JobId ?? -1);
      if (job?.GetUsersInJob()?.Contains(player) ?? false)
      {
        if (sVeh != null)
        {
          if (sVeh is JobVehicle JV)
          {
            if (player.GetUser().JobId == 3 || player.GetUser().JobId == 4)
            {
              if (seat == 0)
              {
                JobVehicle c = new JobVehicle();
                if (JV.GetJob().GetUsersInJob().Contains(player))
                {
                  if (!player.HasData("LastVehicle") || player.GetData<Vehicle>("LastVehicle") == null) return;
                  if (player.HasData("LastVehicle") && veh == player.GetData<Vehicle>("LastVehicle"))
                  {
                    veh.SetData("timerJobVehicleRespawn", false);
                    if (playerTimersJobVehicleRespawn.ContainsKey(player))
                    {
                      playerTimersJobVehicleRespawn[player].Stop();
                    }
                  }
                  else
                  {
                    if (player.GetData<bool>("HatRoute") == true)
                    {
                      StopJob(player);
                    }
                  }
                }
              }
              else
              {
                job.StopJob(player);
                ChatService.SendMessage(player, $"~y~[JOB]~s~ Du hast deinen Job ~o~{job.Name}~s~ beendet.");
                if (playerTimersJobVehicleRespawn.ContainsKey(player))
                {
                  playerTimersJobVehicleRespawn[player].Stop();
                }
                CheckPointHandle.DeleteCheckpoints(player);
                if (!player.HasData("LastVehicle") || player.GetData<Vehicle>("LastVehicle") == null) return;
                player.GetData<Vehicle>("LastVehicle").ResetData("timerJobVehicleRespawn");
                ServerVehicle nsSVeh = VehicleManager.GetServerVehicleFromVehicle(player.GetData<Vehicle>("LastVehicle"));
                ServerVehicleExtensions.Spawn(nsSVeh, player.GetData<Vehicle>("LastVehicle"));
                return;
              }
            }
            if (player.GetUser().JobId == 2)
            {
              JobVehicle c = new JobVehicle();
              if (JV.GetJob().GetUsersInJob().Contains(player))
              {
                if (!player.HasData("LastVehicle") || player.GetData<Vehicle>("LastVehicle") == null) return;
                if (player.HasData("LastVehicle") && veh == player.GetData<Vehicle>("LastVehicle"))
                {
                  veh.SetData("timerJobVehicleRespawn", false);
                  if (playerTimersJobVehicleRespawn.ContainsKey(player))
                  {
                    playerTimersJobVehicleRespawn[player].Stop();
                  }
                }
                else
                {
                  if (player.GetData<bool>("HatRoute") == true)
                  {
                    StopJob(player);
                  }
                }
              }
            }
          }
          else
          {
            job.StopJob(player);
            ChatService.SendMessage(player, $"~y~[JOB]~s~ Du hast deinen Job ~o~{job.Name}~s~ beendet.");
            if (playerTimersJobVehicleRespawn.ContainsKey(player))
            {
              playerTimersJobVehicleRespawn[player].Stop();
            }
            CheckPointHandle.DeleteCheckpoints(player);
            if (!player.HasData("LastVehicle") || player.GetData<Vehicle>("LastVehicle") == null) return;
            player.GetData<Vehicle>("LastVehicle").ResetData("timerJobVehicleRespawn");
            ServerVehicle nsSVeh = VehicleManager.GetServerVehicleFromVehicle(player.GetData<Vehicle>("LastVehicle"));
            ServerVehicleExtensions.Spawn(nsSVeh, player.GetData<Vehicle>("LastVehicle"));
          }
        }
        else if (sVeh! is JobVehicle || veh != null)
        {
          job.StopJob(player);
          ChatService.SendMessage(player, $"~y~[JOB]~s~ Du hast deinen Job ~o~{job.Name}~s~ beendet.");
          if (playerTimersJobVehicleRespawn.ContainsKey(player))
          {
            playerTimersJobVehicleRespawn[player].Stop();
          }
          CheckPointHandle.DeleteCheckpoints(player);
          if (!player.HasData("LastVehicle") || player.GetData<Vehicle>("LastVehicle") == null) return;
          player.GetData<Vehicle>("LastVehicle").ResetData("timerJobVehicleRespawn");
          ServerVehicle nsSVeh = VehicleManager.GetServerVehicleFromVehicle(player.GetData<Vehicle>("LastVehicle"));
          ServerVehicleExtensions.Spawn(nsSVeh, player.GetData<Vehicle>("LastVehicle"));
        }
        else if (sVeh is JobVehicle JV)
        {
          if (JV.JobId != player.GetUser().JobId)
          {
            job.StopJob(player);
            ChatService.SendMessage(player, $"~y~[JOB]~s~ Du hast deinen Job ~o~{job.Name}~s~ beendet.");
            if (playerTimersJobVehicleRespawn.ContainsKey(player))
            {
              playerTimersJobVehicleRespawn[player].Stop();
            }
            CheckPointHandle.DeleteCheckpoints(player);
            if (!player.HasData("LastVehicle") || player.GetData<Vehicle>("LastVehicle") == null) return;
            player.GetData<Vehicle>("LastVehicle").ResetData("timerJobVehicleRespawn");
            ServerVehicle nsSVeh = VehicleManager.GetServerVehicleFromVehicle(player.GetData<Vehicle>("LastVehicle"));
            ServerVehicleExtensions.Spawn(nsSVeh, player.GetData<Vehicle>("LastVehicle"));
          }
        }
      }
    }

    [ServerEvent(Event.PlayerEnterVehicleAttempt)]
    private void JobManagerEnterVehicleAttempt(Player player, Vehicle vehicle, sbyte seat)
    {
      if (JobManager.GetJob<RefuseCollectorJob>().GetUsersInJob().Contains(player)) { JobManager.GetJob<RefuseCollectorJob>().MuellmannOnPlayerEnterVehicle(player, vehicle, seat); }
    }

    [ServerEvent(Event.PlayerDeath)]
    private void JobManagerOnPlayerDeath(Player player, Player killer, uint reason)
    {
      if (JobManager.GetJob<RefuseCollectorJob>().GetUsersInJob().Contains(player)) { JobManager.GetJob<RefuseCollectorJob>().MuellmannOnPlayerDeath(player); }
    }

    [ServerEvent(Event.PlayerDisconnected)]
    private void JobManagerOnPlayerDisconnect(Player player, DisconnectionType type, string reason)
    {
      if (JobManager.GetJob<RefuseCollectorJob>().GetUsersInJob().Contains(player)) { JobManager.GetJob<RefuseCollectorJob>().MuellmannOnPlayerDc(player); }
    }

    [ServerEvent(Event.PlayerExitVehicle)]
    public void JobManagerPlayerExitVehicle2(Player player, Vehicle veh)
    {
      ServerVehicle sVeh = veh.GetServerVehicle();
      if (sVeh == null) return;
      if (sVeh is JobVehicle jV && jV.JobId == 1) // Spieler steigt vom Taxi aus
      {
        var taxiJob = JobManager.GetJob<TaxiDriverJob>();
        if (veh.Occupants.Count == 0) return;
        Player driver = veh.GetDriver();
        if (driver == null) return;
        if (player.GetUser().Id != driver.GetData<int>("Passager")) { player.TriggerEvent("CLIENT:cancelFare"); return; }
        player.TriggerEvent("CLIENT:cancelFareCustomer");
        driver.TriggerEvent("CLIENT:resetFareClock");
        driver.ResetData("Passager");
        driver.ResetData("hasPassager");
        driver.SetData<float>("FareKm", 0);
        driver.TriggerEvent("CLIENT:cancelFare");
        driver.TriggerEvent("CLIENT:startFare");

        foreach (Player occupant in veh.Occupants)
        {
          if (occupant == driver) continue;
          occupant.WarpOutOfVehicle();
        }
      }
    }

    [RemoteEvent("CLIENT:JobManager_TaxiJob_AcceptCall")]
    public void TaxiJobAcceptCall(Player player, string name)
    {
      var taxiJob = JobManager.GetJob<TaxiDriverJob>();

      if (!taxiJob.TaxiContracts.Any(t => t.Name == name))
      {
        ChatService.ErrorMessage(player, "Dieser Spieler hat kein Taxi gerufen oder der Auftrag ist nicht mehr aktuell");
        return;
      }

      var job = taxiJob.TaxiContracts.Where(t => t.Name == name).First();

      var target = PlayerService.GetPlayerByNameOrId(name);
      if (target == null)
      {
        taxiJob.TaxiContracts.Remove(job);
        ChatService.ErrorMessage(player, "Dieser Spieler ist nicht mehr online");
        return;
      }

      job.Driver = player;

      player.TriggerEvent("SERVER:Util_setWaypoint", target.Position.X, target.Position.Y);
      player.SetData<bool>("hasPassager", true);

      ChatService.SendMessage(target, $"!{{02FCFF}}Dein Auftrag wurde von {player.Name} angenommen. Warte an deiner aktuellen Position.");
      ChatService.SendMessage(target, $"!{{02FCFF}}Für die Anfahrt fallen zusätzlich Kosten auf.");
      ChatService.SendMessage(player, $"!{{02FCFF}}Du hast den Auftrag von {name} angenommen. Hole ihn nun ab.");
    }
  }
}
