using System; using System.Collections.Generic; using System.IO; using System.Linq; using Code.Infrastructure.EventBus; using Cysharp.Threading.Tasks; using Newtonsoft.Json; using UnityEngine; namespace Code.Calendar.DataStructures { public interface ITaskService { void AddTask(Task task); void DeleteTask(Task task); List GetByPlant(Guid plantId); List GetTasks(); List GetByDate(DateTime date); void EditTask(Guid guid, Task newTask); } public class TaskService : IDisposable, ITaskService { private readonly EventBus _eventBus; private List _tasks; public TaskService(EventBus eventBus) { _eventBus = eventBus; LoadJsonTasks().Forget(); } private async UniTaskVoid LoadJsonTasks() { var path = Path.Combine(Application.persistentDataPath, "Tasks.json"); if (File.Exists(path)) { using StreamReader reader = new(path); _tasks = JsonConvert.DeserializeObject>(await reader.ReadToEndAsync()) ?? new List(); } else { await using (File.Create(path)) { } _tasks = new (); } _eventBus.RaiseEvent(x => x.TasksLoaded()); } private bool _inAction, _reUseRequest; private async UniTaskVoid SaveJsonTasks() { if (_inAction) { _reUseRequest = true; return; } _inAction = true; var json = JsonConvert.SerializeObject(_tasks, Formatting.Indented); await using StreamWriter writer = new(Path.Combine(Application.persistentDataPath, "Tasks.json")); await writer.WriteAsync(json).AsUniTask(); _inAction = false; if (!_reUseRequest) _eventBus.RaiseEvent(x => x.TasksSaved()); else SaveJsonTasks().Forget(); } public void AddTask(Task task) { task.Id = Guid.NewGuid(); _tasks.Add(task); SaveJsonTasks().Forget(); } public void EditTask(Guid guid, Task newTask) { _tasks[_tasks.FindIndex(x => x.Id == guid)] = newTask; SaveJsonTasks().Forget(); } public void DeleteTask(Task task) { _tasks.Remove(task); SaveJsonTasks().Forget(); } public List GetByPlant(Guid plantId) => _tasks.Where(x => x.PlantId == plantId).ToList(); public List GetByDate(DateTime date) { var byDay = _tasks .Where(x => x.Date.Day == date.Day) .ToList(); var periodicOnes = _tasks .Where(x => x.IsPeriodic && x.Date.Day + new TimeSpan(0, x.PeriodicInterval, 0).Days == date.Day) .ToList(); byDay.AddRange(periodicOnes); return byDay; } public List GetTasks() => _tasks; public void Dispose() { SaveJsonTasks().Forget(); } } public interface ITaskServiceHandle : IGlobalSubscriber { void TasksLoaded(); void TasksSaved(); } }