using Dapper;
using Repository.BackendRepository.Interface;
using Repository.Helper;
using System;
using System.Text;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Threading.Tasks;
using System.Transactions;
using Repository.Models;


namespace Repository.BackendRepository.Implement
{
    public class NiagaraDataSynchronizeRepository : BackendRepository, INiagaraDataSynchronizeRepository
    {
        public NiagaraDataSynchronizeRepository(IDatabaseHelper databaseHelper) : base(databaseHelper)
        {
        }

        /// <summary>
        /// 更新import_niagara_tag資料表
        /// </summary>
        /// <param name="ds"></param>
        /// <param name="building"></param>
        /// <returns></returns>
        public async Task InsertNiagaraTagList(List<Device_value> ds, string building)
        {
            using (IDbConnection conn = GetDbConnection())
            {
                conn.Open();
                using (TransactionScope scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
                {
                    try
                    {
                        string sql = @"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;";
                        await conn.ExecuteAsync(sql);
                        sql = "delete from import_niagara_tag where device_building_tag = '" + building + "'";
                        await conn.ExecuteAsync(sql);

                        //N4資料groupBy後放入import_niagara_tag資料表
                        var ds2 = ds.GroupBy(x => new
                        {
                            tag_name2 = x.tag_name
                        }).Select(x => new Device_value
                        {
                            tag_name = x.Key.tag_name2
                        });

                        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());");
                        }
                        if (sb.Length > 0)
                        {
                            await conn.ExecuteAsync(sb.ToString());
                            sb.Clear();
                        }
                    }
                    catch (Exception exception)
                    {
                        throw exception;
                    }
                    finally
                    {
                        conn.Close();
                    }
                }
            }
        }

        /// <summary>
        /// 更新import_niagara_tag資料表
        /// </summary>
        /// <param name="ds"></param>
        /// <param name="building"></param>
        /// <returns></returns>
        public async Task InsertItemFromNiagara(List<Device_value> ds, string building)
        {
            using (IDbConnection conn = GetDbConnection())
            {
                conn.Open();
                using (TransactionScope scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
                {
                    try
                    {
                        #region 刪除 import_niagara_item資料表中選取的棟別
                        string sql = @"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;";
                        await conn.ExecuteAsync(sql);
                        sql = "delete from import_niagara_item where device_building_tag = '" + building + "'";
                        await conn.ExecuteAsync(sql);
                        #endregion

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

                        foreach (var row in ds)
                        {
                            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
                        }

                        #region N4資料groupBy後放入import_niagara_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 + "'" +
                                ");");
                        }
                        if (sb.Length > 0)
                        {
                            await conn.ExecuteAsync(sb.ToString());
                            sb.Clear();
                        }
                        #endregion
                    }
                    catch (Exception exception)
                    {
                        throw exception;
                    }
                    finally
                    {
                        conn.Close();
                    }
                }
            }
        }
        /// <summary>
        /// 比對 device
        /// </summary>
        /// <returns></returns>
        public async Task DeviceComparison()
        {
            using (IDbConnection conn = GetDbConnection())
            {
                conn.Open();
                using (TransactionScope scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
                {
                    try
                    {
                        List<NiagaraTags> result;
                        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 = (await conn.QueryAsync<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)
                            {
                                await conn.ExecuteAsync(sb.ToString());
                                await conn.ExecuteAsync(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");
                        await conn.ExecuteAsync(sb.ToString());

                    }
                    catch (Exception exception)
                    {
                        throw exception;
                    }
                    finally
                    {
                        conn.Close();
                    }
                }
            }
        }

        /// <summary>
        /// 比對 device_item
        /// </summary>
        /// <returns></returns>
        public async Task DeviceItemComparison()
        {
            using (IDbConnection conn = GetDbConnection())
            {
                conn.Open();
                using (TransactionScope scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
                {
                    try
                    {
                        List<NiagaraTagsForItem> result;
                        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 = (await conn.QueryAsync<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)
                            {
                                await conn.ExecuteAsync(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");
                        await conn.ExecuteAsync(sb.ToString());
                    }
                    catch (Exception exception)
                    {
                        throw exception;
                    }
                    finally
                    {
                        conn.Close();
                    }
                }
            }
        }

        /// <summary>
        /// 新增資料至 buildingMenu
        /// </summary>
        /// <returns></returns>
        public async Task InsertBuildingMenu()
        {
            using (IDbConnection conn = GetDbConnection())
            {
                conn.Open();
                using (TransactionScope scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
                {
                    try
                    {
                        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 = (await conn.QueryAsync<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)
                            {
                                await conn.ExecuteAsync(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");
                        await conn.ExecuteAsync(sb.ToString());
                    }
                    catch (Exception exception)
                    {
                        throw exception;
                    }
                    finally
                    {
                        conn.Close();
                    }
                }
            }
        }

        /// <summary>
        /// 新增資料至 subSystemFloor
        /// </summary>
        /// <returns></returns>
        public async Task InsertSubSystemFloor()
        {
            using (IDbConnection conn = GetDbConnection())
            {
                conn.Open();
                using (TransactionScope scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
                {
                    try
                    {
                        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 = (await conn.QueryAsync<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)
                            {
                                await conn.ExecuteAsync(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");
                        await conn.ExecuteAsync(sb.ToString());
                    }
                    catch (Exception exception)
                    {
                        throw exception;
                    }
                    finally
                    {
                        conn.Close();
                    }
                }
            }
        }

    }
}