using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.SqlClient;
using System.Data;
using MySql.Data.MySqlClient;
using System.IO;

namespace DataPoolingService
{
    class DALscada
    {
        ConnectionClass ConnectionClass = new ConnectionClass();
        Logger Logger = new Logger();
        SqlCommand sqlCommand = new SqlCommand();
        DataTable dataTable = new DataTable();
        SqlDataAdapter SqlDataAdapter = new SqlDataAdapter();

        MySqlCommand MySqlCommand = new MySqlCommand();
        Boolean check = false;
        private static int  site_id, uom_id, meter_id;
        private static string meter_no;
        private static double units;
        private static DateTime date;
        private static string reading_method;

        public void GetAndInsertData()
        {
            try
            {
                ConnectionClass.OpenConnection();
                // string query = "Select b.reading_method,a.* from utility_sub_meter_reading a ,utility_sub_meter b  WHERE CONVERT(date, date) = '2025-01-19' and a.meter_id = b.meter_id";
                 string query = "Select b.reading_method,a.* from utility_sub_meter_reading a ,utility_sub_meter b  WHERE CONVERT(date, date) = CONVERT(date, GETDATE()) and a.meter_id = b.meter_id";

                sqlCommand = new SqlCommand(query, ConnectionClass.connection);
                SqlDataAdapter.SelectCommand = sqlCommand;
                dataTable = new DataTable();
                SqlDataAdapter.Fill(dataTable);
                ConnectionClass.CloseConnection();

                if (dataTable.Rows.Count > 0)
                {
                    InsertingData(dataTable);
                }
                else
                {
                    Logger.NotFoundLog();
                }
            }
            catch (Exception ex)
            {
                ConnectionClass.CloseConnection();
            }

        }
        private bool CheckRecordExist()
        {
            try
            {
                ConnectionClass.OpenConnectionMysql();

                DataRowCollection rows = dataTable.Rows; // Get the collection of rows from the DataTable

                string query = "SELECT * FROM utility_sub_meter_reading WHERE DATE(reading_timestamp) = CURDATE() limit 1";
                //string query = "Select * from utility_sub_meter_reading a where date(a.reading_timestamp) = '2024-04-05'";

                MySqlCommand mySqlCommand = new MySqlCommand(query, ConnectionClass.MySqlConnection);

                using (MySqlDataReader dataReader = mySqlCommand.ExecuteReader())
                {
                    // Check if any rows are returned by the query
                    if (dataReader.HasRows)
                    {
                        check = true;
                        return true; // Records exist for the current date
                    }
                }
                check = false;
                return false; // No records found for the current date
            }
            catch (Exception ex)
            {
                // Log or handle the exception appropriately
                Console.WriteLine("Error: " + ex.Message);
                return false; // Or return true/false based on your error handling strategy
            }
            finally
            {
                ConnectionClass.CloseConnectionMysql(); // Ensure connection is closed
            }
        }
        private void InsertingData(DataTable dt)
        {
            try
            {
                Logger.StartLogEvent();
                ConnectionClass.OpenConnectionMysql();

                foreach (DataRow dr in dt.Rows)
                {
                    meter_id = Convert.ToInt32(dr["meter_id"]);
                    meter_no = (dr["meter_number"].ToString());
                    site_id = Convert.ToInt32(dr["site_id"]);
                    uom_id = Convert.ToInt32(dr["uom_id"]);
                    units = Convert.ToDouble(dr["units"]);
                    date = Convert.ToDateTime(dr["date"]);

                    string mySqlDefaultFormat = date.ToString("yyyy-MM-dd HH:mm:ss");

                    // Check if the record already exists
                    string checkQuery = "SELECT COUNT(*) FROM utility_sub_meter_reading " +
                                        "WHERE meter_id = @meter_id  AND " +
                                        "DATE(reading_timestamp) = DATE(@date)";

                    using (MySqlCommand checkCmd = new MySqlCommand(checkQuery, ConnectionClass.MySqlConnection))
                    {
                        checkCmd.Parameters.AddWithValue("@meter_id", meter_id);
                        checkCmd.Parameters.AddWithValue("@site_id", site_id);
                        checkCmd.Parameters.AddWithValue("@date", mySqlDefaultFormat);

                        int recordExists = Convert.ToInt32(checkCmd.ExecuteScalar());

                        if (recordExists == 0) // If the record does not exist
                        {
                            reading_method = dr["reading_method"].ToString();
                            string insertQuery;
                            if (reading_method == "CONSUMPTION")
                            {
                                insertQuery = "INSERT INTO utility_sub_meter_reading " +
                                                "(meter_id, meter_number, site_id, uom_id, reading_diff, reading_timestamp) " +
                                                "VALUES (@meter_id, @meter_no, @site_id, @uom_id, @units, @date)";

                            }
                            else
                            {

                                insertQuery = "INSERT INTO utility_sub_meter_reading " +
                                                 "(meter_id, meter_number, site_id, uom_id, reading, reading_timestamp) " +
                                                 "VALUES (@meter_id, @meter_no, @site_id, @uom_id, @units, @date)";

                            }

                          

                            using (MySqlCommand insertCmd = new MySqlCommand(insertQuery, ConnectionClass.MySqlConnection))
                            {
                                insertCmd.Parameters.AddWithValue("@meter_id", meter_id);
                                insertCmd.Parameters.AddWithValue("@meter_no", meter_no);
                                insertCmd.Parameters.AddWithValue("@site_id", site_id);
                                insertCmd.Parameters.AddWithValue("@uom_id", uom_id);
                                insertCmd.Parameters.AddWithValue("@units", units);
                                insertCmd.Parameters.AddWithValue("@date", mySqlDefaultFormat);

                                // Execute the query
                                int rowsAffected = insertCmd.ExecuteNonQuery();

                                if (rowsAffected == 1)
                                {
                                    // Log the successful insert to the text file
                                    Logger.RowSuccessLog(meter_no, site_id, units);
                                }
                                else
                                {
                                    // Log the failed insert to the text file
                                    Logger.RowFailedLog(meter_no, site_id, units);
                                }
                            }
                        }
                        else
                        {
                            // Log if record already exists
                            Logger.RowAlreadyExistsLog(meter_no, site_id, units);
                        }
                    }
                }

                ConnectionClass.CloseConnectionMysql();
                Logger.EndLogEvent();
            }
            catch (Exception ex)
            {
                // Handle any exceptions that may occur during execution.
                //Logger.ErrorLog(ex);
                ConnectionClass.CloseConnectionMysql();
            }
        }
        private string GetDate()
        {
            DateTime currentDateTime = DateTime.Now;
            // Convert to MySQL's default format 'YYYY-MM-DD HH:MM:SS'
            string mySqlDefaultFormat = currentDateTime.ToString("yyyy-MM-dd HH:mm:ss");
            return mySqlDefaultFormat;
        }
        public void InsertReadingDiff()
        {
            if (check == false)
            {
                dataTable = new DataTable();

                ConnectionClass.OpenConnectionMysql();
                string query = @"SELECT 
                    b.meter_number,
                    IF(b.units = 0, 0, b.units) AS units_yesterday,
                    c.units AS units_today,
                    DATE(b.reading_timestamp) AS date_yesterday,
                    DATE(c.reading_timestamp) AS date_today
                FROM 
                    utility_sub_meter_reading AS b
                JOIN  
                    utility_sub_meter_reading AS c
                    ON DATE(b.reading_timestamp) = DATE(c.reading_timestamp) - INTERVAL 1 DAY
                    AND b.meter_number = c.meter_number
                JOIN
                    utility_sub_meter sm
                    ON c.meter_number = sm.meter_number
                WHERE 
                    DATE(c.reading_timestamp) = CURDATE()
                    AND sm.utility_type = 'SOLAR'";
                MySqlCommand = new MySqlCommand(query, ConnectionClass.MySqlConnection);
                MySqlDataAdapter mySqlDataAdapter = new MySqlDataAdapter();
                mySqlDataAdapter.SelectCommand = MySqlCommand; //           
                mySqlDataAdapter.Fill(dataTable); // 

                if (dataTable.Rows.Count > 0)
                {
                    // ConnectionClass.OpenConnection();

                    // Loop through the rows of the DataTable
                    foreach (DataRow row in dataTable.Rows)
                    {
                        // Calculate the difference between units_today and units_yesterday
                        double unitsToday = Convert.ToDouble(row["units_today"]);
                        double unitsYesterday = Convert.ToDouble(row["units_yesterday"]);
                        double readingDiff = unitsToday - unitsYesterday;

                        // Update the utility_sub_meter_reading table
                        string updateQuery = @"UPDATE utility_sub_meter_reading 
                           SET reading_diff = @reading_diff 
                           WHERE meter_number = @meter_number 
                           AND DATE(reading_timestamp) = @date_today";

                        MySqlCommand updateCommand = new MySqlCommand(updateQuery, ConnectionClass.MySqlConnection);
                        updateCommand.Parameters.AddWithValue("@reading_diff", readingDiff);
                        updateCommand.Parameters.AddWithValue("@meter_number", row["meter_number"]);
                        updateCommand.Parameters.AddWithValue("@date_today", row["date_today"]);
                        updateCommand.ExecuteNonQuery();
                    }
                }
                ConnectionClass.CloseConnectionMysql();
            }
        }

        public void SyncUtilitySubMeterData()
        {
            try
            {
                // Step 1: Get data from MySQL
                FetchDataFromMySQL();

                if (dataTable.Rows.Count > 0)
                {
                    // Step 2: Synchronize data with SQL Server
                    SynchronizeWithSQLServer();
                    Console.WriteLine("Data synchronized successfully.");
                }
                else
                {
                    Console.WriteLine("No data found in MySQL to synchronize.");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error during synchronization: " + ex.Message);
            }
        }
        private void FetchDataFromMySQL()
        {
            ConnectionClass.OpenConnectionMysql();
            string query = "SELECT * FROM utility_sub_meter";
            MySqlCommand = new MySqlCommand(query, ConnectionClass.MySqlConnection);
            MySqlDataAdapter mySqlDataAdapter = new MySqlDataAdapter();
            mySqlDataAdapter.SelectCommand = MySqlCommand; //           
            mySqlDataAdapter.Fill(dataTable); // 
            ConnectionClass.CloseConnectionMysql();
        }

        private void SynchronizeWithSQLServer()
        {
            const string deleteQuery = "DELETE FROM utility_sub_meter";
            const string insertQuery = @"
            INSERT INTO utility_sub_meter 
            (meter_id, utility_type, uom_id, allocation_type, site_id, unit_id, 
            meter_number, location, added_by, date_time_added, install_capacity, scada_tag,description,is_active,reading_method) 
            VALUES 
            (@MeterID, @UtilityType, @UOMID, @AllocationType, @SiteID, @UnitID, 
            @MeterNumber, @Location, @AddedBy, @DateTimeAdded, @InstallCapacity, @ScadaTag,@Description,@IsActive,@ReadingMethod)";

            ConnectionClass.OpenConnection();

            // Step 1: Delete existing data
            using (var deleteCommand = new SqlCommand(deleteQuery, ConnectionClass.connection))
            {
                deleteCommand.ExecuteNonQuery();
            }

            // Step 2: Insert new data
            using (var transaction = ConnectionClass.connection.BeginTransaction())
            {
                using (var insertCommand = new SqlCommand(insertQuery, ConnectionClass.connection, transaction))
                {
                    // Add parameters once to avoid creating them repeatedly
                    insertCommand.Parameters.Add("@MeterID", SqlDbType.Int);
                    insertCommand.Parameters.Add("@UtilityType", SqlDbType.VarChar);
                    insertCommand.Parameters.Add("@UOMID", SqlDbType.Int);
                    insertCommand.Parameters.Add("@AllocationType", SqlDbType.VarChar);
                    insertCommand.Parameters.Add("@SiteID", SqlDbType.Int);
                    insertCommand.Parameters.Add("@UnitID", SqlDbType.Int);
                    insertCommand.Parameters.Add("@MeterNumber", SqlDbType.VarChar);
                    insertCommand.Parameters.Add("@Location", SqlDbType.VarChar);
                    insertCommand.Parameters.Add("@AddedBy", SqlDbType.VarChar);
                    insertCommand.Parameters.Add("@DateTimeAdded", SqlDbType.DateTime);
                    insertCommand.Parameters.Add("@InstallCapacity", SqlDbType.Decimal);
                    insertCommand.Parameters.Add("@ScadaTag", SqlDbType.VarChar);
                    insertCommand.Parameters.Add("@Description", SqlDbType.VarChar);
                    insertCommand.Parameters.Add("@IsActive", SqlDbType.TinyInt);
                    insertCommand.Parameters.Add("@ReadingMethod", SqlDbType.VarChar);
                    foreach (DataRow row in dataTable.Rows)
                    {
                        // Update parameter values for each row
                        insertCommand.Parameters["@MeterID"].Value = row["id"];
                        insertCommand.Parameters["@UtilityType"].Value = row["utility_type"];
                        insertCommand.Parameters["@UOMID"].Value = row["uom_id"];
                        insertCommand.Parameters["@AllocationType"].Value = row["allocation_type"];
                        insertCommand.Parameters["@SiteID"].Value = row["site_id"];
                        insertCommand.Parameters["@UnitID"].Value = row["unit_id"];
                        insertCommand.Parameters["@MeterNumber"].Value = row["meter_number"];
                        insertCommand.Parameters["@Location"].Value = row["location"];
                        insertCommand.Parameters["@AddedBy"].Value = row["added_by"];
                        insertCommand.Parameters["@DateTimeAdded"].Value = row["date_time_added"];
                        insertCommand.Parameters["@InstallCapacity"].Value = row["install_capacity"];
                        insertCommand.Parameters["@ScadaTag"].Value = row["scada_tag"];
                        insertCommand.Parameters["@Description"].Value = row["description"];
                        insertCommand.Parameters["@IsActive"].Value = row["is_active"];
                        insertCommand.Parameters["@ReadingMethod"].Value = row["reading_method"];
                        insertCommand.ExecuteNonQuery();
                    }
                }

                transaction.Commit();

            }

            ConnectionClass.CloseConnection();
        }
    }
}
