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

namespace CarManagerV3
{
    /// <summary>
    /// The <c>ImageManager</c> class is responsible for managing car images, including fetching and storing them locally.
    /// </summary>
    internal class ImageManager
    {
        /// <summary>
        /// Initializes the image folder by creating it if it does not exist.
        /// </summary>
        public static void InitializeImageFolder()
        {
            string path = "images";
            
            if (!System.IO.Directory.Exists(path))
            {
                System.IO.Directory.CreateDirectory(path);
            }

            // Do not catch here. If we cannot create our images folder, the program wont work.
            
        }

        /// <summary>
        /// Generates the image path for a given car based on its attributes.
        /// </summary>
        /// <param name="car">The car.</param>
        /// <returns>The image path for this Car.</returns>
        public static string GetImagePath(Car car)
        {
            string basePath = "images/";
            string fileName = $"{car.Make}_{car.Model}_{car.Year}_{car.Color}.png";
            return basePath + fileName;
        }

        /// <summary>
        /// Gets the image for a given car, fetching it if necessary.
        /// </summary>
        /// <param name="car">The car.</param>
        /// <returns>The <see cref="Image"/> object for the car.</returns>
        public static Image GetImage(Car car)
        {
            InitializeImageFolder();
            FetchImage(car);
            string path = GetImagePath(car);
            // does image exist?
            try
            {
                if (System.IO.File.Exists(path))
                {
                    return Image.FromFile(path);
                }
            }
            catch (Exception ex)
            {
                Console.Error.WriteLine($"Error loading image: {ex.Message}");
            }
            try
            {
                return Image.FromFile("images/no_image_available.png");
            }
            catch (Exception ex)
            {
                Console.Error.WriteLine($"Error loading fallback image: {ex.Message}");
                return null;
            }
        }

        /// <summary>
        /// Fetches an image for a Car from https://cdn.imagin.studio/getimage if it does not already exist locally and saves it to images/<c>Make_Model_Year_Color.webp</>.
        /// If the image cannot be fetched, a placeholder image is used instead.
        /// Uses example customer id "hrjavascript-mastery", because they wouldn't give me one. Stole this from a tutorial page. :)
        /// </summary>
        /// <param name="car">The car.</param>
        public static void FetchImage(Car car)
        {
            // Fetch the image from https://cdn.imagin.studio/getimage and save it to images/Make_Model_Year.webp
            // use params like this: ?customer=hrjavascript-mastery&zoomType=fullscreen&make={make}&modelFamily={model}&modelYear={year}&angle=front&paintDescription={color}&fileType=png
            // check if the image already exists
            string path = GetImagePath(car);
            if (System.IO.File.Exists(path))
            {
                return;
            }
            string url = $"https://cdn.imagin.studio/getimage?customer=hrjavascript-mastery&zoomType=fullscreen&make={car.Make}&modelFamily={car.Model}&modelYear={car.Year}&angle=front&paintDescription={car.Color}&fileType=png";
            //add Referer header to avoid 403 error
            using (var client = new System.Net.WebClient())
            {
                client.Headers.Add("Referer", "http://localhost");
                try
                {
                    client.DownloadFile(url, path);
                }
                catch 
                {
                    // if error, use fallback image no_image_available.png
                    System.IO.File.Copy("images/no_image_available.png", path);
                }
            }

        }
    }
}
