using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PushPlatform.Common.Util
{
    public class DataTableHelp
    {
        #region 合并一样的DT
        public static DataTable hebingSameStructure(DataTable DataTable1, DataTable DataTable2)
        {
            DataTable newDataTable = DataTable1.Clone();

            object[] obj = new object[newDataTable.Columns.Count];
            for (int i = 0; i < DataTable1.Rows.Count; i++)
            {
                DataTable1.Rows[i].ItemArray.CopyTo(obj, 0);
                newDataTable.Rows.Add(obj);
            }

            for (int i = 0; i < DataTable2.Rows.Count; i++)
            {
                DataTable2.Rows[i].ItemArray.CopyTo(obj, 0);
                newDataTable.Rows.Add(obj);
            }
            return newDataTable;
        }
        #endregion

        #region 合并不一样的DT
        /// <summary>
        /// 将两个列不同的DataTable合并成一个新的DataTable
        /// </summary>
        /// <param name="dt1">表1</param>
        /// <param name="dt2">表2</param>
        /// <param name="DTName">合并后新的表名</param>
        /// <returns></returns>
        public static DataTable UniteDataTable(DataTable dt1, DataTable dt2, string DTName)
        {
            DataTable dt3 = dt1.Clone();
            for (int i = 0; i < dt2.Columns.Count; i++)
            {
                if (dt3.Columns.Contains(dt2.Columns[i].ColumnName))
                {
                    continue;
                }
                dt3.Columns.Add(dt2.Columns[i].ColumnName);
            }
            object[] obj = new object[dt3.Columns.Count];

            for (int i = 0; i < dt1.Rows.Count; i++)
            {
                dt1.Rows[i].ItemArray.CopyTo(obj, 0);
                dt3.Rows.Add(obj);
            }

            if (dt1.Rows.Count >= dt2.Rows.Count)
            {
                for (int i = 0; i < dt2.Rows.Count; i++)
                {
                    for (int j = 0; j < dt2.Columns.Count; j++)
                    {
                        dt3.Rows[i][j + dt1.Columns.Count] = dt2.Rows[i][j].ToString();
                    }
                }
            }
            else
            {
                DataRow dr3;
                for (int i = 0; i < dt2.Rows.Count - dt1.Rows.Count; i++)
                {
                    dr3 = dt3.NewRow();
                    dt3.Rows.Add(dr3);
                }
                for (int i = 0; i < dt2.Rows.Count; i++)
                {
                    for (int j = 0; j < dt2.Columns.Count; j++)
                    {
                        dt3.Rows[i][j + dt1.Columns.Count] = dt2.Rows[i][j].ToString();
                    }
                }
            }
            dt3.TableName = DTName; //设置DT的名字
            return dt3;
        }
        #endregion
    
        #region 根据patientId将多行记录何在一行上
        public static DataTable ToOneRow(DataTable table)
        {
            DataTable returnTable = table.Clone();

            //用户Id
            string userId = string.Empty;
            //第几行同一用户
            int sameUserCount = 0;
            //同一用户所在行
            int sheetRowIndex = 0;
            foreach (DataRow row in table.Rows)
            {
                //与上一行是否同一用户
                bool isSameUser = false;
                if (userId == row[0].ToString())
                {
                    isSameUser = true;
                    sameUserCount++;
                }
                else if (string.IsNullOrEmpty(userId))
                {
                    userId = row[0].ToString();
                    sameUserCount = 0;
                }
                else
                {
                    userId = row[0].ToString();
                    sameUserCount = 0;
                    ++sheetRowIndex;
                }

                if (!isSameUser)
                {
                    DataRow newrow = returnTable.NewRow();
                    foreach (DataColumn column in table.Columns)
                    {
                        newrow[column.ColumnName] = row[column.ColumnName];
                    }
                    returnTable.Rows.Add(newrow);
                }
                else
                {
                    foreach (DataColumn column in table.Columns)
                    {
                        if (
                            column.Caption == "PatientID" || column.Caption == "_id"
                            )
                        {
                            continue;
                        }
                        else
                        {
                            if (!returnTable.Columns.Contains(column.ColumnName + sameUserCount.ToString()))
                            {
                                returnTable.Columns.Add(column.ColumnName + sameUserCount.ToString());
                            }
                            returnTable.Rows[sheetRowIndex][column.ColumnName + sameUserCount.ToString()] = row[column.ColumnName];
                        }
                    }
                }
            }
            return returnTable;
        }
        #endregion

        #region 根据自定义的某行将多行记录何在一行上
        public static DataTable ToOneRow(string basisColumn,DataTable table,List<string> notHecolumn)
        {
            DataTable returnTable = table.Clone();
            foreach(DataColumn dc in returnTable.Columns)
            {
                if (notHecolumn.IndexOf(dc.ColumnName) > -1)
                    continue;
                else
                    dc.ColumnName = dc.ColumnName + "_1";
            }

            //用户Id
            string userId = string.Empty;
            //第几行同一用户
            int sameUserCount = 1;
            //同一用户所在行
            int sheetRowIndex = 0;
            foreach (DataRow row in table.Rows)
            {
                //与上一行是否同一用户
                bool isSameUser = false;
                if (userId == row[basisColumn].ToString())
                {
                    isSameUser = true;
                    sameUserCount++;
                }
                else if (string.IsNullOrEmpty(userId))
                {
                    userId = row[basisColumn].ToString();
                    sameUserCount = 1;
                }
                else
                {
                    userId = row[basisColumn].ToString();
                    sameUserCount = 1;
                    ++sheetRowIndex;
                }

                if (!isSameUser)
                {
                    DataRow newrow = returnTable.NewRow();
                    foreach (DataColumn column in table.Columns)
                    {
                        if (notHecolumn.IndexOf(column.ColumnName) > -1)
                            newrow[column.ColumnName] = row[column.ColumnName];
                        else
                            newrow[column.ColumnName+"_1"] = row[column.ColumnName];
                    }
                    returnTable.Rows.Add(newrow);
                }
                else
                {
                    foreach (DataColumn column in table.Columns)
                    {
                        if (notHecolumn.IndexOf(column.Caption)>-1)
                        {
                            continue;
                        }
                        else
                        {
                            if (!returnTable.Columns.Contains(column.ColumnName +"_"+ sameUserCount.ToString()))
                            {
                                returnTable.Columns.Add(column.ColumnName + "_" + sameUserCount.ToString());
                            }
                            returnTable.Rows[sheetRowIndex][column.ColumnName + "_" + sameUserCount.ToString()] = row[column.ColumnName];
                        }
                    }
                }
            }
            return returnTable;
        }
        #endregion

        #region 合并不一样的DT,到目标datatable上
        /// <summary>
        /// 将两个列不同的DataTable合并成一个新的DataTable
        /// </summary>
        /// <param name="dt1">表1目标datatable</param>
        /// <param name="dt2">表2源dataTable</param>
        /// <returns></returns>
        public static DataTable AddDataTable(DataTable dt1, DataTable dt2)
        {
            for (int i = 0; i < dt2.Columns.Count; i++)
            {
                if (dt2.Columns[i].ColumnName == "patientId")
                {
                    continue;
                }
                dt1.Columns.Add(dt2.Columns[i].ColumnName);
            }
            foreach (DataRow v in dt2.Rows)
            {
                DataRow oldrow = dt1.Select("patientId='" + v["patientId"] + "'").FirstOrDefault();
                if(oldrow == null)
                {
                    continue;
                }
                foreach (DataColumn column in dt2.Columns)
                {
                    if (column.ColumnName != "patientId")
                    {
                        oldrow[column.ColumnName] = v[column.ColumnName];
                    }
                }
            }
            return dt1;
        }

        /// <summary>
        /// 将两个列不同的DataTable合并成一个新的DataTable
        /// </summary>
        /// <param name="dt1">表1目标datatable</param>
        /// <param name="dt2">表2源dataTable</param>
        /// <returns></returns>
        public static DataTable AddDataTable(DataTable dt1, DataTable dt2,string bsaeName)
        {
            for (int i = 0; i < dt2.Columns.Count; i++)
            {
                if (dt2.Columns[i].ColumnName == bsaeName)
                {
                    continue;
                }
                dt1.Columns.Add(dt2.Columns[i].ColumnName);
            }
            foreach (DataRow v in dt2.Rows)
            {
                DataRow oldrow = dt1.Select(""+ bsaeName + "='" + v[bsaeName] + "'").FirstOrDefault();
                if (oldrow == null)
                {
                    continue;
                }
                foreach (DataColumn column in dt2.Columns)
                {
                    if (column.ColumnName != bsaeName)
                    {
                        oldrow[column.ColumnName] = v[column.ColumnName];
                    }
                }
            }
            return dt1;
        }
        #endregion

        #region 合并不一样的DT,到目标datatable上(自定义参数)
        /// <summary>
        /// 将两个列不同的DataTable合并成一个新的DataTable
        /// </summary>
        /// <param name="dt1">表1目标datatable</param>
        /// <param name="dt2">表2源dataTable</param>
        /// <returns></returns>
        public static DataTable AddDataTable(DataTable dt1, DataTable dt2,List<string> notHeColumn,List<string> conditionsColumn)
        {
            for (int i = 0; i < dt2.Columns.Count; i++)
            {
                if (notHeColumn.IndexOf(dt2.Columns[i].ColumnName)>-1 || dt1.Columns.Contains(dt2.Columns[i].ColumnName))
                {
                    continue;
                }
                dt1.Columns.Add(dt2.Columns[i].ColumnName);
            }
            foreach (DataRow v in dt2.Rows)
            {
                DataRow oldrow = dt1.Select("patientId='" + v["patientId"] + "' and  mongoId='" + v["mongoId"] + "'").FirstOrDefault();
                foreach (DataColumn column in dt2.Columns)
                {
                    if (notHeColumn.IndexOf(column.ColumnName) < 0)
                    {
                        oldrow[column.ColumnName] = v[column.ColumnName];
                    }
                }
            }
            return dt1;
        }
        #endregion

        #region 合并不一样的DT,到目标datatable上(自定义参数),占位指定位置
        /// <summary>
        /// 将两个列不同的DataTable合并成一个新的DataTable
        /// </summary>
        /// <param name="dt1">表1目标datatable</param>
        /// <param name="dt2">表2源dataTable</param>
        /// <returns></returns>
        public static DataTable AddDataTable(DataTable dt1, DataTable dt2, List<string> notHeColumn, List<string> conditionsColumn,string ZhanWeiName)
        {
            int beginIndex = 0;
            for (int i = 0; i < dt2.Columns.Count; i++)
            {
                if (notHeColumn.IndexOf(dt2.Columns[i].ColumnName) > -1 || dt1.Columns.Contains(dt2.Columns[i].ColumnName))
                {
                    continue;
                }
                if (beginIndex == 0)
                    beginIndex = dt1.Columns[ZhanWeiName].Ordinal + 1;
                dt1.Columns.Add(dt2.Columns[i].ColumnName).SetOrdinal(beginIndex++);
            }
            foreach (DataRow v in dt2.Rows)
            {
                DataRow oldrow = dt1.Select("patientId='" + v["patientId"] + "' and  mongoId='" + v["mongoId"] + "'").FirstOrDefault();
                foreach (DataColumn column in dt2.Columns)
                {
                    if (notHeColumn.IndexOf(column.ColumnName) < 0)
                    {
                        oldrow[column.ColumnName] = v[column.ColumnName];
                    }
                }
            }
            dt1.Columns.Remove(ZhanWeiName);
            return dt1;
        }
        #endregion

        #region 合并不一样的DT(linq实现)
        /// <summary>
        /// 将两个列不同的DataTable合并成一个新的DataTable
        /// </summary>
        /// <param name="dt1">表1</param>
        /// <param name="dt2">表2</param>
        /// <param name="DTName">合并后新的表名</param>
        /// <returns></returns>
        public static DataTable UniteDataTableOfLinq(DataTable dt1, DataTable dt2)
        {
            DataTable DtAll = dt1.Clone();
            foreach (DataColumn v in dt2.Columns)
            {
                if (v.ColumnName != "userId")
                {
                    DtAll.Columns.Add(v.ColumnName);
                }
            }
            var query =
                from rHead in dt1.AsEnumerable()
                join rTail in dt2.AsEnumerable()
                on rHead.Field<string>("userId") equals rTail.Field<string>("userId")
                select rHead.ItemArray.Concat(rTail.ItemArray.Skip(1));

            foreach (var obj in query)
            {
                DataRow dr = DtAll.NewRow();
                dr.ItemArray = obj.ToArray();
                DtAll.Rows.Add(dr);
            }
            return DtAll;
        }
        #endregion

    }
}
