using log4net;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VIZ.Framework.Core;
using VIZ.Package.Domain;
using VIZ.Package.Service;

namespace VIZ.Package.Module
{
    /// <summary>
    /// 页模型控制器
    /// </summary>
    public class PageModelController
    {
        /// <summary>
        /// 日志
        /// </summary>
        private readonly static ILog log = LogManager.GetLogger(typeof(PageModelController));

        /// <summary>
        /// GH服务
        /// </summary>
        private GHService ghService = new GHService();

        /// <summary>
        /// Viz命令服务
        /// </summary>
        private VizCommandService vizCommandService = new VizCommandService();

        /// <summary>
        /// Viz控制对象下载服务
        /// </summary>
        private VizControlObjectDownloadService vizControlObjectDownloadService = new VizControlObjectDownloadService();

        /// <summary>
        /// 开始下载图片任务
        /// </summary>
        /// <param name="pages">页集合</param>
        public void BeginDownLoadIamge(List<PageModelBase> pages)
        {
            ThreadHelper.SafeRun(() =>
            {
                foreach (PageModelBase page in pages)
                {
                    if (page.ThumbnailBitmap != null)
                        continue;

                    if (string.IsNullOrWhiteSpace(page.ThumbnailUri))
                        continue;

                    var bitmap = this.ghService.GetImage(page.ThumbnailUri);

                    WPFHelper.BeginInvoke(() =>
                    {
                        page.ThumbnailBitmap = bitmap;
                    });
                }
            });
        }

        /// <summary>
        /// 开始下载控制对象
        /// </summary>
        /// <param name="pages">页集合</param>
        /// <param name="callback">下载完成回调</param>
        public void BeginDownLoadControlObject(List<PageModelBase> pages, Action callback)
        {
            if (pages == null || pages.Count == 0)
                return;

            PageLoadingWindow window = new PageLoadingWindow();
            window.Owner = ApplicationDomainEx.MainWindow;

            Task.Run(() =>
            {
                IMainViewService service = ApplicationDomainEx.ServiceManager.GetService<IMainViewService>(ViewServiceKeys.MAIN_VIEW_SERVICE);

                // 设置主窗口不可用
                WPFHelper.Invoke(() =>
                {
                    ApplicationDomainEx.IsSceneLoading = true;
                    service?.SetIsEnabled(false);
                    window?.Show();
                });

                // 下载页控制对象信息
                try
                {
                    this.vizControlObjectDownloadService.Load(pages);
                }
                catch (Exception ex)
                {
                    log.Error(ex);
                }
                finally
                {
                    // 恢复主窗口可用
                    WPFHelper.Invoke(() =>
                    {
                        ApplicationDomainEx.IsSceneLoading = false;
                        service?.SetIsEnabled(true);
                        window?.Close();

                        // 回调
                        callback?.Invoke();
                    });
                }
            });
        }

        /// <summary>
        /// 开始清理
        /// </summary>
        /// <param name="groups">链接分组</param>
        public void BeginTakeClear(List<ConnGroupModel> groups)
        {
            if (groups == null || groups.Count == 0)
                return;

            ThreadHelper.SafeRun(() =>
            {
                ApplicationDomainEx.IsSceneLoading = true;

                foreach (ConnGroupModel group in groups)
                {
                    if (group == ApplicationDomainEx.PreviewConnGroup)
                        continue;

                    if (group.Items == null || group.Items.Count == 0)
                        continue;

                    List<ConnModel> items = group.Items.ToList();

                    foreach (ConnModel item in items)
                    {
                        try
                        {
                            if (!item.IsEnabled || !item.IsConnected)
                                continue;

                            this.vizCommandService.TakeClear(item);
                        }
                        catch (Exception ex)
                        {
                            log.Error(ex);
                        }
                    }
                }

                ApplicationDomainEx.IsSceneLoading = true;
            });
        }

        /// <summary>
        /// 开始初始化页
        /// </summary>
        /// <param name="pages">页集合</param>
        public void BeginTakeInit(List<PageModel> pages)
        {
            if (pages == null || pages.Count == 0)
                return;

            ThreadHelper.SafeRun(() =>
            {
                ApplicationDomainEx.IsSceneLoading = true;

                // 清理状态
                WPFHelper.Invoke(() =>
                {
                    foreach (PageModel page in pages)
                    {
                        if (page.SceneInfo == null)
                            continue;

                        page.SceneInfo.TakeInitedProgress = 0d;
                        page.SceneInfo.TakeInitedMessage = null;
                    }
                });

                // 已经处理过的场景信息列表
                List<SceneInfoModel> executedList = new List<SceneInfoModel>();

                foreach (PageModel page in pages)
                {
                    if (page.SceneInfo == null)
                        continue;

                    if (executedList.Contains(page.SceneInfo))
                        continue;

                    executedList.Add(page.SceneInfo);

                    // 是否拥有关联的连接分组信息
                    ConnGroupModel group = ApplicationDomainEx.ConnGroups.FirstOrDefault(p => p.GroupID == page.ConnGroupID);
                    if (group == null)
                    {
                        WPFHelper.BeginInvoke(() =>
                        {
                            page.SceneInfo.TakeInitedMessage = $"未找到页关联的连接分组";
                        });
                        continue;
                    }

                    // 连接分组是否拥有可用的连接
                    var conns = group.Items.Where(p => p.IsEnabled).ToList();

                    if (conns.Count == 0)
                    {
                        WPFHelper.BeginInvoke(() =>
                        {
                            page.SceneInfo.TakeInitedMessage = $"连接分组没有连接可用";
                        });
                        continue;
                    }

                    int progressMax = conns.Count;
                    int progress = 0;

                    StringBuilder message = new StringBuilder();

                    foreach (ConnModel conn in conns)
                    {
                        try
                        {
                            if (!conn.IsConnected || !conn.IsEnabled)
                            {
                                message.AppendLine($"{conn.IP}:{conn.Port} 连接中断");
                                continue;
                            }

                            string result = this.vizCommandService.TakeInit(conn, page.ScenePath);
                            // 是否执行成功
                            if (result.StartsWith(ApplicationConstants.VIZ_COMMAND_RESULT_ERROR_PREFIX))
                            {
                                message.AppendLine(result);
                                continue;
                            }

                            ++progress;
                        }
                        catch (Exception ex)
                        {
                            log.Error(ex);
                            message.AppendLine(ex.Message);
                        }
                    }

                    WPFHelper.BeginInvoke(() =>
                    {
                        page.SceneInfo.TakeInitedProgress = (double)progress / (double)progressMax;
                        page.SceneInfo.TakeInitedMessage = message.ToString();
                    });
                }

                ApplicationDomainEx.IsSceneLoading = true;
            });
        }
    }
}
