using JWH.CONTROL;
using JWH.NETWORK;
using MongoDB.Driver;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using Telerik.WinControls.Data;
using Telerik.WinControls.UI;

namespace DDUtilityApp.MESDOWNLOADER
{
    public partial class ServerLog : Form
    {
        DataSet dsXml;
        DataTable dtFiles;
        public ServerLog()
        {
            InitializeComponent();
            SetDataTable();
            GetXmlFile();
            gridLogFiles.CellDoubleClick += Grid_CellDoubleClick;
            gridLogFiles.KeyDown += Grid_KeyDown;
        }


        private void ServerLog_Shown(object sender, EventArgs e)
        {
            this.WindowState = System.Windows.Forms.FormWindowState.Maximized;
            txtPath.Text = GlobalVariable.Instance.MesDownloadPath; //Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
            SetGridView();
        }
        private void ServerLog_Resize(object sender, EventArgs e)
        {
            splitContainer2.SplitterDistance = splitContainer2.ClientSize.Width / 2;
        }
        private void btnConnect_Click(object sender, EventArgs e)
        {
            gridLogFiles.DataSource = null;
            dtFiles.Rows.Clear();
            LoadFiles(gridServer.ChildRows);
        }
        private void btnFoder_Click(object sender, EventArgs e)
        {
            // 폴더 선택 대화 상자를 생성
            using (FolderBrowserDialog folderDialog = new FolderBrowserDialog())
            {
                // txtPath.Text에 값이 있으면 해당 경로로 설정, 없으면 문서 폴더로 설정
                if (!string.IsNullOrEmpty(txtPath.Text))
                {
                    folderDialog.SelectedPath = txtPath.Text;
                }
                else
                {
                    // 초기값이 없으면 문서 폴더를 기본 경로로 설정
                    folderDialog.SelectedPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
                }

                // 폴더 선택 대화 상자가 "확인" 버튼을 클릭했을 경우
                if (folderDialog.ShowDialog() == DialogResult.OK)
                {
                    // 선택한 경로를 텍스트 박스에 표시
                    txtPath.Text = folderDialog.SelectedPath;
                    GlobalVariable.Instance.MesDownloadPath = folderDialog.SelectedPath;
                }
            }
        }
        private void btnPath_Click(object sender, EventArgs e)
        {
            System.Diagnostics.Process.Start("explorer.exe", txtPath.Text);
        }
        private void cboxServer_SelectedIndexChanged(object sender, EventArgs e)
        {
            gridServer.DataSource = null;
            if (dsXml == null || !dsXml.Tables.Contains("Item")) return;

            int serverId = 0;
            if (cboxServer.SelectedValue == null) return;
            if (cboxServer.SelectedValue is DataRowView dataRowView)
            {
                serverId = Convert.ToInt32(dataRowView["Server_Id"]); // Replace "ColumnName" with the actual column name
            }
            else
            {
                serverId = Convert.ToInt32(cboxServer.SelectedValue);
            }

            DataTable filteredTable = dsXml.Tables["Item"].Clone();



            // LINQ를 사용하여 Server Item Server_Id 기준으로 조인
            var query = from table1 in dsXml.Tables["Server"].AsEnumerable()
                        join table2 in dsXml.Tables["Item"].AsEnumerable()
                        on table1.Field<int>("Server_Id") equals table2.Field<int>("Server_Id")
                        where table2.Field<int>("Server_Id") == serverId // 필터 조건을 추가
                        select new
                        {
                            name = table1.Field<string>("name"),
                            nameap = table2.Field<string>("name"),
                            url = table2.Field<string>("url"),
                            dir = table2.Field<string>("dir"),
                            conkey = table2.Field<string>("conkey"),
                            Server_Id = table2.Field<int>("Server_Id")
                        };

            gridServer.DataSource = query;
            var uniqueNames = query.Select(x => x.nameap).Distinct();
            UpdateCheckBoxes(uniqueNames);
            SetGridView();
        }
        private void Grid_KeyDown(object sender, KeyEventArgs e) //jhlim 20250202
        {
            if (e.KeyCode == Keys.Enter)
            {
                Grid_CellDoubleClick((GridViewEx)sender, null);
            }
        }
        private bool isProcessing = false; // 중복 실행 방지 플래그

        private async void Grid_CellDoubleClick(object sender, GridViewCellEventArgs e) // jhlim 20250202
        {
            if (isProcessing) return; // 이미 실행 중이면 종료

            isProcessing = true; // 실행 상태 설정

            RadGridView gd = sender.GetType().Name.Contains("GridDataCellElement") ?
                ((GridDataCellElement)sender)?.RowElement?.GridControl : (GridViewEx)sender;

            try
            {
                List<string> mergefileList = new List<string>();
                bool rtnBool = false;
                int totalFiles = gd.SelectedRows.Count;

                if (totalFiles == 0)
                {
                    MessageBox.Show("선택된 파일이 없습니다.");
                    isProcessing = false;
                    return;
                }

                // 프로그래스 바 폼 생성 및 표시
                using (ProgressForm progressForm = new ProgressForm(totalFiles))
                {
                    progressForm.Show();
                    progressForm.UpdateProgress(string.Empty, 0); // 초기 상태 업데이트

                    int processedCount = 0;

                    // 파일 다운로드 비동기 처리
                    foreach (GridViewRowInfo row in gd.SelectedRows)
                    {
                        var host = Util.GetStr(row.Cells["url"].Value);
                        var dir = row.Cells["dir"].Value;
                        var fileName = row.Cells["FileName"].Value;
                        var userId = Util.GetStr(row.Cells["userId"].Value);
                        var password = Util.GetStr(row.Cells["password"].Value);

                        // 진행 상태 업데이트
                        processedCount++;
                        progressForm.UpdateProgress(fileName?.ToString(), processedCount);

                        FtpsClient.Disconnect();
                        FtpsClient.Initialize(host, userId, password);

                        rtnBool = await Task.Run(() =>
                            FtpsClient.DownloadFtpsFile($"{dir}/{fileName}", $"{txtPath.Text}\\{fileName}")
                        );

                        if (!rtnBool)
                        {
                            MessageBox.Show($"{fileName} 다운로드에 실패했습니다.");
                            break;
                        }

                        mergefileList.Add($"{txtPath.Text}\\{fileName}");
                    }

                    progressForm.Close(); // 프로그래스 바 폼 닫기
                }

                // 다운로드 완료 후 병합 처리
                if (rtnBool)
                {
                    if (totalFiles > 1)
                    {
                        string filename = Util.GetFileMerge(mergefileList);
                        MessageBox.Show($"{totalFiles}개의 파일을 머지 하였습니다.");
                        System.Diagnostics.Process.Start(filename);
                    }
                    else
                    {
                        MessageBox.Show($"{gd.SelectedRows[0].Cells["Name"].Value} 파일을 저장 하였습니다.");
                        string fileName = mergefileList[0];
                        string extension = Path.GetExtension(fileName);
                        if (string.Compare(extension, ".Log", true) != 0)
                        {
                            fileName += ".Log";
                            File.Move(mergefileList[0], fileName);
                        }
                        System.Diagnostics.Process.Start(fileName);
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"에러 발생: {ex.Message}");
            }
            finally
            {
                isProcessing = false; // 실행 완료 후 플래그 해제
            }
        }

        private void GetXmlFile()
        {
            string xmlPath = ConfigurationManager.AppSettings["BULK_VIEWER"];
            dsXml = XmlToDsConverter.ConvertXmlToDataSet(xmlPath);

            if (dsXml == null || dsXml.Tables.Count == 0)
            {
                MessageBox.Show("XML 데이터를 불러올 수 없습니다.", "오류", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            PopulateComboBox();
        }
        private void PopulateComboBox()
        {
            if (dsXml == null || !dsXml.Tables.Contains("Server")) return;

            cboxServer.DataSource = dsXml.Tables["Server"];
            cboxServer.DisplayMember = "name";   // 사용자가 볼 값 (서버 이름)
            cboxServer.ValueMember = "Server_Id"; // 내부적으로 사용할 값 (서버 ID)
            cboxServer.SelectedIndex = 0;
        }
        private void SetDataTable()
        {
            dtFiles = new DataTable();
            dtFiles.Columns.Add("Name", typeof(string));
            dtFiles.Columns.Add("nameap", typeof(string));
            dtFiles.Columns.Add("FileName", typeof(string));
            dtFiles.Columns.Add("Size", typeof(string));
            dtFiles.Columns.Add("Modified", typeof(string));
            dtFiles.Columns.Add("Type", typeof(string));
            dtFiles.Columns.Add("url", typeof(string));
            dtFiles.Columns.Add("dir", typeof(string));
            dtFiles.Columns.Add("userId", typeof(string));
            dtFiles.Columns.Add("password", typeof(string));
        }
        private void SetGridView()
        {
            gridServer.Columns.Clear();
            gridLogFiles.Columns.Clear();

            gridLogFiles.MultiSelect = true;
            gridLogFiles.SelectionMode = GridViewSelectionMode.FullRowSelect;

            gridServer.AutoGenerateColumns = false;
            gridServer.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.None; // 컬럼 크기 자동 조정 끄기
            // 컬럼 추가
            gridServer.Columns.Add(new GridViewTextBoxColumn("name") { HeaderText = "시스템명", Width = 100, ReadOnly = true });
            gridServer.Columns.Add(new GridViewTextBoxColumn("nameap") { HeaderText = "서버명", Width = 100, ReadOnly = true });
            gridServer.Columns.Add(new GridViewTextBoxColumn("url") { HeaderText = "FTP 서버", Width = 300, ReadOnly = true });
            gridServer.Columns.Add(new GridViewTextBoxColumn("dir") { HeaderText = "FTP 폴더", Width = 300, ReadOnly = true });
            gridServer.Columns.Add(new GridViewTextBoxColumn("conkey") { IsVisible = false });

            gridLogFiles.AutoGenerateColumns = false;
            gridLogFiles.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.None; // 컬럼 크기 자동 조정 끄기
            gridLogFiles.Columns.Add(new GridViewTextBoxColumn("name") { HeaderText = "시스템", Width = 100, ReadOnly = true });
            gridLogFiles.Columns.Add(new GridViewTextBoxColumn("nameap") { HeaderText = "서버", Width = 100, ReadOnly = true });
            gridLogFiles.Columns.Add(new GridViewTextBoxColumn("FileName") { HeaderText = "파일명", Width = 300, ReadOnly = true });
            gridLogFiles.Columns.Add(new GridViewTextBoxColumn("Size") { HeaderText = "파일 크기", Width = 100, TextAlignment = ContentAlignment.MiddleRight, ReadOnly = true });
            gridLogFiles.Columns.Add(new GridViewTextBoxColumn("Modified") { HeaderText = "수정 날짜", Width = 150, TextAlignment = ContentAlignment.MiddleCenter, ReadOnly = true });
            gridLogFiles.Columns.Add(new GridViewTextBoxColumn("Type") { HeaderText = "파일 유형", Width = 100, ReadOnly = true });
            gridLogFiles.Columns.Add(new GridViewTextBoxColumn("url") { IsVisible = false });
            gridLogFiles.Columns.Add(new GridViewTextBoxColumn("dir") { IsVisible = false });
            gridLogFiles.Columns.Add(new GridViewTextBoxColumn("userId") { IsVisible = false });
            gridLogFiles.Columns.Add(new GridViewTextBoxColumn("password") { IsVisible = false });

            FilterGridByNameap();
        }
        private void FilterGridByNameap()
        {

            var checkedNames = plSubPart.Controls.OfType<CheckBox>()
               .Where(c => c.Checked)
               .Select(c => c.Text)
               .ToList();

            // 기존 필터 제거
            gridServer.FilterDescriptors.Clear();
            gridLogFiles.FilterDescriptors.Clear();
            // 체크된 항목이 없으면 전체 표시
            if (checkedNames == null || checkedNames.Count == 0)
                return;

            // 필터 생성
            CompositeFilterDescriptor compositeFilter = new CompositeFilterDescriptor();
            compositeFilter.LogicalOperator = FilterLogicalOperator.Or;

            foreach (var name in checkedNames)
            {
                compositeFilter.FilterDescriptors.Add(new FilterDescriptor("nameap", FilterOperator.IsEqualTo, name));
            }

            // 필터 적용
            gridServer.FilterDescriptors.Add(compositeFilter);
            gridLogFiles.FilterDescriptors.Add(compositeFilter);
        }
        private void UpdateCheckBoxes(IEnumerable<string> uniqueNames)
        {
            // 기존 체크박스 삭제
            plSubPart.Controls.Clear();

            // 이름을 정렬
            var sortedNames = uniqueNames.OrderBy(name => name);

            // 체크박스 동적 생성
            foreach (var name in sortedNames)
            {
                CheckBox checkBox = new CheckBox();
                checkBox.Text = name;
                checkBox.AutoSize = true;
                checkBox.Checked = true; // 기본값 체크 상태

                // 체크박스 이벤트  
                checkBox.CheckedChanged += (s, ev) =>
                {
                    FilterGridByNameap();
                };

                // 패널에 추가
                plSubPart.Controls.Add(checkBox);
            }
        }
        private void LoadFiles(GridViewChildRowCollection rows)
        {
            try
            {
                foreach (GridViewRowInfo row in gridServer.ChildRows) // 필터된 행 제외
                {
                    if (row.IsVisible && row.Cells.Count > 1) // 표시된 행만 처리
                    {
                        var path = Util.GetStr(row.Cells[3].Value);
                        string[] userInfo = Util.GetUser(Util.GetStr(row.Cells[4].Value));

                        if (userInfo != null)
                        {
                            FtpsClient.Initialize(Util.GetStr(row.Cells[2].Value), userInfo[0], userInfo[1]);

                            // FTPS 서버에서 파일 목록 가져오기
                            var fileList = FtpsClient.GetFtpsList(path);

                            if (fileList == null || fileList.Length == 0)
                            {
                                MessageBox.Show("파일 목록을 가져올 수 없습니다.", "오류", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                                return;
                            }

                            // 데이터 테이블 생성 후 바인딩
                            foreach (var item in fileList)
                            {
                                dtFiles.Rows.Add(row.Cells["name"].Value, row.Cells["nameap"].Value, item.Name, item.Size.ToString("N0")
                                    , item.Modified.ToString("yyyy-MM-dd HH:mm:ss"), item.Type, row.Cells["url"].Value, row.Cells["dir"].Value, userInfo[0], userInfo[1]);
                            }

                        }
                    }
                }
                gridLogFiles.DataSource = dtFiles;
                SetGridView();
            }
            catch (Exception ex)
            {
                MessageBox.Show($"파일 목록 로드 오류: {ex.Message}", "오류", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
    }
}
