using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace CarManagerV2
{
    public partial class MainForm : Form
    {
        List<Car> cars = new List<Car>();

        public MainForm()
        {
            InitializeComponent();
            SafeManager.InitializeFile("cars.csv");
            List<Car> _cars = SafeManager.ReadCars("cars.csv");
            
            refreshCars(_cars);

        }

        private async void refreshCars(List<Car> _cars, bool updateGlobal = true)
        {

            // Sort by Car.Order. If equal, sort by ID
            _cars = _cars.Count > 0 ? _cars.OrderBy(c => c.Order).ThenBy(c => c.Id).ToList() : _cars;

            if (updateGlobal)
            {
                cars = _cars;
            }

            foreach (Car car in _cars)
            {
                // not in list? add it
                bool isNew = flpCars.Controls.OfType<CarCard>().All(c => c.Car.Id != car.Id);
                // existing but changed? update it
                CarCard card = new CarCard();
                if (!isNew)
                {
                    CarCard existing = flpCars.Controls.OfType<CarCard>().First(c => c.Car.Id == car.Id);
                    Car existingCar = existing.Car;
                    if (existing == null)
                    {
                        Console.Error.WriteLine($"[L] Error: Existing car card not found for car ID: {car.Id}");
                        continue;
                    }
                    // compare details
                    Console.WriteLine($"[L] Checking car: {car.Id} | Car Color: {car.Color} | Ex Color: {existingCar.Color}");
                    if (existingCar.IsChanged(car))
                    {
                        Console.WriteLine($"[L] Updating car: {car.Id}");
                        // changes
                        card = existing;

                    }
                    else
                    {
                        // no changes
                        Console.WriteLine($"[L] No changes for car: {car.Id}");
                        flpCars.Controls.SetChildIndex(existing, _cars.IndexOf(car));
                        continue;
                    }
                }

                card.CarName = $"{car.Make} {car.Model}";
                card.CarDetails = $"{car.Year}, {car.Mileage} km, ${car.Price}";
                card.Car = car.Clone();
                card.LoadImage();
                // clear existing event handlers to prevent multiple subscriptions
                card.ClearCardClickedHandlers();
                card.CardClicked += (s, e) =>
                {
                    Console.WriteLine($"Card clicked: {car.Id}");
                    CarDetailsForm detailsForm = new CarDetailsForm(car);
                    detailsForm.FormClosed += async (s2, e2) =>
                    {
                        Console.WriteLine("Car details form closed.");
                        // refresh cars
                        Console.WriteLine("Refreshing cars...");
                        List<Car> __cars = await Task.Run(() => SafeManager.ReadCars("cars.csv"));
                        if(tbxSearch.Text.Length > 0)
                        {
                            Console.WriteLine("Search box has text, applying search filter.");
                            cars = __cars;
                            searchList(tbxSearch.Text);
                            return;
                        }
                        refreshCars(__cars);
                        
                    };
                    detailsForm.ShowDialog();
                };
                
                if (isNew)
                {
                    flpCars.Controls.Add(card);
                }
                flpCars.Controls.SetChildIndex(card, _cars.IndexOf(car));
            }

            // Remove cards that are no longer in _cars
            var carIds = _cars.Select(c => c.Id).ToList();
            var cardsToRemove = flpCars.Controls.OfType<CarCard>().Where(c => !carIds.Contains(c.Car.Id)).ToList();
            foreach (var card in cardsToRemove)
            {
                flpCars.Controls.Remove(card);
            }

            flpCars.Refresh();
            flpCars.Invalidate();
            flpCars.Update();
        }


        private void btnNewCar_Click(object sender, EventArgs e)
        {
            Car foocar = StateManager.CreateCar("New", "Car", 2020, "White", 0, 20000);
            CarDetailsForm detailsForm = new CarDetailsForm(foocar);
            detailsForm.FormClosed += (s2, e2) =>
            {
                // refresh cars
                Console.WriteLine("Refreshing cars...");
                List<Car> cars_ = SafeManager.ReadCars("cars.csv");
                refreshCars(cars_, false);
            };
            detailsForm.ShowDialog();
        }

        List<Car> filterCarsByQuery(string query)
        {
            List<Car> results = new List<Car>();
            foreach (Car car in cars)
            {
                if (car.Make.ToLower().Contains(query.ToLower()) || car.Model.ToLower().Contains(query.ToLower()) || car.Year.ToString().Contains(query) || car.Mileage.ToString().Contains(query) || car.Price.ToString().Contains(query))
                {
                    results.Add(car);
                }
            }
            return results;
        }

        void searchList(string query)
        {
            List<Car> results = filterCarsByQuery(query);
            refreshCars(results, false);
        }

        private async void tbxSearch_TextChanged(object sender, EventArgs e)
        {
            string query = tbxSearch.Text;
            await Task.Delay(100); // debounce
            if(query != tbxSearch.Text) return; // text changed during delay
            //flpCars.Controls.Clear();
            if (string.IsNullOrWhiteSpace(query))
            {
                refreshCars(cars);
            }
            else
            {
                searchList(query);
            }
        }
    }
}
