using System;
using System.Data;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using Microsoft.Extensions.Logging;
using PowerEasy.WebFuture.DataMigrations.Foundation.Log;

namespace PowerEasy.WebFuture.DataMigrations.Foundation.Utilities
{
    /// <summary>
    /// 迁移帮助类。
    /// </summary>
    public static class MigrateHelper
    {
        /// <summary>
        /// 替换附件路径。
        /// </summary>
        /// <param name="path">路径。</param>
        /// <param name="uploadPath">上传目录。</param>
        /// <returns>返回处理后路径。</returns>
        public static string AddUploadPathFlag(string path, string uploadPath)
        {
            if (string.IsNullOrEmpty(path))
            {
                return path;
            }

            if (!path.StartsWith("http") && !path.StartsWith("$") && !path.StartsWith("file") && !path.StartsWith("data:image"))
            {
                if (path.StartsWith("/"))
                {
                    path = uploadPath + path;
                    path = path.ToLower();
                }
                else
                {
                    path = uploadPath + "/" + path;
                    path = path.ToLower();
                }
            }

            return path;
        }

        /// <summary>
        /// 替换附件路径。
        /// </summary>
        /// <param name="content">内容。</param>
        /// <param name="uploadPath">上传目录。</param>
        /// <returns>返回处理后路径。</returns>
        public static string ReplaceContentUploadPath(string content, string uploadPath)
        {
            if (string.IsNullOrEmpty(content))
            {
                return content;
            }

            content = Regex.Replace(content, "((src|href)\\s*=\\s*(\"|\'))(([^(http|$|https|mailto|file:|data:image|#)]/*))", "$1" + uploadPath + "$4".ToLower(), RegexOptions.IgnoreCase);

            content = Regex.Replace(content, "((src|href)\\s*=\\s*(\"|\'))([^\"']*)(\"|\')", m =>
            {
                // 获取src或href的路径部分
                string pathPart = m.Groups[0].Value;

                // 检查路径中是否包含$/
                if (pathPart.Contains("$/"))
                {
                    // 将路径部分转换为小写
                    pathPart = pathPart.ToLower();
                }

                // 重新构造src或href属性
                return pathPart;
            }, RegexOptions.IgnoreCase);

            return content;
        }

        /// <summary>
        /// 从内容字段得到处理过的简介，过滤HTML标签。
        /// </summary>
        /// <param name="content">内容。</param>
        /// <returns>简介。</returns>
        public static string FilterHTMLTag(string content)
        {
            if (string.IsNullOrEmpty(content))
            {
                return string.Empty;
            }

            var intro = Regex.Replace(content, "<table[^>]*>((?!table).)*<\\/table>", string.Empty); // 去除表格。

            string pattern = "<style>.*?</style>";

            intro = Regex.Replace(intro, pattern, string.Empty, RegexOptions.Singleline | RegexOptions.IgnoreCase);
            intro = Regex.Replace(intro, "<STYLE[^>]*>((?!STYLE).)*<\\/STYLE>", string.Empty); // 去除style。
            intro = Regex.Replace(intro, "<style[^>]*>((?!style).)*<\\/style>", string.Empty); // 去除style。
            intro = intro.Replace("</p>", "\n"); // p标签变成换行符。
            intro = intro.Replace("<br />", "\n"); // 换行标签变成换行符。
            intro = Regex.Replace(intro, "\\s*<div class=\"image-title\".*>.*div>", string.Empty); // 去除图片注释。
            intro = Regex.Replace(intro, "<\\/?[^>]*>", string.Empty); // 去除HTML Tag。
            intro = intro.Replace("&nbsp;", string.Empty); // 去掉nbsp。
            intro = Regex.Replace(intro, "\n(\n)*( )*(\n)*\n", "\n"); // 去掉多余的换行。
            intro = Regex.Replace(intro, "^\n+|\n+$/g", string.Empty); // 去掉开头和结尾的换行。
            intro = intro.TrimStart("/n/r".ToCharArray()); // 去掉开头和结尾的换行。
            intro = intro.TrimStart("\n\r".ToCharArray()); // 去掉开头和结尾的换行。
            intro = intro.TrimEnd("/n/r".ToCharArray()); // 去掉开头和结尾的换行。
            intro = intro.TrimEnd("\n\r".ToCharArray()); // 去掉开头和结尾的换行。

            if (intro.Length > 300)
            {
                intro = intro.Substring(0, 300);
            }

            return intro;
        }

        /// <summary>
        /// 根据映射后的对象，反射赋值给新目标行对应字段。
        /// </summary>
        /// <param name="obj">。映射后的对象。</param>
        /// <param name="newRow">新目标数据库表的行。</param>
        /// <returns>返回处理后的数据库行数据。</returns>
        public static DataRow GetMapperDataRow(object obj, DataRow newRow)
        {
            PropertyInfo[] properties = obj.GetType().GetProperties();

            foreach (PropertyInfo property in properties)
            {
                var value = property.GetValue(obj, null);

                // 检查属性是否可为空。
                if (property.PropertyType.IsGenericType && property.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
                {
                    // 可空类型，检查是否有值。
                    if (value != null)
                    {
                        newRow[property.Name] = value;
                    }
                    else
                    {
                        newRow[property.Name] = DBNull.Value;
                    }
                }
                else
                {
                    // 非可空类型，直接赋值。
                    newRow[property.Name] = value ?? DBNull.Value;
                }
            }

            return newRow;
        }

        /// <summary>
        /// 根据列名获取数据（string。）
        /// </summary>
        /// <param name="sourceDataRow">数据行。</param>
        /// <param name="columnName">列名。</param>
        /// <returns>返回对应值。</returns>
        public static string GetColumnValueString(DataRow sourceDataRow, string columnName)
        {
            var value = string.Empty;

            // 检查数据行和列名是否为空。
            if (sourceDataRow == null || string.IsNullOrEmpty(columnName))
            {
                return value;
            }

            // 检查指定列名是否存在于数据行中。
            if (!sourceDataRow.Table.Columns.Contains(columnName))
            {
                return value;
            }

            // 获取列值，如果为空则返回空字符串。
            value = sourceDataRow[columnName]?.ToString().Trim() ?? string.Empty;

            return value;
        }

        /// <summary>
        /// 根据列名获取数据（int）。
        /// </summary>
        /// <param name="sourceDataRow">数据行。</param>
        /// <param name="columnName">列名。</param>
        /// <returns>返回对应值，如果无法转换为int，则返回默认值0。</returns>
        public static int GetColumnValueInt(DataRow sourceDataRow, string columnName)
        {
            int value = 0;

            // 检查数据行和列名是否为空。
            if (sourceDataRow == null || string.IsNullOrEmpty(columnName))
            {
                return value;
            }

            // 检查指定列名是否存在于数据行中。
            if (!sourceDataRow.Table.Columns.Contains(columnName))
            {
                return value;
            }

            // 尝试获取列值并转换为int。
            if (sourceDataRow[columnName] != DBNull.Value && int.TryParse(sourceDataRow[columnName].ToString(), out value))
            {
                return value;
            }
            else
            {
                LogHelper.WriteLogAndFormLog(columnName + " 列转换成int出错！");
            }

            // 如果转换失败或值为DBNull.Value，则返回默认值0。
            return 0;
        }

        /// <summary>
        /// 根据列名获取数据（DateTime），如果无法转换则返回默认值。
        /// </summary>
        /// <param name="sourceDataRow">数据行。</param>
        /// <param name="columnName">列名。</param>
        /// <param name="defaultValue">默认值，如果不提供，则使用当前时间。</param>
        /// <returns>返回对应值，如果无法转换为DateTime，则返回提供的默认值或当前时间。</returns>
        public static DateTime GetColumnValueDateTime(DataRow sourceDataRow, string columnName, DateTime? defaultValue = null)
        {
            // 检查数据行和列名是否为空。
            if (sourceDataRow == null || string.IsNullOrEmpty(columnName))
            {
                return defaultValue ?? DateTime.Now;
            }

            // 检查指定列名是否存在于数据行中。
            if (!sourceDataRow.Table.Columns.Contains(columnName))
            {
                return defaultValue ?? DateTime.Now;
            }

            // 尝试获取列值并转换为DateTime。
            object columnValue = sourceDataRow[columnName];
            if (columnValue != DBNull.Value && DateTime.TryParse(columnValue.ToString(), out DateTime value))
            {
                return value;
            }
            else
            {
                LogHelper.WriteLogAndFormLog(columnName + " 列转换成DateTime出错！");
            }

            // 如果转换失败或值为DBNull.Value，则返回默认值或当前时间。
            return defaultValue ?? DateTime.Now;
        }
    }
}
