using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CarManagerV3
{
    // Could be made non-static / non-singleton if multiple collections are needed in the future. Not likely though.
    /// <summary>
    /// The <c>StateManager</c> class is responsible for managing the state of the car collection, including adding, removing, updating, and retrieving cars.
    /// Fully static / singleton at the moment, as only one collection is needed.
    /// </summary>
    internal class StateManager
    {
        // Initialize global static list of cars
        static List<Car> cars = new List<Car>();
        // Initialize default file path for car data.
        // TODO: If no recent file paths are found, prompt user to select a file path instead of using a hardcoded default in the program folder.
        static string filePath = "cars.csv";

        /// <summary>
        /// Gets a car by its identifier.
        /// </summary>
        /// <param name="id">The identifier.</param>
        /// <returns>
        /// A <see cref="Car"/> object if found; otherwise, null.
        /// </returns>
        public static Car GetCarById(int id)
        {
            cars = SafeManager.ReadCars(filePath);
            return cars.FirstOrDefault(c => c.Id == id);
        }

        /// <summary>
        /// Public getter and setter for the cars list. Used to have better control over the list.
        /// </summary>
        /// <value>
        /// The cars.
        /// </value>
        public static List<Car> Cars { get { return cars; } set { cars = value; } }

        /// <summary>
        /// Adds a car to the collection.
        /// </summary>
        /// <param name="car">The car to add.</param>
        public static void AddCar(Car car)
        {
            cars = SafeManager.ReadCars(filePath);
            cars.Add(car);
            SafeManager.SaveCars(filePath, cars);
        }

        /// <summary>
        /// Removes a car from the collection.
        /// </summary>
        /// <param name="car">The car to remove.</param>
        public static void RemoveCar(Car car)
        {
            cars = SafeManager.ReadCars(filePath);
            Car existingCar = GetCarById(car.Id);
            if (existingCar == null) return;
            cars.Remove(existingCar);
            SafeManager.SaveCars(filePath, cars);
        }

        /// <summary>
        /// Updates a car in the collection. Identifies itself by its Id.
        /// </summary>
        /// <remarks>
        /// If the car's Id has changed during editing, this will not work correctly. Keep Id immutable!
        /// </remarks>
        /// <param name="car">The car to update.</param>
        public static void UpdateCar(Car car)
        {
            Car existingCar = GetCarById(car.Id);
            if (existingCar != null)
            {
                int index = cars.IndexOf(existingCar);
                cars[index] = car;
                Console.WriteLine("Updated car: " + existingCar.Id);
                SafeManager.SaveCars(filePath, cars);
            }
        }

        /// <summary>
        /// Creates a new car and adds it to the collection.
        /// </summary>
        /// <param name="make">The make.</param>
        /// <param name="model">The model.</param>
        /// <param name="year">The year.</param>
        /// <param name="color">The color.</param>
        /// <param name="mileage">The mileage.</param>
        /// <param name="price">The price.</param>
        /// <returns>
        /// The newly created <see cref="Car"/> object.
        /// </returns>
        public static Car CreateCar(string make, string model, int year, string color, int mileage, decimal price)
        {
            cars = SafeManager.ReadCars(filePath);
            int newId = cars.Count > 0 ? cars.Max(c => c.Id) + 1 : 1;
            Car newCar = new Car(newId, make, model, year, color, mileage, price);
            AddCar(newCar);
            return newCar;
        }

        /// <summary>
        /// Sets the file path used for saving and loading car data.
        /// Called when user selects a new file path.
        /// </summary>
        /// <param name="path">The path.</param>
        public static void setFilePath(string path)
        {
            filePath = path;
        }
    }
}
