using Microsoft.Data.Sqlite;
using System;
using System.IO;
using System.Collections.Generic;
using AquaCare.Model;

namespace AquaCare.Persistence
{
    public class Datenbank
    {
        private static readonly string PersistencePath = Path.GetDirectoryName(
            typeof(Datenbank).Assembly.Location) ?? throw new InvalidOperationException("Assembly location not found");
        
        private static readonly string DbPath = Path.Combine(
            PersistencePath, 
            "..", "..", "..", "..",
            "AquaCare.Persistence",
            "AquaCareDatenbank.db");

        private string ConnectionString => $"Data Source={DbPath}";

        public Datenbank()
        {
            EnsureDatabaseExists();
        }

        private void EnsureDatabaseExists()
        {
            var directory = Path.GetDirectoryName(DbPath);
            if (directory != null && !Directory.Exists(directory))
            {
                Directory.CreateDirectory(directory);
            }

            if (!File.Exists(DbPath))
            {
                InitializeNewDatabase();
            }
        }

        private void InitializeNewDatabase()
        {
            using var connection = new SqliteConnection(ConnectionString);
            connection.Open();
            
            var command = connection.CreateCommand();
            command.CommandText = @"
                CREATE TABLE IF NOT EXISTS Werte (
                    Datum DATETIME PRIMARY KEY,
                    Gefuettert BOOLEAN,
                    FilterReinigen BOOLEAN,
                    WasserWechseln BOOLEAN,
                    Temperatur REAL,
                    PhWert REAL,
                    Nitrat REAL,
                    Ammoniak REAL
                )";
            command.ExecuteNonQuery();
        }

        public void AddValue(Werte wert)
        {
            using var connection = new SqliteConnection(ConnectionString);
            connection.Open();
            
            var command = connection.CreateCommand();
            command.CommandText = @"
                INSERT INTO Werte (
                    Datum, Gefuettert, FilterReinigen, WasserWechseln, 
                    Temperatur, PhWert, Nitrat, Ammoniak
                ) VALUES (
                    @Datum, @Gefuettert, @FilterReinigen, @WasserWechseln,
                    @Temperatur, @PhWert, @Nitrat, @Ammoniak
                )";

            command.Parameters.AddWithValue("@Datum", wert.Datum);
            command.Parameters.AddWithValue("@Gefuettert", wert.Gefuettert);
            command.Parameters.AddWithValue("@FilterReinigen", wert.FilterReinigen);
            command.Parameters.AddWithValue("@WasserWechseln", wert.WasserWechseln);
            command.Parameters.AddWithValue("@Temperatur", wert.Temperatur);
            command.Parameters.AddWithValue("@PhWert", wert.PhWert);
            command.Parameters.AddWithValue("@Nitrat", wert.Nitrat);
            command.Parameters.AddWithValue("@Ammoniak", wert.Ammoniak);

            command.ExecuteNonQuery();
        }

        public List<Werte> GetValuesAsObjects()
        {
            var werte = new List<Werte>();
            using var connection = new SqliteConnection(ConnectionString);
            connection.Open();

            var command = connection.CreateCommand();
            command.CommandText = "SELECT * FROM Werte ORDER BY Datum DESC";

            using var reader = command.ExecuteReader();
            while (reader.Read())
            {
                werte.Add(new Werte
                {
                    Datum = reader.GetDateTime(0),
                    Gefuettert = reader.GetBoolean(1),
                    FilterReinigen = reader.GetBoolean(2),
                    WasserWechseln = reader.GetBoolean(3),
                    Temperatur = reader.GetDouble(4),
                    PhWert = reader.GetDouble(5),
                    Nitrat = reader.GetDouble(6),
                    Ammoniak = reader.GetDouble(7)
                });
            }

            return werte;
        }
    }
}