using CloudBuilder.AI.Data;
using CloudBuilder.AI.Entity;
using CloudBuilder.AI.Gui.Request;
using CloudBuilder.AI.Linkup;
using CloudBuilder.AI.Policy;
using CloudBuilder.AI.SearchCriteria;
using CloudBuilder.Core.Service;
using CloudBuilder.Gui;
using CloudBuilder.Request.AI;
using CloudBuilder.Request.Security;
using CloudBuilder.Security.Data;
using CloudBuilder.Security.Entity;
using CloudBuilder.Security.Linkup;
using CloudBuilder.Security.Policy;
using DocumentFormat.OpenXml.Wordprocessing;
using Krypton.Toolkit;
using Microsoft.AspNetCore.Authorization;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Security.Permissions;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.Window;


namespace CloudBuilder.AI.Gui
{
    public partial class AiBookOperationPage : AbstractPage
    {
        private SecurityMessagePolicy securityMessagePolicy = null!;
        private BookStatusPolicy bookStatusPolicy = null!;
        private AiBookRequest aiBookRequest = null!;
        private AiSentenceRequest aiSentenceRequest = null!;
        private AiChapterRequest aiChapterRequest = null!;
        private AiBookEntity aiBookEntity = null!;
        private AiBookData data = null!;
        private DmsFileRequestHelper dmsFileRequestHelper;
        private DmsFileRequest dmsFileRequest;
        private AiChapterSearchCriteria searchCriteria;
        public AiBookOperationPage()
        {
            InitializeComponent();
        }


        /// <summary>
        /// 第一次加载时执行，只执行一次
        /// </summary>
        public override void FunctionLoaded()
        {
            try
            {
                base.FunctionLoaded();
                //初始化容器-------------------------------------
                aiBookRequest = ServiceHelper.GetTypeService<AiBookRequest>();
                aiChapterRequest = ServiceHelper.GetTypeService<AiChapterRequest>();
                aiSentenceRequest = ServiceHelper.GetTypeService<AiSentenceRequest>();
                bookStatusPolicy = ServiceHelper.GetTypeService<BookStatusPolicy>();
                securityMessagePolicy = ServiceHelper.GetTypeService<SecurityMessagePolicy>();
                dmsFileRequest = ServiceHelper.GetTypeService<DmsFileRequest>();
                dmsFileRequestHelper = new DmsFileRequestHelper();
                //界面初始化
                InitGui();
            }
            catch (ValidatedException ex)
            {
                ShowMessageBox.ShowInfo(ex.Message);
            }
            catch (ServiceErrorException ex)
            {
                ShowMessageBox.ShowError(ex.Message);
            }
            catch (Exception ex)
            {
                ShowMessageBox.ShowError(ex.Message);
            }
        }


        private void InitGui()
        {
            InitBindingContext();

            InitComBox();

            InitDisplayMode();

            InitGridViewPagination();

            this.ParentAbstractForm.AcceptButton = this.searchBut;
            this.ParentAbstractForm.CancelButton = this.resetBut;
        }

        private void InitComBox()
        {
            statusCombo.SetDataSource(bookStatusPolicy.GetDataSource(), true);
        }
        /// <summary>
        /// DataGridView分页控件初始化
        /// </summary>
        private void InitGridViewPagination()
        {
            searchCriteria = new AiChapterSearchCriteria();
            gridViewPagination.SetLimit(searchCriteria.limit);
            gridViewPagination.OnPaginationChanged += SearchChapter;
        }

        /// <summary>
        /// 有特殊要求的UI控件初始化设置,Init与Add配对后，使用guiOperateHelper管理
        /// </summary>
        private void InitBindingContext()
        {
            //需要绑定数据
            guiBindingContext = new GuiBindingContext();

            InitPermission();

            guidTxt.Set(AiBookEntity.GUID, guidLabel.Text, EnumEditModeColor.ReadOnly);

            descriptionTxt.Set(AiBookEntity.DESCRIPTION);
            statusCombo.Set(AiBookEntity.STATUS, EnumEditModeColor.ReadOnly);
            titleTxt.Set(AiBookEntity.TITLE, titleLabel.Text, EnumEditModeColor.Required);
            authorTxt.Set(AiBookEntity.AUTHOR);
            bookTypeTxt.Set(AiBookEntity.BOOK_TYPE);
            filePathTxt.Set(AiBookData.FILE_NAME, EnumEditModeColor.ReadOnly);

            dataGv.InitColumn(false, false);
            sentenceGv.InitColumn(true, false);

            guiOperateHelper = new GuiOperateHelper();
        }

        private void InitPermission()
        {
            createBut.Set(AIPermissionPolicy.AiBook, Operate.Insert);
            amendBut.Set(AIPermissionPolicy.AiBook, Operate.Update);
            deleteBut.Set(AIPermissionPolicy.AiBook, Operate.Delete);
        }

        /// <summary>
        /// 每次从别的界面进入时执行，发生在FunctionLoaded之后
        /// </summary>
        /// <param name="param"></param>
        public override void FunctionActivated(object param)
        {
            try
            {
                if (param == null)
                {
                    guidSearchTxt.Focus();
                    return;
                }

                InitDisplayMode();

                AiBookOperationLinkup linkup = null;

                if (param is AiBookOperationLinkup)
                {
                    linkup = (AiBookOperationLinkup)param;
                }

                this.DisplayMode = (GuiDisplayMode)linkup.DisplayMode;

                guidSearchTxt.Text = linkup.Guid;

                if (this.DisplayMode == GuiDisplayMode.View)
                {
                    Search();
                }
                else if (this.DisplayMode == GuiDisplayMode.Create)
                {
                    Create();
                }
                else if (this.DisplayMode == GuiDisplayMode.Amend)
                {
                    Search();
                    Amend();
                }

                guidSearchTxt.Focus();
            }
            catch (ValidatedException ex)
            {
                ShowMessageBox.ShowInfo(ex.Message);
            }
            catch (ServiceErrorException ex)
            {
                ShowMessageBox.ShowError(ex.Message);
            }
            catch (Exception ex)
            {
                ShowMessageBox.ShowError(ex.Message);
            }
        }

        public override void FunctionSelected()
        {
            this.ParentAbstractForm.AcceptButton = this.searchBut;
            if (!IsDialog)
                this.ParentAbstractForm.CancelButton = this.resetBut;
            else
                this.ParentAbstractForm.CancelButton = this.cancelBut;

            guidSearchTxt.Focus();
        }

        public override bool FunctionDeactivating()
        {
            if (this.DisplayMode == GuiDisplayMode.View)
            {
                return true;
            }
            else
            {
                return CancelEditing();
            }
        }

        private bool CancelEditing()
        {
            DialogResult result = ShowMessageBox.ShowOption(securityMessagePolicy.ComposeMessage(SecurityMessagePolicy.GUI_CONFIRM_CANCEL), securityMessagePolicy.ComposeMessage(SecurityMessagePolicy.GUI_CONFIRM));

            //从外部跳转(非mainKryptonNavigator)，result第一次不生效？，所以再执行一次生效
            if (result == DialogResult.Cancel)
            {
                result = ShowMessageBox.ShowOption(securityMessagePolicy.ComposeMessage(SecurityMessagePolicy.GUI_CONFIRM_CANCEL), securityMessagePolicy.ComposeMessage(SecurityMessagePolicy.GUI_CONFIRM));
            }

            if (result == DialogResult.No)
            {
                return false;
            }

            Cancel();

            return true;
        }

        private void InitDisplayMode()
        {
            this.DisplayMode = GuiDisplayMode.View;

            SetDisplayMode();
        }

        private void SetDisplayMode()
        {
            if (this.DisplayMode == GuiDisplayMode.View)
            {
                savePanel.Visible = false;
                operationPanel.Visible = true;

                guiOperateHelper.EnableControls(true, topPanel);
                guiOperateHelper.EnableControls(false, contentPanel);
                //查詢有記錄時,修改等控件有效
                if (aiBookEntity != null)
                    guiOperateHelper.EnableControls(true, bottomPanel, processPanel,gridViewPagination);
                else
                    guiOperateHelper.EnableControls(false, bottomPanel, processPanel, gridViewPagination);
            }
            else if (this.DisplayMode == GuiDisplayMode.Amend || this.DisplayMode == GuiDisplayMode.Create)
            {
                savePanel.Visible = true;
                operationPanel.Visible = false;

                guiOperateHelper.EnableControls(false, topPanel, processPanel, gridViewPagination);
                guiOperateHelper.EnableControls(true, bottomPanel, contentPanel);

                if (this.DisplayMode == GuiDisplayMode.Amend) guiOperateHelper.EnableControls(false, guidTxt);
            }

        }

        private void PackUIToEntity()
        {
            guiBindingContext.DataPack();
        }

        private bool SaveValidate()
        {
            if (!guiOperateHelper.CheckValidate(this.contentPanel)) return false;

            return true;
        }

        private void Search()
        {
            try
            {
                if (string.IsNullOrEmpty(guidSearchTxt.Text)) return;

                Reset();

                data = aiBookRequest.FindByKey(guidSearchTxt.Text);

                if (data == null || data.AiBook == null)
                {
                    ShowMessageBox.ShowInfo(securityMessagePolicy.ComposeMessage(SecurityMessagePolicy.GUI_WS_RECORD_NOT_FOUND));
                }
                else
                {
                    aiBookEntity = data.AiBook;

                    PackEntityToUI();

                    SetDisplayMode();
                }
            }
            catch (ValidatedException ex)
            {
                ShowMessageBox.ShowInfo(ex.Message);
            }
            catch (ServiceErrorException ex)
            {
                ShowMessageBox.ShowError(ex.Message);
            }
            catch (Exception ex)
            {
                ShowMessageBox.ShowError(ex.Message);
            }
        }


        /// <summary>
        /// 与Web同步写法
        /// </summary>
        /// <returns></returns>
        private AiChapterSearchCriteria PackSearchCriteria()
        {
            searchCriteria = new AiChapterSearchCriteria();
            searchCriteria.limit = gridViewPagination.Limit;
            searchCriteria.page = gridViewPagination.CurrentPage;
            searchCriteria.orderby = AiChapterEntity.CHAPTER_INDEX;

            List<SearchFilter> filters = new List<SearchFilter>();

            SearchFilter filter = new SearchFilter();
            filter.Column = AiChapterEntity.DB_BOOK_GUID;
            filter.Type = SearchFilterTypePolicy.TEXT;
            filter.Operator = SearchFilterOperatorPolicy.EQUAL_TO;
            filter.Value = data.AiBook.Guid;
            filters.Add(filter);

            searchCriteria.Filter = filters.ToArray();

            return searchCriteria;
        }

        private void SearchChapter()
        {
            try
            {
                var chapterResultData = aiChapterRequest.FindBySearchCriteria(PackSearchCriteria());

                gridViewPagination.SetTotal(chapterResultData.Total);

                dataGv.SetDataSource(chapterResultData.Datas);

            }
            catch (ValidatedException ex)
            {
                ShowMessageBox.ShowInfo(ex.Message);
            }
            catch (ServiceErrorException ex)
            {
                ShowMessageBox.ShowError(ex.Message);
            }
            catch (Exception ex)
            {
                ShowMessageBox.ShowError(ex.Message);
            }
        }

        private void Create()
        {
            this.DisplayMode = GuiDisplayMode.Create;

            guiOperateHelper.ResetControls(this.mainPanel);

            SetDisplayMode();

            data = new AiBookData();
            aiBookEntity = new AiBookEntity()
            {
                Status = BookStatusPolicy.DRAFT,
                CreatedBy = string.Empty,
                UpdatedBy = string.Empty,
                CreatedDatetime = DateTime.Now,
                UpdatedDatetime = DateTime.Now,
            };
            data.AiBook = aiBookEntity;

            PackEntityToUI();

            guidTxt.Focus();
        }

        private void Amend()
        {
            this.DisplayMode = GuiDisplayMode.Amend;

            SetDisplayMode();
        }

        private void PackEntityToUI()
        {
            guiBindingContext.DataBind(data.AiBook, this);

            filePathTxt.Text = data.FileName;

            SearchChapter();
        }

        private void Reset()
        {
            this.DisplayMode = GuiDisplayMode.View;

            aiBookEntity = null;

            guiOperateHelper.ResetControls(this.contentPanel);

            SetDisplayMode();

            guidSearchTxt.Focus();
        }

        public void Cancel()
        {
            if (!string.IsNullOrEmpty(guidSearchTxt.Text))
                Search();
            else
                Reset();

        }


        private void permissionNameSearchBut_Click(object sender, EventArgs e)
        {
            //try
            //{
            //    AbstractForm dialog = GetAbstractDialog(typeof(AiBookEnquiryPage).Name);

            //    if (DialogResult.OK != dialog.ShowDialog()) return;

            //    permissionNameSearchTxt.Text = ((AiBookEntity[])dialog.OutputData)[0].PermissionName;

            //    Search();
            //}
            //catch (ValidatedException ex)
            //{
            //    ShowMessageBox.ShowInfo(ex.Message);
            //}
            //catch (ServiceErrorException ex)
            //{
            //    ShowMessageBox.ShowError(ex.Message);
            //}
            //catch (Exception ex)
            //{
            //    ShowMessageBox.ShowError(ex.Message);
            //}
        }

        private void searchBut_Click(object sender, EventArgs e)
        {
            try
            {
                if (string.IsNullOrEmpty(guidSearchTxt.Text))
                {
                    ShowMessageBox.ShowInfo(securityMessagePolicy.ComposeMessage(SecurityMessagePolicy.GUI_VALID_INPUT, GuiOperateHelper.GetLabelText(guidSearchLabel.Text)));
                    this.guidSearchTxt.Focus();
                    return;
                }
                this.DisplayMode = GuiDisplayMode.View;

                Search();

            }
            catch (ValidatedException ex)
            {
                ShowMessageBox.ShowInfo(ex.Message);
            }
            catch (ServiceErrorException ex)
            {
                ShowMessageBox.ShowError(ex.Message);
            }
            catch (Exception ex)
            {
                ShowMessageBox.ShowError(ex.Message);
            }
        }

        private void resetBut_Click(object sender, EventArgs e)
        {
            try
            {
                guiOperateHelper.ResetControls(this.topPanel);
                Reset();
            }
            catch (ValidatedException ex)
            {
                ShowMessageBox.ShowInfo(ex.Message);
            }
            catch (ServiceErrorException ex)
            {
                ShowMessageBox.ShowError(ex.Message);
            }
            catch (Exception ex)
            {
                ShowMessageBox.ShowError(ex.Message);
            }
        }

        private void createBut_Click(object sender, EventArgs e)
        {
            try
            {
                Create();
            }
            catch (ValidatedException ex)
            {
                ShowMessageBox.ShowInfo(ex.Message);
            }
            catch (ServiceErrorException ex)
            {
                ShowMessageBox.ShowError(ex.Message);
            }
            catch (Exception ex)
            {
                ShowMessageBox.ShowError(ex.Message);
            }
        }

        private void amendBut_Click(object sender, EventArgs e)
        {
            try
            {
                Amend();
            }
            catch (ValidatedException ex)
            {
                ShowMessageBox.ShowInfo(ex.Message);
            }
            catch (ServiceErrorException ex)
            {
                ShowMessageBox.ShowError(ex.Message);
            }
            catch (Exception ex)
            {
                ShowMessageBox.ShowError(ex.Message);
            }
        }

        private void deleteBut_Click(object sender, EventArgs e)
        {
            try
            {
                if (aiBookEntity == null)
                {
                    ShowMessageBox.ShowInfo(securityMessagePolicy.ComposeMessage(SecurityMessagePolicy.GUI_WS_RECORD_NOT_FOUND));
                    return;
                }

                if (DialogResult.Yes != ShowMessageBox.ShowOption(securityMessagePolicy.ComposeMessage(SecurityMessagePolicy.GUI_CONFIRM_DEL_NULL), securityMessagePolicy.ComposeMessage(SecurityMessagePolicy.GUI_DELETE))) return;

                aiBookRequest.Delete(aiBookEntity.Guid);

                ShowMessageBox.ShowInfo(securityMessagePolicy.ComposeMessage(SecurityMessagePolicy.GUI_SUCCEED_DELETED_NULL));

                Reset();
            }
            catch (ValidatedException ex)
            {
                ShowMessageBox.ShowInfo(ex.Message);
            }
            catch (ServiceErrorException ex)
            {
                ShowMessageBox.ShowError(ex.Message);
            }
            catch (Exception ex)
            {
                ShowMessageBox.ShowError(ex.Message);
            }
        }

        private void saveBut_Click(object sender, EventArgs e)
        {
            try
            {
                if (!SaveValidate()) return;

                PackUIToEntity();


                if (this.DisplayMode == GuiDisplayMode.Create)
                {
                    data = aiBookRequest.Insert(data);
                    aiBookEntity.Guid = data.AiBook.Guid;
                }
                else
                    aiBookRequest.Update(data);


                ShowMessageBox.ShowInfo((this.DisplayMode == GuiDisplayMode.Create) ?
                    securityMessagePolicy.ComposeMessage(SecurityMessagePolicy.GUI_SUCCEED_CREATED_NULL) :
                    securityMessagePolicy.ComposeMessage(SecurityMessagePolicy.GUI_SUCCEED_UPDATED_NULL));

                guidSearchTxt.Text = aiBookEntity.Guid;
                Search();
            }
            catch (ValidatedException ex)
            {
                ShowMessageBox.ShowInfo(ex.Message);
            }
            catch (ServiceErrorException ex)
            {
                ShowMessageBox.ShowError(ex.Message);
            }
            catch (Exception ex)
            {
                ShowMessageBox.ShowError(ex.Message);
            }
        }

        private void cancelBut_Click(object sender, EventArgs e)
        {
            try
            {
                CancelEditing();
            }
            catch (ValidatedException ex)
            {
                ShowMessageBox.ShowInfo(ex.Message);
            }
            catch (ServiceErrorException ex)
            {
                ShowMessageBox.ShowError(ex.Message);
            }
            catch (Exception ex)
            {
                ShowMessageBox.ShowError(ex.Message);
            }
        }

        private void addBut_Click(object sender, EventArgs e)
        {
            //dataGv.AddRow(new AiBookDependentEntity() { CreatedBy = string.Empty, UpdatedBy = string.Empty });
        }

        private void delBut_Click(object sender, EventArgs e)
        {
            if (dataGv.RowCount <= 0 || dataGv.SelectedCells.Count <= 0)
            {
                ShowMessageBox.ShowInfo(securityMessagePolicy.ComposeMessage(SecurityMessagePolicy.GUI_WS_RECORD_NOT_FOUND));
                return;
            }

            dataGv.DeleteRows(dataGv.SelectedCells);
        }

        private void uploadBut_Click(object sender, EventArgs e)
        {
            try
            {
                OpenFileDialog openFileDialog = new OpenFileDialog();
                openFileDialog.Multiselect = false;

                if (openFileDialog.ShowDialog() != DialogResult.OK)
                    return;

                string[] fileNames = openFileDialog.FileNames;

                string folderName = dmsFileRequest.GetFolderName(typeof(AiBookEntity).Name);
                BookDmsFileViewEntity dmsFile = dmsFileRequestHelper.UploadFile(fileNames[0], folderName);
                if (dmsFile == null || dmsFile.FileId == 0) return;

                data.AiBook.FileId = dmsFile.FileId;

                aiBookRequest.Update(data);

                ShowMessageBox.ShowInfo(securityMessagePolicy.ComposeMessage(SecurityMessagePolicy.GUI_SUCCEED_UPDATED_NULL));
            }
            catch (ValidatedException ex)
            {
                ShowMessageBox.ShowInfo(ex.Message);
            }
            catch (ServiceErrorException ex)
            {
                ShowMessageBox.ShowError(ex.Message);
            }
            catch (Exception ex)
            {
                ShowMessageBox.ShowError(ex.Message);
            }
        }

        private void processBut_Click(object sender, EventArgs e)
        {
            try
            {
                AbstractForm dialog;
                dialog = GetAbstractDialog(typeof(AiBookProcessDialogPage).Name);
                if (DialogResult.OK != dialog.ShowCreateDialog()) return;

                AiBookProcessData d = (AiBookProcessData)dialog.OutputData;

                data = aiBookRequest.ProcessBook(data.AiBook.Guid, d.Encoding, d.Pattern);

                ShowMessageBox.ShowInfo(securityMessagePolicy.ComposeMessage(SecurityMessagePolicy.GUI_SUCCEED_UPDATED_NULL));

                guidSearchTxt.Text = data.AiBook.Guid;
                Search();
            }
            catch (ValidatedException ex)
            {
                ShowMessageBox.ShowInfo(ex.Message);
            }
            catch (ServiceErrorException ex)
            {
                ShowMessageBox.ShowError(ex.Message);
            }
            catch (Exception ex)
            {
                ShowMessageBox.ShowError(ex.Message);
            }
        }

        private void dataGv_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            try
            {
                if (e.RowIndex == -1 || e.ColumnIndex == -1) return;

                if (dataGv.RowCount <= 0 || dataGv.SelectedCells.Count <= 0)
                {
                    ShowMessageBox.ShowInfo(securityMessagePolicy.ComposeMessage(SecurityMessagePolicy.GUI_WS_RECORD_NOT_FOUND));
                    return;
                }

                AiChapterEntity chapter = dataGv.GetRowData<AiChapterEntity>(dataGv.SelectedCells[0].RowIndex);

                AiSentenceViewEntity[] aiSentences = aiSentenceRequest.FindByChapterGuid(chapter.Guid);

                sentenceGv.SetDataSource(aiSentences);
            }
            catch (ValidatedException ex)
            {
                ShowMessageBox.ShowInfo(ex.Message);
            }
            catch (ServiceErrorException ex)
            {
                ShowMessageBox.ShowError(ex.Message);
            }
            catch (Exception ex)
            {
                ShowMessageBox.ShowError(ex.Message);
            }
        }

        private void extractNamesBut_Click(object sender, EventArgs e)
        {
            try
            {
                if (dataGv.RowCount <= 0 || dataGv.SelectedCells.Count <= 0)
                {
                    ShowMessageBox.ShowInfo(securityMessagePolicy.ComposeMessage(SecurityMessagePolicy.GUI_WS_RECORD_NOT_FOUND));
                    return;
                }

                AiChapterEntity chapter = dataGv.GetRowData<AiChapterEntity>(dataGv.SelectedCells[0].RowIndex);

                aiBookRequest.ExtractNamesByChapterGuid(data.AiBook.Guid, chapter.Guid);

                AiSentenceViewEntity[] aiSentences = aiSentenceRequest.FindByChapterGuid(chapter.Guid);

                sentenceGv.SetDataSource(aiSentences);
            }
            catch (ValidatedException ex)
            {
                ShowMessageBox.ShowInfo(ex.Message);
            }
            catch (ServiceErrorException ex)
            {
                ShowMessageBox.ShowError(ex.Message);
            }
            catch (Exception ex)
            {
                ShowMessageBox.ShowError(ex.Message);
            }
        }
    }
}
