using PlantBox.Client.Models;
using PlantBox.Shared.Communication;
using PlantBox.Shared.Communication.Commands;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Net.Sockets;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;

namespace PlantBox.Client.ViewModels
{
    class HomeViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        private ObservableCollection<PlantInfo> _plants;
        public ObservableCollection<PlantInfo> Plants
        {
            get => _plants;
            set
            {
                if (value != _plants)
                {
                    _plants = value;
                    OnPropertyChanged();
                }
            }
        }

        public HomeViewModel()
        {
            Plants = LoadPlants(App.Settings.IDs);
        }

        public ObservableCollection<PlantInfo> LoadPlants(IEnumerable<ulong> ids)
        {
            if (App.Settings.BrokerIP == "")
            {
                return new ObservableCollection<PlantInfo>();
            }

            IEnumerable<PlantInfo> infos = GetPlantInfos(ids);

            return new ObservableCollection<PlantInfo>(infos);
        }

        private IEnumerable<PlantInfo> GetPlantInfos(IEnumerable<ulong> ids)
        {
            using (var client = new TcpClient(App.Settings.BrokerIP, Connection.TCP_CLIENT_PORT))
            using (var stream = new CommandStream(client.GetStream()))
            {

                foreach (ulong id in ids)
                {
                    stream.Send(new InfoRequest().ToCommandPacket(id));
                    (_, var responseInfo) = stream.Receive<InfoResponse>();

                    yield return new PlantInfo
                    (
                        responseInfo.Name,
                        id,
                        responseInfo.Type,
                        responseInfo.State,
                        responseInfo.HumidityMin,
                        responseInfo.HumidityMax,
                        responseInfo.LuminosityMin,
                        responseInfo.LuminosityMax,
                        responseInfo.TemperatureMin,
                        responseInfo.TemperatureMax
                    );
                }
            }
        }

        protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
