using System;
using System.Collections.Generic;
using System.Text;
using System.Configuration;
using tpDomeWinAPP.Models;
using System.Data;
//using System.Data.SqlClient;
using MySql.Data.MySqlClient;
using Repository.Helper;
using Repository.BackendRepository.Interface;
using Dapper;
using System.Linq;
using NPOI.SS.Formula.Functions;
using Microsoft.Extensions.Primitives;
using MySqlX.XDevAPI.Relational;
using static NPOI.HSSF.Util.HSSFColor;

namespace tpDomeWinAPP.Service
{
    public class procCompare
    {
        string Connection1 = ConfigurationManager.ConnectionStrings["dbConStr"].ConnectionString;
        protected readonly IDatabaseHelper _databaseHelper;
        protected string UseDB;
        protected IDbConnection con;
        private readonly IBackendRepository backendRepository;

        
        public bool ToInsertNiagaraTagList(List<device_value2> dt, string building )
        {
            bool result = false;
            //tag
            insertNiagaraTagList(dt, building);
            insertItemFromNiagara(dt, building);
            deviceComparison();
            deviceItemComparison();
            insertBuildingMenu();
            insertSubSystemFloor();
            return result;
        }

        protected void insertNiagaraTagList(List<device_value2> dt, string building)
        {
            var ds2 = dt.GroupBy(x => new
            {
                tag_name2 = x.tag_name
            }).Select(x => new device_value2
            {
                tag_name = x.Key.tag_name2
            });

            using (MySqlConnection conn = new MySqlConnection(Connection1))
            {
                conn.Open();

                #region 不存在就 Create table 
                string ss = @" CREATE TABLE IF NOT EXISTS `import_niagara_tag` (
                                 `id` int(11) NOT NULL AUTO_INCREMENT,
                                 `db_tags` varchar(50) DEFAULT NULL,
                                 `niagara_tags` varchar(50) DEFAULT NULL,
                                 `device_area_tag` varchar(50) DEFAULT NULL,
                                 `device_building_tag` varchar(50) DEFAULT NULL,
                                 `device_system_tag` varchar(50) DEFAULT NULL,
                                 `device_name_tag` varchar(50) DEFAULT NULL,
                                 `device_floor_tag` varchar(50) DEFAULT NULL,
                                 `device_master_tag` varchar(50) DEFAULT NULL,
                                 `device_last_name_tag` varchar(50) DEFAULT NULL,
                                 `device_serial_tag` varchar(50) DEFAULT NULL,
                                 `atDateTime` datetime(1) DEFAULT NULL,
                                 `is_used` smallint(1) DEFAULT 0,
                                 PRIMARY KEY (`id`)
                               ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;";
                conn.Execute(ss.ToString());
                ss = "delete from import_niagara_tag where device_building_tag = '" + building + "'";
                conn.Execute(ss.ToString());
                #endregion

                StringBuilder sb = new StringBuilder();

                foreach (var row in ds2)
                {
                    if (string.IsNullOrEmpty(row.tag_name)) continue;
                    string[] arrTag = row.tag_name.Split('_');

                    sb.Append($@" insert import_niagara_tag(niagara_tags, device_area_tag, device_building_tag, device_system_tag,
                                device_name_tag, device_floor_tag, device_master_tag, device_last_name_tag, device_serial_tag, atDateTime) values('" +
                        row.tag_name + "', '" +
                        arrTag[0] + "', '" +
                        arrTag[1] + "', '" +
                        arrTag[2] + "', '" +
                        arrTag[3] + "', '" +
                        arrTag[4] + "', '" +
                        arrTag[5] + "', '" +
                        arrTag[6] + "', '" +
                        arrTag[7] + "',  " +
                        "now());");
                }
                try
                {
                    if (sb.Length > 0)
                    {
                        conn.Execute(sb.ToString());
                        sb.Clear();
                    }
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }
        }

        protected void insertItemFromNiagara(List<device_value2> dt, string building)
        {
            using (MySqlConnection conn = new MySqlConnection(Connection1))
            {
                conn.Open();
                #region create table
                string ss = @"CREATE TABLE IF NOT EXISTS `import_niagara_item` (
                              `id` int(11) NOT NULL AUTO_INCREMENT,
                              `device_area_tag` varchar(50) DEFAULT NULL,
                              `device_building_tag` varchar(50) DEFAULT NULL,
                              `device_system_tag` varchar(50) DEFAULT NULL,
                              `device_name_tag` varchar(50) DEFAULT NULL,
                              `device_point_name` varchar(50) DEFAULT NULL,
                              `check_status` varchar(50) DEFAULT NULL,
                              PRIMARY KEY (`id`)
                            ) ENGINE=InnoDB AUTO_INCREMENT=59 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;";
                conn.Execute(ss.ToString());
                ss = "delete from import_niagara_item where device_building_tag = '" + building + "'";
                conn.Execute(ss.ToString());
                #endregion

                List<device_item8> dt_item = new List<device_item8>();

                foreach (var row in dt)
                {
                    if (string.IsNullOrEmpty(row.tag_name)) continue;
                    string[] arrTag = row.tag_name.Split('_');

                    #region for item
                    device_item8 row_item = new device_item8();
                    row_item.tag_name = row.tag_name;
                    row_item.device_area_tag = arrTag[0];
                    row_item.device_building_tag = arrTag[1];
                    row_item.device_system_tag = arrTag[2];
                    row_item.device_name_tag = arrTag[3];
                    row_item.device_floor_tag = arrTag[4];
                    row_item.device_master_tag = arrTag[5];
                    row_item.device_last_name_tag = arrTag[6];
                    row_item.device_serial_tag = arrTag[7];
                    row_item.point_name = row.point_name;
                    dt_item.Add(row_item);
                    #endregion
                }

                //device_item
                var ds2_item = dt_item.GroupBy(x => new
                {
                    device_area_tag2 = x.device_area_tag,
                    device_building_tag2 = x.device_building_tag,
                    device_system_tag2 = x.device_system_tag,
                    device_name_tag2 = x.device_name_tag,
                    point_name2 = x.point_name
                }).Select(x => new device_item8
                {
                    device_area_tag = x.Key.device_area_tag2,
                    device_building_tag = x.Key.device_building_tag2,
                    device_system_tag = x.Key.device_system_tag2,
                    device_name_tag = x.Key.device_name_tag2,
                    point_name = x.Key.point_name2
                });

                StringBuilder sb = new StringBuilder();
                foreach (var row2 in ds2_item)
                {
                    sb.Append($@" insert import_niagara_item(device_area_tag, device_building_tag, device_system_tag, device_name_tag, device_point_name)
                              values('" +
                        row2.device_area_tag + "', '" +
                        row2.device_building_tag + "', '" +
                        row2.device_system_tag + "', '" +
                        row2.device_name_tag + "', '" +
                        row2.point_name + "'" +
                        ");");
                }
                try
                {
                    if (sb.Length > 0)
                    {
                        conn.Execute(sb.ToString());
                        sb.Clear();
                    }
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }
        }

        /// <summary>
        /// 比對device和import_Niagara_tag,並更新至device(資料表)
        /// </summary>
        public void deviceComparison()
        {
            using (MySqlConnection conn = new MySqlConnection(Connection1))
            {
                List<NiagaraTags> result;

                conn.Open();
                StringBuilder sb = new StringBuilder();
                StringBuilder sb2 = new StringBuilder();
                sb.Append($@" SELECT m.*
                               FROM import_niagara_tag m
                               LEFT JOIN device d
                               ON m.niagara_tags = d.device_number
                               WHERE d.device_number IS NULL");
                result = conn.Query<NiagaraTags>(sb.ToString()).ToList<NiagaraTags>();

                sb.Clear();
                //新增至device, is_link = 1
                if (result.Count > 0)
                {
                    foreach (var data in result)
                    {
                        sb.Append($@" insert device(device_guid, deleted, status, priority, is_link, device_area_tag, 
                                    device_building_tag, device_system_tag, device_name_tag, device_floor_tag, device_master, 
                                    device_last_name, device_serial_tag, device_number, device_system_category_layer3, created_at, updated_at)
                                values(uuid(), 0, 1, 0, 1, '" +  
                                data.device_area_tag + "', '" + 
                                data.device_building_tag + "', '" +
                                data.device_system_tag + "', '" +
                                data.device_name_tag + "', '" +

                                data.device_floor_tag + "', '" +
                                data.device_master_tag + "', '" +
                                data.device_last_name_tag + "', '" +
                                data.device_serial_tag + "', '" +
                                data.niagara_tags + "', '" +  
                                data.device_system_tag + "', now(), now() );");

                        sb2.Append($@"INSERT device_kind (device_kind_guid, device_building_tag, device_system_tag, device_name_tag, 
                                    device_normal_flashing, device_close_flashing, device_error_flashing, device_error_independent, 
                                    created_by, created_at)
                                    VALUES (uuid(), '" + data.device_building_tag + "', '" + data.device_system_tag + "', '" + data.device_name_tag + 
                                    "', 0, 0, 1, 0, 'B43E3CA7-96DD-4FC7-B6E6-974ACC3B0878', now());");
                    }
                    if(sb.Length > 0)
                    {
                        conn.Execute(sb.ToString());
                        conn.Execute(sb2.ToString());
                        sb.Clear();
                        sb2.Clear();
                    }
                }
                
                //device有,niagara沒有,is_link 更新成 0
                sb.Append($@" SET SQL_SAFE_UPDATES = 0;
                              UPDATE device d LEFT JOIN import_niagara_tag m ON d.device_number = m.niagara_tags
                              SET d.is_link = 0
                              WHERE m.niagara_tags IS NULL");
                conn.Execute(sb.ToString());

            }
        }

        /// <summary>
        /// 比對device_item和import_Niagara_item,並更新至device_item(資料表)
        /// </summary>
        public void deviceItemComparison()
        {
            using (MySqlConnection conn = new MySqlConnection(Connection1))
            {
                List<NiagaraTagsForItem> result;

                conn.Open();
                StringBuilder sb = new StringBuilder();
                sb.Append($@" SELECT m.*
                              FROM import_niagara_item m
                              LEFT JOIN device_item d
                              ON m.device_system_tag = d.device_system_tag and m.device_name_tag = d.device_name_tag and m.device_point_name = d.points
                              WHERE d.points IS NULL");
                result = conn.Query<NiagaraTagsForItem>(sb.ToString()).ToList<NiagaraTagsForItem>();
                sb.Clear();
                //新增至device, is_link = 1
                if (result.Count > 0)
                {
                    foreach (var data in result)
                    {
                        var isControll = 0;
                        var isBool = 0;
                        if (data.device_point_name == "ER" || data.device_point_name == "AL" || data.device_point_name == "ST")
                        {
                            isControll = 1;
                        }
                        if (data.device_point_name == "ER" || data.device_point_name == "ST")
                        {
                            isBool = 1;
                        }
                        sb.Append($@"insert device_item(deleted, points, is_show, is_show_riserDiagram, is_controll, is_bool, is_link, 
                                    device_system_tag, device_name_tag, created_at, updated_at)
                                    VALUES (0, '" + 
                                    data.device_point_name + "', 1, 0, " + 
                                    isControll + "," +
                                    isBool + ", 1, '" +
                                    data.device_system_tag + "', '" +
                                    data.device_name_tag + "', " +
                                    "now(), now());");
                    }
                    if (sb.Length > 0)
                    {
                        conn.Execute(sb.ToString());
                        sb.Clear();
                    }
                }
                //device有,niagara沒有,is_link 更新成 0
                sb.Append($@" SET SQL_SAFE_UPDATES = 0;
                              UPDATE device_item d LEFT JOIN import_niagara_item m 
                              ON d.device_system_tag = m.device_system_tag and d.device_name_tag = m.device_name_tag and d.points = m.device_point_name
                              SET d.is_link = 0
                              WHERE m.device_point_name IS NULL");
                conn.Execute(sb.ToString());
            }
        }

        public void insertBuildingMenu()
        {
            using (MySqlConnection conn = new MySqlConnection(Connection1))
            {
                conn.Open();
                List<NiagaraTags> result;
                StringBuilder sb = new StringBuilder();
                #region comparison building_menu and import_niagara_tag
                sb.Append($@" select a.* from (
                              	select  device_building_tag, device_system_tag, device_name_tag
                              	from import_niagara_tag
                              	group by device_building_tag, device_system_tag, device_name_tag 
                              ) AS a
                              LEFT JOIN building_menu b
                              ON a.device_building_tag = b.device_building_tag and a.device_system_tag = b.device_system_tag and a.device_name_tag = b.sub_system_tag
                              WHERE b.device_building_tag IS NULL");
                result = conn.Query<NiagaraTags>(sb.ToString()).ToList<NiagaraTags>();
                #endregion
                sb.Clear();

                if (result.Count > 0)
                {
                    foreach (var data in result) {
                        #region insert building_menu
                        sb.Append(@"insert building_menu(building_tag, main_system_tag, sub_system_tag, device_building_tag, device_system_tag,
                              is_link, created_by, created_at, updated_by, updated_at)
                              VALUES ('" + data.device_building_tag + "', '" +
                              data.device_system_tag + "', '" +
                              data.device_name_tag + "', '" +
                              data.device_building_tag + "', '" +
                              data.device_system_tag + "', " + 
                              "1, 'B43E3CA7-96DD-4FC7-B6E6-974ACC3B0878', now(), 'B43E3CA7-96DD-4FC7-B6E6-974ACC3B0878', now() );");
                        #endregion
                    }
                    if (sb.Length > 0)
                    {
                        conn.Execute(sb.ToString());
                        sb.Clear();
                    }
                }
                //building_menu有,import_niagara_tag沒有,is_link 更新成 0
                sb.Append($@" SET SQL_SAFE_UPDATES = 0;
                              UPDATE building_menu b LEFT JOIN (
                              	select  device_building_tag, device_system_tag, device_name_tag
                              	from import_niagara_tag
                              	group by device_building_tag, device_system_tag, device_name_tag
                              ) AS a ON b.device_building_tag = a.device_building_tag 
                              and a.device_system_tag = b.device_system_tag and a.device_name_tag = b.sub_system_tag
                              SET b.is_link = 0
                              WHERE b.device_building_tag IS NULL");
                conn.Execute(sb.ToString());
            }
        }

        public void insertSubSystemFloor()
        {
            using (MySqlConnection conn = new MySqlConnection(Connection1))
            {
                conn.Open();
                List<NiagaraTags> result;
                StringBuilder sb = new StringBuilder();
                #region comparison sub_system_floor and import_niagara_tag
                sb.Append($@" select a.* from (
                              	select  device_building_tag, device_system_tag, device_name_tag, device_floor_tag
                              	from import_niagara_tag
                              	group by device_building_tag, device_system_tag, device_name_tag, device_floor_tag
                              ) AS a
                              LEFT JOIN sub_system_floor b
                              ON a.device_building_tag = b.building_tag and a.device_system_tag = b.main_system_tag and a.device_name_tag = b.sub_system_tag and a.device_floor_tag = b.floor_tag
                              WHERE b.building_tag IS NULL");
                result = conn.Query<NiagaraTags>(sb.ToString()).ToList<NiagaraTags>();
                #endregion
                sb.Clear();


                if(result.Count > 0)
                {
                    foreach(var data in result)
                    {
                        #region insert building_menu
                        sb.Append(@"insert sub_system_floor(building_tag, main_system_tag, sub_system_tag, floor_tag,  
                                    is_link, created_by, created_at, updated_by, updated_at)
                                    VALUES ('" +
                                    data.device_building_tag + "', '" +
                                    data.device_system_tag + "', '" + 
                                    data.device_name_tag + "', '" + 
                                    data.device_floor_tag + "', " +  
                                    "1, 'B43E3CA7-96DD-4FC7-B6E6-974ACC3B0878', now(), 'B43E3CA7-96DD-4FC7-B6E6-974ACC3B0878', now());");
                        #endregion
                    }
                    if (sb.Length > 0)
                    {
                        conn.Execute(sb.ToString());
                        sb.Clear();
                    }
                }
                //building_menu有,import_niagara_tag沒有,is_link 更新成 0
                sb.Append($@" SET SQL_SAFE_UPDATES = 0;
                              UPDATE sub_system_floor b LEFT JOIN (
                              	select  device_building_tag, device_system_tag, device_name_tag, device_floor_tag
                              	from import_niagara_tag
                              	group by device_building_tag, device_system_tag, device_name_tag, device_floor_tag
                              ) AS a ON b.building_tag = a.device_building_tag 
                              and b.main_system_tag = a.device_system_tag and b.sub_system_tag = a.device_name_tag and b.floor_tag = a.device_floor_tag
                              SET b.is_link = 0
                              WHERE b.building_tag IS NULL");
                conn.Execute(sb.ToString());

            }
        }

        public bool InsertDbTagList(List<device_value2> dt, string building)
        {
            bool result = false;
            var ds2 = dt.GroupBy(x => new
            {
                tag_name2 = x.tag_name
            }).Select(x => new device_value2
            {
                tag_name = x.Key.tag_name2
            });

            using (MySqlConnection conn = new MySqlConnection(Connection1))
            {
                //CONCAT('{baseURL}', '{deviceKindFilePath}', dk.device_image) AS device_image_url,
                conn.Open();

                #region 判斷 table 是否存在
                string ss = @"IF (not EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'import_dbTag_niagaraTag'))
                            BEGIN  
	                            CREATE TABLE [dbo].[import_dbTag_niagaraTag](
	                                [device_guid] [varchar](36) NOT NULL,
	                                [full_name] [varchar](50) NOT NULL,
	                                [device_number] [varchar](50) NOT NULL,
	                                [niagaraTag] [varchar](50) NOT NULL,
	                                [device_coordinate] [varchar](50) NULL,
	                                [device_number_old] [varchar](50) NULL,
	                                [device_building_tag] [varchar](50) NOT NULL,
	                                [device_system_tag] [varchar](50) NOT NULL,
	                                [device_system_tag_old] [varchar](50) NULL,
	                                [device_floor_tag] [varchar](50) NOT NULL,
	                                [device_name_tag] [varchar](50) NOT NULL,
	                                [device_serial_tag] [varchar](50) NOT NULL,
                                    [atDateTime] [smalldatetime] NULL,
                                 CONSTRAINT [PK_import_dbTag_niagaraTag] PRIMARY KEY CLUSTERED 
                                (
	                                [device_guid] ASC
                                )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
                                ) ON [PRIMARY];
                            END";
                conn.Execute(ss.ToString());
                //ss = "delete from import_niagara_tag where building = '" + building + "'";
                //conn.Execute(ss.ToString());
                #endregion

                StringBuilder sb = new StringBuilder();
                int i = 0;

                sb.Append($@" insert import_dbTag_niagaraTag(device_guid, full_name, device_number, niagaraTag, device_coordinate, device_number_old, device_building_tag, device_system_tag, device_system_tag_old, device_floor_tag, device_name_tag, device_serial_tag, atDateTime) 
                                                      select device_guid, full_name, device_number, '',       device_coordinate, device_number_old, device_building_tag, device_system_tag, device_system_tag_old, device_floor_tag, device_name_tag, device_serial_tag, getDate()
                       from device where deleted = 0;");
                conn.Execute(sb.ToString());
                sb.Clear();

                #region update  niagara_tags
                sb.Clear();
                sb.Append($@"update import_dbTag_niagaraTag set niagaraTag = b.niagara_tags
                            from [dbo].[import_niagara_tag] b
                            where import_dbTag_niagaraTag.device_number = b.niagara_tags ");
                conn.Execute(sb.ToString());
                #endregion
            }

            return result;
        }


        public List<NiagaraTags> GetNiagaraTags(string building)
        {
            List<NiagaraTags> result;
            using (MySqlConnection conn = new MySqlConnection(Connection1))
            {
                //CONCAT('{baseURL}', '{deviceKindFilePath}', dk.device_image) AS device_image_url,
                conn.Open();
                StringBuilder sb = new StringBuilder();
                sb.Append($@" select * from import_niagara_tag where device_building_tag = '{building}'");
                result = conn.Query<NiagaraTags>(sb.ToString()).ToList<NiagaraTags>(); 
            }
            return result;
        }

        public List<NiagaraTags> SearchNiagaraTags(string sql)
        {
            List<NiagaraTags> result;
            using (MySqlConnection conn = new MySqlConnection(Connection1))
            {
                //CONCAT('{baseURL}', '{deviceKindFilePath}', dk.device_image) AS device_image_url,
                conn.Open();
                StringBuilder sb = new StringBuilder();
                sb.Append(sql);
                result = conn.Query<NiagaraTags>(sb.ToString()).ToList<NiagaraTags>();
            }
            return result;
        }

        public List<dbDevice> SearchDBTags(string building)
        {
            List<dbDevice> result;
            using (MySqlConnection conn = new MySqlConnection(Connection1))
            {
                //CONCAT('{baseURL}', '{deviceKindFilePath}', dk.device_image) AS device_image_url,
                conn.Open();
                StringBuilder sb = new StringBuilder();
                if (string.IsNullOrEmpty(building))
                {
                    sb.Append("select * from import_dbTag_niagaraTag  order by device_number");
                }
                else {
                    sb.Append($@"select * from import_dbTag_niagaraTag where device_building_tag = '{building}' order by device_number");
                }
               
                result = conn.Query<dbDevice>(sb.ToString()).ToList<dbDevice>();
            }
            return result;
        }

        public List<dbDevice> filterDBTags(string sql)
        {
            List<dbDevice> result;
            using (MySqlConnection conn = new MySqlConnection(Connection1))
            {
                //CONCAT('{baseURL}', '{deviceKindFilePath}', dk.device_image) AS device_image_url,
                conn.Open();
                StringBuilder sb = new StringBuilder();
                sb.Append(sql);
                result = conn.Query<dbDevice>(sb.ToString()).ToList<dbDevice>();
            }
            return result;
        }

        /// <summary>
        /// 更新 DbTag 中的 Niagara tag 欄位
        /// </summary>
        /// <param name="sql"></param>
        /// <returns></returns>
        public int updateNiagaraTag_forDBTags(string bilding)
        {
            int i = -1;
            using (MySqlConnection conn = new MySqlConnection(Connection1))
            {
                //CONCAT('{baseURL}', '{deviceKindFilePath}', dk.device_image) AS device_image_url,
                conn.Open();
                StringBuilder sb = new StringBuilder();
                try
                {
                    #region 更新該棟的 DB data
                    sb.Append($@"delete  import_dbTag_niagaraTag where device_building_tag = '{bilding}'");
                    conn.Execute(sb.ToString());
                    sb.Clear();

                    sb.Append($@" insert import_dbTag_niagaraTag(device_guid, full_name, device_number, niagaraTag, device_coordinate, device_number_old, device_building_tag, device_system_tag, device_system_tag_old, device_floor_tag, device_name_tag, device_serial_tag, atDateTime) 
                                                              select device_guid, full_name, device_number, '',       device_coordinate, device_number_old, device_building_tag, device_system_tag, device_system_tag_old, device_floor_tag, device_name_tag, device_serial_tag, getDate()
                               from device where deleted = 0 and device_building_tag = '{bilding}';");
                    conn.Execute(sb.ToString());
                    sb.Clear();
                    #endregion

                    sb.Append($@"update import_dbTag_niagaraTag set niagaraTag = b.niagara_tags
                                from [dbo].[import_niagara_tag] b
                                where import_dbTag_niagaraTag.device_number = b.niagara_tags 
                                      and import_dbTag_niagaraTag.device_building_tag = '{bilding}'");
                    i = conn.Execute(sb.ToString());
                    sb.Clear();
               
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }
            return i;
        }
    }
}