using System;
using System.Collections.Generic;
using System.Linq;
using FairyView;
using SimpleCore;
using SimpleCore.Library;
using StandardScene.Utils;

namespace StandardScene.Charge
{
    /// <summary>
    /// 充电桩管理辅助类
    /// 提供简化的静态方法用于快速访问充电桩功能
    /// </summary>
    public static class ChargeStationHelper
    {
        /// <summary>打开充电桩管理面板（单实例）。</summary>
        public static void OpenManagementWindow() => ChargeStationManagementForm.Open();

        /// <summary>打开充电桩管理面板（兼容旧 API）。</summary>
        public static void OpenManagementDialog() => ChargeStationManagementForm.Open();

        /// <summary>
        /// 获取指定站点的充电桩
        /// </summary>
        /// <param name="siteId">站点ID</param>
        /// <returns>充电桩对象，如果不存在则返回null</returns>
        public static ChargeStation GetStationBySiteId(int siteId)
        {
            var dataService = ChargeStationDataService.Instance;
            return dataService.GetAllStations()
                .FirstOrDefault(s => s.SiteId == siteId);
        }

        /// <summary>
        /// 获取指定IP的充电桩
        /// </summary>
        /// <param name="ipAddress">IP地址</param>
        /// <returns>充电桩对象，如果不存在则返回null</returns>
        public static ChargeStation GetStationByIp(string ipAddress)
        {
            var dataService = ChargeStationDataService.Instance;
            return dataService.GetAllStations()
                .FirstOrDefault(s => s.IpAddress == ipAddress);
        }

        /// <summary>
        /// 获取所有充电桩配置
        /// </summary>
        /// <returns>所有充电桩配置列表</returns>
        public static List<ChargeStation> GetAllStationConfigs()
        {
            var dataService = ChargeStationDataService.Instance;
            return dataService.GetAllStations();
        }

        /// <summary>
        /// 获取当前充电策略配置
        /// </summary>
        /// <returns>充电策略配置对象</returns>
        public static ChargeStrategyConfig GetChargeStrategyConfig()
        {
            var configService = ChargeStrategyConfigService.Instance;
            return configService.LoadConfig();
        }

        /// <summary>
        /// 保存充电策略配置
        /// </summary>
        /// <param name="config">充电策略配置对象</param>
        public static void SaveChargeStrategyConfig(ChargeStrategyConfig config)
        {
            var configService = ChargeStrategyConfigService.Instance;
            configService.SaveConfig(config);
        }

        /// <summary>
        /// 检查指定站点是否有可用的充电桩
        /// </summary>
        /// <param name="siteId">站点ID</param>
        /// <returns>true表示有可用充电桩，false表示没有</returns>
        public static bool IsSiteHasAvailableChargeStation(int siteId)
        {
            var station = GetStationBySiteId(siteId);
            return station != null && 
                   station.Enabled && 
                   station.Status == ChargeStationStatus.Idle;
        }

        /// <summary>
        /// 标记充电桩开始充电
        /// </summary>
        /// <param name="stationId">充电桩编号</param>
        /// <param name="carId">车辆ID</param>
        /// <returns>成功返回true，失败返回false</returns>
        public static bool StartCharging(string stationId, int carId)
        {
            try
            {
                var dataService = ChargeStationDataService.Instance;
                var station = dataService.GetStationById(stationId);

                if (station == null)
                {
                    Diagnosis.Log($"充电桩 {stationId} 不存在", "ChargeStation", true);
                    return false;
                }

                if (station.Status == ChargeStationStatus.Charging)
                {
                    Diagnosis.Log($"充电桩 {station.Name} 已经在充电中", "ChargeStation", true);
                    return false;
                }

                bool success = dataService.UpdateStationStatus(stationId, ChargeStationStatus.Charging);

                if (success)
                {
                    Diagnosis.Log($"车辆 {carId} 开始在充电桩 {station.Name} 充电", "ChargeStation", true);
                }

                return success;
            }
            catch (Exception ex)
            {
                Diagnosis.Log($"启动充电失败: {ExceptionFormatter.FormatEx(ex)}", "ChargeStation", true);
                return false;
            }
        }

        /// <summary>
        /// 标记充电桩停止充电
        /// </summary>
        /// <param name="stationId">充电桩编号</param>
        /// <param name="carId">车辆ID</param>
        /// <returns>成功返回true，失败返回false</returns>
        public static bool StopCharging(string stationId, int carId)
        {
            try
            {
                var dataService = ChargeStationDataService.Instance;
                var station = dataService.GetStationById(stationId);

                if (station == null)
                {
                    Diagnosis.Log($"充电桩 {stationId} 不存在", "ChargeStation", true);
                    return false;
                }

                bool success = dataService.UpdateStationStatus(stationId, ChargeStationStatus.Idle);

                if (success)
                {
                    Diagnosis.Log($"车辆 {carId} 在充电桩 {station.Name} 充电完成", "ChargeStation", true);
                }

                return success;
            }
            catch (Exception ex)
            {
                Diagnosis.Log($"停止充电失败: {ExceptionFormatter.FormatEx(ex)}", "ChargeStation", true);
                return false;
            }
        }

        /// <summary>
        /// 标记充电桩为故障状态
        /// </summary>
        /// <param name="stationId">充电桩编号</param>
        /// <param name="reason">故障原因</param>
        /// <returns>成功返回true，失败返回false</returns>
        public static bool MarkAsFault(string stationId, string reason = "")
        {
            try
            {
                var dataService = ChargeStationDataService.Instance;
                bool success = dataService.UpdateStationStatus(stationId, ChargeStationStatus.Fault);

                if (success)
                {
                    var station = dataService.GetStationById(stationId);
                    var message = string.IsNullOrEmpty(reason) 
                        ? $"充电桩 {station.Name} 标记为故障" 
                        : $"充电桩 {station.Name} 标记为故障: {reason}";
                    
                    Diagnosis.Log(message, "ChargeStation", true);
                }

                return success;
            }
            catch (Exception ex)
            {
                Diagnosis.Log($"标记故障失败: {ExceptionFormatter.FormatEx(ex)}", "ChargeStation", true);
                return false;
            }
        }

        /// <summary>
        /// 获取充电桩状态摘要信息
        /// </summary>
        /// <returns>格式化的状态字符串</returns>
        public static string GetStatusSummary()
        {
            var dataService = ChargeStationDataService.Instance;
            var stations = dataService.GetAllStations();

            var total = stations.Count;
            var idle = stations.Count(s => s.Status == ChargeStationStatus.Idle && s.Enabled);
            var charging = stations.Count(s => s.Status == ChargeStationStatus.Charging);
            var fault = stations.Count(s => s.Status == ChargeStationStatus.Fault);
            var offline = stations.Count(s => s.Status == ChargeStationStatus.Battery);

            return $"总数:{total} | 空闲:{idle} | 充电中:{charging} | 故障:{fault} | 离线:{offline}";
        }

        /// <summary>
        /// 获取最近的空闲充电桩（基于站点ID）
        /// </summary>
        /// <param name="currentSiteId">当前站点ID</param>
        /// <returns>最近的充电桩，如果没有则返回null</returns>
        public static ChargeStation FindNearestIdleStation(int currentSiteId)
        {
            var dataService = ChargeStationDataService.Instance;
            var idleStations = dataService.GetIdleStations();

            if (idleStations.Count == 0)
                return null;

            // 优先选择同站点的充电桩
            var sameStation = idleStations.FirstOrDefault(s => s.SiteId == currentSiteId);
            if (sameStation != null)
                return sameStation;

            // 否则选择第一个可用的
            return idleStations[0];
        }

        /// <summary>
        /// 快速创建测试充电桩（用于测试）
        /// </summary>
        /// <param name="name">名称</param>
        /// <param name="ip">IP地址</param>
        /// <param name="siteId">站点ID</param>
        /// <returns>创建成功返回true</returns>
        public static bool QuickAddStation(string name, string ip, int? siteId = null)
        {
            var dataService = ChargeStationDataService.Instance;

            var station = new ChargeStation
            {
                Name = name,
                IpAddress = ip,
                Port = 502,
                SetVoltage = 220.0,
                SetElectricCurrent = 32.0,
                Status = ChargeStationStatus.Idle,
                Enabled = true,
                SiteId = siteId,
                Remarks = $"快速创建于 {DateTime.Now}"
            };

            bool success = dataService.AddStation(station, out string errorMsg);

            if (success)
            {
                Diagnosis.Log($"快速创建充电桩: {name}", "ChargeStation", true);
            }
            else
            {
                Diagnosis.Log($"快速创建充电桩失败: {errorMsg}", "ChargeStation", true);
            }

            return success;
        }

        /// <summary>显示充电桩选择面板（非阻塞；通过 <paramref name="onSelected"/> 回调返回结果）。</summary>
        public static void ShowStationSelectionDialog(ChargeStationStatus? filterByStatus, System.Action<ChargeStation> onSelected)
        {
            var stations = ChargeStationDataService.Instance.GetAllStations();
            if (filterByStatus.HasValue)
                stations = stations.Where(s => s.Status == filterByStatus.Value).ToList();

            if (stations.Count == 0)
            {
                FairyUiHelper.Alert("提示", "没有符合条件的充电桩");
                onSelected?.Invoke(null);
                return;
            }

            var labels = stations.Select(s =>
                $"[{s.StationId}] {s.Name} - {s.IpAddress}:{s.Port} - {GetStatusText(s.Status)}").ToArray();
            int sel = 0;
            var dlg = GUI.DeclarePanel()
                .ShowTitle("选择充电桩")
                .TopMost(true)
                .ForceFloat()
                .InitSize(520, 400)
                .InitPos(false, 0, 0, 0.5f, 0.5f, 0.5f, 0.5f);
            dlg.Define(pb =>
            {
                if (pb.Closing()) { dlg.Exit(); onSelected?.Invoke(null); return; }
                sel = pb.ListBox("充电桩", labels, height: 12);
                if (pb.Button("确定", distinct: "cs-pick-ok"))
                {
                    dlg.Exit();
                    onSelected?.Invoke(sel >= 0 && sel < stations.Count ? stations[sel] : null);
                }
                pb.SameLine(8);
                if (pb.Button("取消", distinct: "cs-pick-cancel"))
                {
                    dlg.Exit();
                    onSelected?.Invoke(null);
                }
            });
        }

        /// <summary>
        /// 获取状态文本
        /// </summary>
        private static string GetStatusText(ChargeStationStatus status)
        {
            switch (status)
            {
                case ChargeStationStatus.Idle: return "空闲";
                case ChargeStationStatus.Charging: return "充电中";
                case ChargeStationStatus.Fault: return "故障";
                case ChargeStationStatus.Battery: return "离线";
                default: return "未知";
            }
        }

        /// <summary>
        /// 批量更新充电桩在线状态（用于定期监控）
        /// </summary>
        /// <param name="timeout">超时时间（毫秒）</param>
        /// <returns>更新的充电桩数量</returns>
        public static int UpdateOnlineStatus(int timeout = 3000)
        {
            var dataService = ChargeStationDataService.Instance;
            var stations = dataService.GetAllStations().Where(s => s.Enabled).ToList();
            int updatedCount = 0;

            foreach (var station in stations)
            {
                try
                {
                    // 这里应该实际ping充电桩，此处仅演示
                    bool isOnline = PingStation(station.IpAddress, station.Port, timeout);

                    var expectedStatus = isOnline 
                        ? (station.Status == ChargeStationStatus.Battery ? ChargeStationStatus.Idle : station.Status)
                        : ChargeStationStatus.Battery;

                    if (station.Status != expectedStatus && 
                        (station.Status == ChargeStationStatus.Battery || expectedStatus == ChargeStationStatus.Battery))
                    {
                        if (dataService.UpdateStationStatus(station.StationId, expectedStatus))
                        {
                            updatedCount++;
                            Diagnosis.Log($"充电桩 {station.Name} 状态更新为: {GetStatusText(expectedStatus)}", 
                                "ChargeStation", true);
                        }
                    }
                }
                catch (Exception ex)
                {
                    Diagnosis.Log($"检查充电桩 {station.Name} 在线状态失败: {ex.Message}", 
                        "ChargeStation");
                }
            }

            return updatedCount;
        }

        /// <summary>
        /// Ping 充电桩（检查连通性）
        /// </summary>
        private static bool PingStation(string ip, int port, int timeout)
        {
            try
            {
                using (var client = new System.Net.Sockets.TcpClient())
                {
                    var result = client.BeginConnect(ip, port, null, null);
                    var success = result.AsyncWaitHandle.WaitOne(TimeSpan.FromMilliseconds(timeout));

                    if (success)
                    {
                        client.EndConnect(result);
                        return true;
                    }
                    return false;
                }
            }
            catch
            {
                return false;
            }
        }
    }
}



