using PCHMI;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace CowainHmi
{
    public class CsvHelper
    {
        public static void CreateCsv(string filePath, string[] colNames)
        {
            try
            {
                string directoryName = Path.GetDirectoryName(filePath);
                if (!Directory.Exists(directoryName) && directoryName.Length > 0)
                {
                    Directory.CreateDirectory(directoryName);
                }
                WriteRow(filePath, colNames.ToList());
            }
            catch (Exception ex)
            {
                new PClass().WErrTxt("CreateCsv错误:" + ex.ToString());
            }
        }

        public static void WriteRow(string dir, List<string> row)
        {
            WriteRow(dir, new List<List<string>> { row });
        }

        public static void DataTableToCsv(string filePath, DataTable tab)
        {
            try
            {
                if (tab == null || tab.Rows.Count <= 0)
                {
                    return;
                }

                List<List<string>> list = new List<List<string>>();
                string[] array = new string[tab.Columns.Count];
                List<string> list2 = new List<string>();
                foreach (DataColumn column in tab.Columns)
                {
                    list2.Add(column.ColumnName);
                }

                list.Add(list2);
                for (int i = 0; i < tab.Rows.Count; i++)
                {
                    for (int j = 0; j < tab.Columns.Count; j++)
                    {
                        array[j] = tab.Rows[i][j].ToString();
                    }

                    list.Add(array.ToList());
                }

                WriteLines(filePath, list);
            }
            catch (Exception ex)
            {
                new PClass().WErrTxt("DataTableToCsv错误:" + ex.ToString());
            }
        }

        public static void WriteLine(string dir, List<string> row)
        {
            WriteRow(dir, new List<List<string>> { row });
        }

        public static void WriteLines(string dir, List<List<string>> row)
        {
            WriteRow(dir, row);
        }

        public static void WriteRow(string dir, List<List<string>> row)
        {
            try
            {
                string text = "";
                string text2 = "";
                for (int i = 0; i < row.Count; i++)
                {
                    text = "";
                    for (int j = 0; j < row[i].Count; j++)
                    {
                        row[i][j] = row[i][j].Replace("\"", "\"\"");
                        if (row[i][j].IndexOf(",") > -1)
                        {
                            row[i][j] = "\"" + row[i][j] + "\"";
                        }

                        text = text + row[i][j] + ",";
                    }

                    if (text.Substring(text.Length - 1, 1) == ",")
                    {
                        text = text.Remove(text.Length - 1, 1);
                    }

                    text2 = text2 + text.TrimEnd(',') + "\r\n";
                }

                if (text2.Length > 2 && text2.Substring(text2.Length - 2, 2) == "\r\n")
                {
                    text2 = text2.Remove(text2.Length - 2, 2);
                }

                WriteTxt(text2, dir);
            }
            catch (Exception ex)
            {
                new PClass().WErrTxt("WriteRow错误:" + ex.ToString());
            }
        }

        public static void WriteTxt(string str, string URL)
        {
            byte[] bytes = Encoding.Default.GetBytes(str + "\r\n");
            try
            {
                FileStream fileStream = File.OpenWrite(URL);
                fileStream.Position = fileStream.Length;
                fileStream.Write(bytes, 0, bytes.Length);
                fileStream.Close();
            }
            catch (Exception ex)
            {
                new PClass().WErrTxt("WriteTxt错误:" + ex.ToString());
            }
        }

        public List<List<string>> ReadRow(string dir)
        {
            List<string> list = new List<string>(File.ReadAllLines(dir));
            List<List<string>> list2 = new List<List<string>>();
            for (int i = 0; i < list.Count; i++)
            {
                int j = 0;
                int num = 0;
                List<string> list3 = new List<string>();
                while (j < list[i].Length)
                {
                    string text;
                    if (list[i][j] == '"')
                    {
                        j++;
                        int num2 = j;
                        for (; j < list[i].Length; j++)
                        {
                            if (list[i][j] == '"')
                            {
                                j++;
                                if (j >= list[i].Length || list[i][j] != '"')
                                {
                                    j--;
                                    break;
                                }
                            }
                        }

                        text = list[i].Substring(num2, j - num2);
                        text = text.Replace("\"\"", "\"");
                    }
                    else
                    {
                        int num3 = j;
                        for (; j < list[i].Length && list[i][j] != ','; j++)
                        {
                        }

                        text = list[i].Substring(num3, j - num3);
                    }

                    if (num < list3.Count)
                    {
                        list3[num] = text;
                    }
                    else
                    {
                        list3.Add(text);
                    }

                    num++;
                    for (; j < list[i].Length && list[i][j] != ','; j++)
                    {
                    }

                    if (j < list[i].Length)
                    {
                        j++;
                    }
                }

                while (list3.Count > num)
                {
                    list3.RemoveAt(num);
                }

                list2.Add(list3);
            }

            return list2;
        }

        public static DataTable CsvToDataTable(string filePath)
        {
            return OpenCSV(filePath);
        }

        public static DataTable OpenCSV(string filePath)
        {
            DataTable dataTable = new DataTable();
            try
            {
                int num = 0;
                string pattern = "(?<=^|,)(\"(?:[^\"]|\"\")*\"|[^,]*)";
                List<string> list = new List<string>(File.ReadAllLines(filePath, Encoding.Default));
                int num2 = 0;
                int num3 = 0;
                for (int i = 0; i < list.Count; i++)
                {
                    num3++;
                    string input = list[i];
                    if (num3 < num + 1)
                    {
                        continue;
                    }

                    if (num3 == num + 1)
                    {
                        foreach (Match item in Regex.Matches(input, pattern))
                        {
                            dataTable.Columns.Add(item.Value);
                        }

                        continue;
                    }

                    MatchCollection matchCollection = Regex.Matches(input, "(?<=^|,)(\"(?:[^\"]|\"\")*\"|[^,]*)");
                    num2 = 0;
                    DataRow dataRow = dataTable.NewRow();
                    foreach (Match item2 in matchCollection)
                    {
                        string text = item2.Value;
                        if (text.Length > 2 && text.Substring(0, 1) == "\"" && text.Substring(text.Length - 1, 1) == "\"")
                        {
                            text = text.Remove(0, 1);
                            text = text.Remove(text.Length - 1, 1);
                        }

                        dataRow[num2] = text.Replace("\"\"", "\"");
                        num2++;
                    }

                    dataTable.Rows.Add(dataRow);
                }

                return dataTable;
            }
            catch (Exception ex)
            {
                new PClass().WErrTxt("OpenCSV错误:" + ex.ToString());
                return dataTable;
            }
        }

        public static Encoding GetType(string FILE_NAME)
        {
            FileStream fileStream = new FileStream(FILE_NAME, FileMode.Open, FileAccess.Read);
            Encoding type = GetType(fileStream);
            fileStream.Close();
            return type;
        }

        public static Encoding GetType(FileStream fs)
        {
            _ = new byte[3] { 255, 254, 65 };
            _ = new byte[3] { 254, 255, 0 };
            _ = new byte[3] { 239, 187, 191 };
            Encoding result = Encoding.Default;
            BinaryReader binaryReader = new BinaryReader(fs, Encoding.Default);
            int.TryParse(fs.Length.ToString(), out var result2);
            byte[] array = binaryReader.ReadBytes(result2);
            if (IsUTF8Bytes(array) || (array[0] == 239 && array[1] == 187 && array[2] == 191))
            {
                result = Encoding.UTF8;
            }
            else if (array[0] == 254 && array[1] == byte.MaxValue && array[2] == 0)
            {
                result = Encoding.BigEndianUnicode;
            }
            else if (array[0] == byte.MaxValue && array[1] == 254 && array[2] == 65)
            {
                result = Encoding.Unicode;
            }

            binaryReader.Close();
            return result;
        }

        private static bool IsUTF8Bytes(byte[] data)
        {
            int num = 1;
            for (int i = 0; i < data.Length; i++)
            {
                byte b = data[i];
                if (num == 1)
                {
                    if (b >= 128)
                    {
                        while (((b = (byte)(b << 1)) & 0x80u) != 0)
                        {
                            num++;
                        }

                        if (num == 1 || num > 6)
                        {
                            return false;
                        }
                    }
                }
                else
                {
                    if ((b & 0xC0) != 128)
                    {
                        return false;
                    }

                    num--;
                }
            }

            if (num > 1)
            {
                throw new Exception("非预期的byte格式");
            }

            return true;
        }
    }
}
