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;

namespace tpDomeWinAPP.Service
{
    public class getDeviceSvc
    {
        string Connection1 = string.Empty;
        protected readonly IDatabaseHelper _databaseHelper;
        protected string UseDB;
        protected IDbConnection con;
        private readonly IBackendRepository backendRepository;

        public getDeviceSvc(string Connection_parame = null)
        {
            if (!string.IsNullOrEmpty(Connection_parame))
            {
                Connection1 = Connection_parame;
            }
            else
            {
                Connection1 = ConfigurationManager.ConnectionStrings["dbConStr"].ConnectionString;
            }
        }
      
        public List<Device> getDevices()
        {

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

                var sql = $@"SELECT 
                                        d.*,
                                        d.full_name AS Device_full_name,
                                        b.full_name AS Building_full_name,
                                        ms.full_name AS Main_system_full_name,
                                        ss.full_name AS Sub_system_full_name,
                                        f.full_name AS Floor_full_name,
                                        dk.device_image,
                                        device_image AS device_image_url,
                                        dk.device_close_color,
                                        dk.device_normal_color,
                                        dk.device_error_color,
                                        dk.device_normal_flashing,
                                        dk.device_close_flashing,
                                        dk.device_error_flashing,
                                        (SELECT
                                            STRING_AGG( ISNULL(system_key, ' '), ',')
                                            FROM device_disaster dd 
                                            JOIN variable v ON v.deleted = 0 AND v.system_type = 'disaster' AND v.system_value = dd.device_system_value
                                            WHERE dd.device_guid = d.device_guid
                                        ) AS Device_disaster_type_text
                                        FROM ( 
                                            SELECT * 
                                                FROM device d
                                                WHERE 
                                              --          d.building_guid = @Building_guid
                                              --      AND d.main_system_guid = @Main_system_guid
                                              --      AND d.sub_system_guid = @Sub_system_guid
                                              --      AND d.floor_guid = @Floor_guid AND
                                                     d.deleted = 0
                                        ) d
                                        JOIN building b ON d.building_guid = b.building_guid
                                        JOIN main_system ms ON d.main_system_guid = ms.main_system_guid
                                        JOIN sub_system ss ON d.sub_system_guid = ss.sub_system_guid
                                        JOIN floor f ON d.floor_guid = f.floor_guid
                                        LEFT JOIN device_kind dk ON dk.device_building_tag = d.device_building_tag
                                                                    AND dk.device_system_tag = d.device_system_tag
                                                                    -- AND dk.device_floor_tag = d.device_floor_tag
                                                                    AND dk.device_name_tag = d.device_name_tag
                                        ORDER BY d.priority ASC, d.device_number ASC
                                        ";

                var devices = conn.Query<Device>(sql).AsList<Device>();
                return devices;
                //var sql_node = $@"SELECT
                //                    dn.device_node_guid,
                //                    dn.device_guid,
                //                    dn.full_name AS Device_node_full_name,
                //                    dn.device_node_coordinate,
                //                    dn.priority
                //                FROM device_node dn 
                //                WHERE dn.deleted = 0 AND dn.device_guid = @device_guid
                //                ORDER BY dn.priority ASC";
                //foreach (var device in devices)
                //{
                //    device.Device_nodes = await backendRepository.GetAllAsync<DeviceNode>(sql_node, new { device_guid = device.Device_guid });
                //}
            }

        }

        #region insert DB
        public bool clearTb_importData()
        {
            bool result = false;
            using (SqlConnection conn = new SqlConnection(Connection1))
            {
                //CONCAT('{baseURL}', '{deviceKindFilePath}', dk.device_image) AS device_image_url,
                conn.Open();
                StringBuilder sb = new StringBuilder();
                int i = 0;
               
                sb.Append($@" truncate table importExcel; 
                              truncate table importData_batch;"); 
                try
                {
                    conn.Execute(sb.ToString());
                    
                }
                catch (Exception ex)
                {
                    throw ex;
                } 
            }

            return result;
        }

        public bool insertDB(DataTable dt)
        {
            bool result = false;
            using (SqlConnection conn = new SqlConnection(Connection1))
            {
                //CONCAT('{baseURL}', '{deviceKindFilePath}', dk.device_image) AS device_image_url,
                conn.Open();
                StringBuilder sb = new StringBuilder();
                int i = 0;
                foreach (DataRow row in dt.Rows)
                {
                    sb.Append($@" insert importExcel(intro, old_tags, new_tags, floor, device_name, device_note, device_type, device_number, atDateTime) values('" +
                        row["tag_name_zh"].ToString() + "', '" +
                        row["old_tags"].ToString() + "', '" +
                        row["new_tags"].ToString() + "', '" +
                        row["floor"].ToString() + "', '" +
                        row["device_name"].ToString() + "', '" +
                        row["device_note"].ToString() + "', '" +
                        row["device_type"].ToString() + "', '" +
                        row["device_number"].ToString() + "' , getdate());");
                    i++;
                    try
                    {
                        if (i >= 100)
                        {
                            conn.Execute(sb.ToString());
                            sb.Clear();
                            i = 0;
                        }
                    }
                    catch (Exception ex)
                    {
                        throw ex;
                    }
                }
                if (sb.Length > 0)
                {
                    conn.Execute(sb.ToString());
                }
            }
            
            return result;
        }

        public bool insertDB_batch() {
            bool result = false;
            using (SqlConnection conn = new SqlConnection(Connection1))
            {
                //CONCAT('{baseURL}', '{deviceKindFilePath}', dk.device_image) AS device_image_url,
                conn.Open();
                StringBuilder sb = new StringBuilder();
                sb.Append($@" select  old_tags, new_tags, tag_no5, serial, tagName from 
	                                (
		                                select old_tags, new_tags,  tagName tag_no5
		                                from importExcel a  CROSS APPLY [Func_StringSplit](a.new_tags, '_') 
		                                where serial = 5  and new_tags like '%~%' 
	                                ) b  CROSS APPLY [Func_StringSplit](b.tag_no5, '~') 
	                                where serial = 2;");
                var batchData = conn.Query<Device_batch>(sb.ToString());
                int i = 0;
                sb.Clear();
                foreach (var row in batchData)
                {
                    var ss = row.tag_no5.Split('~');
                    int start_num = int.Parse(ss[0]);
                    int end_num = int.Parse(ss[1]);
                    var ss_old = row.old_tags.Split('_');
                    var ss_new = row.new_tags.Split('_');

                    string vv5 = string.Empty;
                    //if (row.new_tags == "H_M10_B4F_FCU_001~108")
                    //{
                    //    Console.WriteLine("here");
                    //}
                    for (int j = 1; j <= end_num; j++)
                    {
                        switch (ss[0].Length)
                        {

                            case 2:  vv5 = (j <= 9) ? "0" + j.ToString() : j.ToString();  break;
                            case 3:
                                if (j <= 9)
                                    // vv5 = "00" + j.ToString();
                                    vv5 = "0" + j.ToString();
                                else if (j <= 99)
                                    // vv5 = "0" + j.ToString();
                                    vv5 = j.ToString();
                                else vv5 = j.ToString(); 
                                break;
                        }
                        string old_tag = ss_old[0] + "_" + ss_old[1] + "_" + ss_old[2] + "_" + ss_old[3] + "_" + vv5;
                        string new_tag = ss_new[0] + "_" + ss_new[1] + "_" + ss_new[2] + "_" + ss_new[3] + "_" + vv5;

                        sb.Append($@" insert importData_batch(old_tags, new_tags) values('" +
                        old_tag +"', '" +
                        new_tag + "'); ");
                    }
                     
                    try
                    {
                        if (sb.Length > 0)
                        {
                            conn.Execute(sb.ToString());
                            sb.Clear();
                            result = true;
                        } 
                    }
                    catch (Exception ex)
                    {
                        throw ex;
                    }
                }

                try
                {
                    #region  更新 web 端新匯入的 excel 
                    sb.Append($@" update device set device_number_old = device_number where device_number_old is null");
                    conn.Execute(sb.ToString());
                    sb.Clear();

                    //1.2.更新欄位 device_number_old
                    sb.Append($@" update device set device_system_tag_old = b.tagName
	                                from (select device_number, device_number_old, serial, tagName
		                                from device a  CROSS APPLY [Func_StringSplit](a.device_number, '_') 
		                                where serial = 2 and device_system_tag_old is null)b
	                                where device.device_number_old = b.device_number_old and device_system_tag_old is null");
                    conn.Execute(sb.ToString());
                    sb.Clear();
                    #endregion

                    sb.Append("delete from importExcel where new_tags like '%~%'");
                    conn.Execute(sb.ToString());
                    sb.Clear();

                    sb.Append(@"insert  importExcel(new_tags, old_tags)
                                        select new_tags, old_tags from importData_batch");
                    conn.Execute(sb.ToString());
                    sb.Clear();

                    #region 製作比對用 table:import_dbTag_niagaraTag
                    #region 判斷 table 是否存在
                    string s1 = @" 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];";

                        //string ss = @"IF (EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'import_dbTag_niagaraTag'))
                        //        BEGIN  
                        //            drop table import_dbTag_niagaraTag; 
                        //        END";
                        sb.Append("truncate table import_dbTag_niagaraTag");
                            conn.Execute(sb.ToString());
                        sb.Clear();
                        #endregion

                    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
                    #endregion 製作比對用 table:import_dbTag_niagaraTag

                    sb.Append(@"update import_dbTag_niagaraTag set device_number = b.new_tags,
	                                                              device_system_tag = b.device_system_tag
	                                    from (
		                                    select old_tags, new_tags, serial, tagName as device_system_tag
		                                    from importExcel a  CROSS APPLY [Func_StringSplit](a.new_tags, '_') 
		                                    where serial = 2) b 
	                                    where [import_dbTag_niagaraTag].device_number_old = b.old_tags");
                    conn.Execute(sb.ToString());
                    sb.Clear();

                    sb.Append(@"update [dbo].[device] set device.device_number = b.new_tags,
	                                                              device_system_tag = b.device_system_tag
	                                    from (
		                                    select old_tags, new_tags, serial, tagName as device_system_tag
		                                    from importExcel a  CROSS APPLY [Func_StringSplit](a.new_tags, '_') 
		                                    where serial = 2) b 
	                                    where [device].device_number_old = b.old_tags");
                    conn.Execute(sb.ToString());
                    sb.Clear();

                    sb.Append(@"update device_import_ckeck_temp set device_system_tag = b.device_system_tag, 
			                        device_number = b.device_number
		                        from device b 
		                        where device_import_ckeck_temp.device_building_tag = b.device_building_tag and 
				                        device_import_ckeck_temp.device_system_tag_old = b.device_system_tag_old and 
				                        device_import_ckeck_temp.device_number_old = b.device_number_old
				                        and device_import_ckeck_temp.device_number <> b.device_number");
                    conn.Execute(sb.ToString());
                    sb.Clear();

                    sb.Append(@"update device_kind set device_system_tag = b.device_system_tag
		                        from device b 
		                        where device_kind.device_building_tag = b.device_building_tag and 
		                        device_kind.device_system_tag_old = b.device_system_tag_old and 
		                        device_kind.device_name_tag = b.device_name_tag");
                    conn.Execute(sb.ToString());
                    sb.Clear();

                    
                    result = true ;
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            } 
            return result;
        }
        #endregion
    }
}