using System;  
using System.Collections.Generic;  
using System.Data;  
using System.Linq;  
using System.IO;  
using System.Data.OleDb; 

namespace LFP_Manager.Function
{
    public static class csExcelExport
    {
        public static void ExportToExcel(this DataTable dataTable, String filePath, bool overwiteFile = true)  
        {
            if (Directory.Exists(Path.GetDirectoryName(filePath)) == false)
                Directory.CreateDirectory(Path.GetDirectoryName(filePath));
            if (File.Exists(filePath) && overwiteFile)
                File.Delete(filePath);

            //var conn = String.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Extended Properties='Excel 8.0;HDR=Yes;IMEX=0';", filePath);
            var conn = "";

            if (filePath.IndexOf(".xlsx") > -1)      // 확장자에 따라서 provider 주의
                conn = String.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties='Excel 12.0;HDR=Yes;IMEX=3';", filePath);
            else
                conn = String.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Extended Properties='Excel 8.0;HDR=Yes;IMEX=3';", filePath);

            using (OleDbConnection connection = new OleDbConnection(conn))  
            {  
                connection.Open();  
                using (OleDbCommand command = new OleDbCommand())  
                {  
                    command.Connection = connection;
                    List<String> columnNames = new List<string>();
                    List<String> columnTypes = new List<string>();
                    foreach (DataColumn dataColumn in dataTable.Columns)  
                    {  
                        columnNames.Add(dataColumn.ColumnName);
                        string tName = "VARCHAR";
                        switch (dataColumn.DataType.Name)
                        {
                            case "Int16": tName = "INTEGER"; break;
                            case "Int32": tName = "INTEGER"; break;
                            case "Int64": tName = "INTEGER"; break;
                            case "Double": tName = "DOUBLE"; break;
                            case "String": tName = "VARCHAR"; break;
                            default: tName = dataColumn.DataType.Name; break;
                        }
                        columnTypes.Add(tName);
                    }
                    String tableName = !String.IsNullOrWhiteSpace(dataTable.TableName) ? dataTable.TableName : Guid.NewGuid().ToString();  
                    //command.CommandText = @"CREATE TABLE [{tableName}] ({String.Join(",", columnNames.Select(c => $"[{c}] VARCHAR").ToArray())});";
                    //string join = String.Join(",", columnNames.Select(c => String.Format("[{0}] VARCHAR", c)).ToArray());
                    string join = "";
                    for (int i = 0; i < columnNames.Count; i++)
                    {
                        join += String.Format("[{0}] {1}", columnNames[i], columnTypes[i]);
                        if (i < (columnNames.Count - 1)) join += ",";
                    }
                    command.CommandText = String.Format("CREATE TABLE [{0}] ({1});", 
                        tableName,
                        join
                        );
                    command.ExecuteNonQuery();  
  
                    foreach (DataRow row in dataTable.Rows)  
                    {  
                        List<String> rowValues = new List<string>();  
                        foreach (DataColumn column in dataTable.Columns)  
                        {  
                            rowValues.Add((row[column] != null && row[column] != DBNull.Value) ? row[column].ToString() : String.Empty);  
                        }  
                        //command.CommandText = $"INSERT INTO [{tableName}]({String.Join(",", columnNames.Select(c => $"[{c}]"))}) VALUES ({String.Join(",", rowValues.Select(r => $"'{r}'").ToArray())});";  
                        string a = String.Join(",", columnNames.Select(c => String.Format("[{0}]", c)));
                        string b = String.Join(",", rowValues.Select(r => String.Format("'{0}'", (r == "") ? "0": r)).ToArray());
                        command.CommandText = String.Format("INSERT INTO [{0}]({1}) VALUES ({2});", tableName, a, b);  
                        command.ExecuteNonQuery();  
                    }  
                }  
  
                connection.Close();  
            }  
        }  
    }  
}  
