using System.Net.Http;
using System.Text;
using System.Text.Json; // 適用於 .NET Core 3.0+ / .NET 5/6/7/8
using System.Net;
using System.Net.Sockets;
using System.Diagnostics;
using System.IO;
using Microsoft.VisualBasic.Devices;

namespace HeartbeatSender
{

    public class heartbeatSender
    {
        private readonly HttpClient httpClient = new HttpClient();
        private string token;
        private string token_heartbeatUrl;
        private string init_heartbeatUrl;

        public heartbeatSender()
        {
            LoadHeartbeatUrls("txt/HeartBeat.txt");
        }
        /// <summary>
        /// 讀取URL
        /// </summary>
        /// <param name="filePath">路徑</param>
        private void LoadHeartbeatUrls(string filePath)
        {
            if (!File.Exists(filePath))
            {
                Console.WriteLine("找不到 HeartBeat.txt");
                return;
            }

            string[] lines = File.ReadAllLines(filePath);

            foreach (string line in lines)
            {
                if (line.StartsWith("init:"))
                {
                    init_heartbeatUrl = line.Substring("init:".Length).Trim();
                }
                else if (line.StartsWith("token:"))
                {
                    token_heartbeatUrl = line.Substring("token:".Length).Trim();
                }
            }

            Console.WriteLine("init URL: " + init_heartbeatUrl);
            Console.WriteLine("token URL: " + token_heartbeatUrl);
        }
        
        public static string GetLocalIPv4()
        {
            foreach (var ip in Dns.GetHostEntry(Dns.GetHostName()).AddressList)
            {
                if (ip.AddressFamily == AddressFamily.InterNetwork && !IPAddress.IsLoopback(ip))
                {
                    return ip.ToString();
                }
            }
            return "127.0.0.1"; // fallback
        }
        public async Task<bool> LoginAndGetTokenAsync()
        {
            // init_heartbeat
            //var loginUrl = "http://zqd.superstar.dnsnet.cc/api/room/receiveRegister";
            string hostName = System.Net.Dns.GetHostName();

            var loginPayload = new
            {
                branch_name = "測試",
                room_name = "PC" + hostName.Substring(Math.Max(0, hostName.Length - 3)),
                room_ip = GetLocalIPv4(),
                email = "MachineKTV@gmail.com",
                password = "aa147258-"
            };

            var json = JsonSerializer.Serialize(loginPayload);
            var content = new StringContent(json, Encoding.UTF8, "application/json");

            try
            {
                var response = await httpClient.PostAsync(init_heartbeatUrl, content);
                response.EnsureSuccessStatusCode();

                var responseJson = await response.Content.ReadAsStringAsync();
                // Console.WriteLine("API 回傳內容：" + responseJson);

                using var doc = JsonDocument.Parse(responseJson);
                if (doc.RootElement.TryGetProperty("data", out JsonElement dataElement) &&
                    dataElement.ValueKind == JsonValueKind.Object)
                {
                    if (dataElement.TryGetProperty("token", out JsonElement tokenElement))
                    {
                        token = tokenElement.GetString();
                    }
                }
                // Console.WriteLine("登入成功，取得 token：" + token);
                return true;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"登入失敗：{ex.Message}");
                return false;
            }
        }

        public async Task SendHeartbeatAsync()
        {
            if (string.IsNullOrEmpty(token))
            {
                Console.WriteLine("請先登入取得 token");
                return;
            }
            //Console.WriteLine(GetLocalIPv4());
            string hostName = System.Net.Dns.GetHostName();

            var heartbeatData = new
            {
                branch_name = "測試",
                hostname = "PC" + hostName.Substring(Math.Max(0, hostName.Length - 3)),
                ip = GetLocalIPv4(),
                cpu = GetCpuUsage(),
                memory = GetTotalMemoryInMB(),
                disk = GetDiskTotalSizeInGB()
            };

            var json = JsonSerializer.Serialize(heartbeatData);
            var content = new StringContent(json, Encoding.UTF8, "application/json");
            // token_heartbeat
            // heartbeatUrl = "http://zqd.superstar.dnsnet.cc/api/room/heartbeat";
            var request = new HttpRequestMessage(HttpMethod.Post, token_heartbeatUrl);
            request.Content = content;
            request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
            // Console.WriteLine("送出的 JSON：");
            // Console.WriteLine(json);
            var response = await httpClient.SendAsync(request);
            try
            {

                // Console.WriteLine($"心跳送出狀態：{response.StatusCode}");

                response.EnsureSuccessStatusCode();

                var responseJson = await response.Content.ReadAsStringAsync();

                using var doc = JsonDocument.Parse(responseJson);
                // Console.WriteLine("API 回傳內容：" + responseJson);

            }
            catch (Exception ex)
            {
                var errorContent = await response.Content.ReadAsStringAsync();
                Console.WriteLine($"送出心跳錯誤：{ex.Message}");
                Console.WriteLine($"後端回應內容：{errorContent}");
            }
        }

        private float GetCpuUsage()
        {
            using var cpuCounter = new PerformanceCounter("Processor", "% Processor Time", "_Total");
            cpuCounter.NextValue(); // 需要呼叫兩次
            System.Threading.Thread.Sleep(100);
            return cpuCounter.NextValue(); // 回傳的是百分比，例如 25.3
        }
        private float GetTotalMemoryInMB()
        {
            var computerInfo = new ComputerInfo();
            return computerInfo.TotalPhysicalMemory / (1024f * 1024f); // 轉 MB
        }
        private float GetDiskTotalSizeInGB(string driveLetter = "C")
        {
            var drive = new DriveInfo(driveLetter);
            return drive.TotalSize / (1024f * 1024f * 1024f); // 轉 GB
        }
    }
}
