using ClosedXML.Excel;
using CloudBuilder.Core.DatabaseAccessor.Entity;
using CloudBuilder.Core.DependencyInjection.Form;
using CloudBuilder.Core.Report;
using CloudBuilder.Core.Service;
using CloudBuilder.Gui;
using CloudBuilder.Gui.DependencyInjection;
using CloudBuilder.Request.Security;
using CloudBuilder.Security.Data;
using CloudBuilder.Security.Entity;
using CloudBuilder.Security.Linkup;
using CloudBuilder.Security.Policy;
using CloudBuilder.Security.SearchCriteria;
using DocumentFormat.OpenXml.Office2010.ExcelAc;
using DocumentFormat.OpenXml.Spreadsheet;
using DocumentFormat.OpenXml.Wordprocessing;
using Krypton.Toolkit;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Tokens;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;


namespace CloudBuilder.Security.Gui
{
    public partial class LocaleEnquiryPage : AbstractPage
    {
        private LocaleDisplayData[] locales = null!;
        private LocaleSearchCriteria searchCriteria = null!;
        private BindingContextAttributeProvider provider;
        private LocaleRequest localeRequest;
        private SecurityMessagePolicy securityMessagePolicy;

        //初始化Page，注入容器内，不要在此做任何事情
        public LocaleEnquiryPage()
        {
            InitializeComponent();
        }

        /// <summary>
        /// 第一次加载时执行，只执行一次
        /// </summary>
        public override void FunctionLoaded()
        {
            HandleException(() => OnFunctionLoaded());
        }

        private void OnFunctionLoaded()
        {
            base.FunctionLoaded();
            //初始化容器-------------------------------------
            localeRequest = ServiceHelper.GetTypeService<LocaleRequest>();
            securityMessagePolicy = ServiceHelper.GetTypeService<SecurityMessagePolicy>()!;

            //界面初始化
            InitGui();
        }

        /// <summary>
        /// 每次从别的界面进入时执行，不包括下面的界面切换，发生在FunctionLoaded之后
        /// 这个是有参数传入，常用于查询界面进入到操作界面发生
        /// </summary>
        /// <param name="param"></param>
        public override void FunctionActivated(object param)
        {
            base.FunctionActivated(param);
            groupNameTxt.Focus();
        }
        /// <summary>
        /// 当Page被选中时执行,用于Tab导航的切换，没有参数变化，跟FunctionActivated有区别
        /// </summary>
        public override void FunctionSelected()
        {
            this.ParentAbstractForm.AcceptButton = this.searchBut;
            this.ParentAbstractForm.CancelButton = this.resetBut;


            groupNameTxt.Focus();
        }
        /// <summary>
        /// 控件的初始化
        /// </summary>
        private void InitGui()
        {
            //DataGridView初始化不要自动生成列，且允许重排列名操作
            dataGv.InitColumn(false, true);

            dataGv.SetColumnDataSource(langCol, CulturePolicy.GetInstance().GetComposeMessages(), true);

            langCombo.SetDataSource(CulturePolicy.GetInstance().GetComposeMessages(), true);

            //初始化绑定设置
            InitBindingContext();
            //设置显示模式
            SetDisplayMode(true);

            InitGridViewPagination();
        }
        /// <summary>
        /// DataGridView分页控件初始化
        /// </summary>
        private void InitGridViewPagination()
        {
            searchCriteria = new LocaleSearchCriteria();
            gridViewPagination.SetLimit(searchCriteria.limit);
            gridViewPagination.OnPaginationChanged += Search;
            gridViewPagination.OnPrint += Print;
        }

        /// <summary>
        /// 打印当前查询结果
        /// </summary>
        private void Print()
        {
            //設置查詢條件
            List<string> searCriteria = new List<string>();
            if (!string.IsNullOrEmpty(groupNameTxt.Text))
                searCriteria.Add(groupNameLabel.Text + groupNameTxt.Text);

            //設置每列的格式
            TemplateHeader[] headers = dataGv.GetTemplateHeaders();

            //打印Excel
            new DataToExcelHelper<LocaleEntity>(null).PrintExcel(this.Parent.Text, this.Parent.Text, searCriteria, headers, locales);
        }

        /// <summary>
        /// 有特殊要求的UI控件初始化设置，使用guiOperateHelper管理
        /// </summary>
        private void InitBindingContext()
        {
            InitPermission();

            nameCol.Set(EnumEditModeColor.Required);
            orderByCol.Set(EnumEditModeColor.Required);
            valueCol.Set(EnumEditModeColor.Required);
            groupNameCol.Set(EnumEditModeColor.Required);
            langCol.Set(EnumEditModeColor.Required);

            guiOperateHelper = new GuiOperateHelper();
        }

        private void InitPermission()
        {
            amendBut.Set(SecurityPermissionPolicy.Locale, Operate.Update);
        }

        private void SetDisplayMode(bool enable)
        {
            guiOperateHelper.EnableControls(true, this.searchPanel);
            guiOperateHelper.EnableControls(!enable, dataGv);
            savePanel.Visible = !enable;
            amendBut.Visible = gridViewPagination.Visible = enable;
            guiOperateHelper.EnableControls(enable, amendBut);

            this.groupNameTxt.Focus();
        }

        private void searchBut_Click(object sender, EventArgs e)
        {
            HandleException(() => Search());
        }

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

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

            SearchFilter filter = new SearchFilter();
            filter.Column = LocaleEntity.DB_GROUP_NAME;
            filter.Type = SearchFilterTypePolicy.TEXT;
            filter.Operator = SearchFilterOperatorPolicy.CONTAIN;
            filter.Value = groupNameTxt.GetValue();
            filters.Add(filter);

            filter = new SearchFilter();
            filter.Column = LocaleEntity.DB_VALUE;
            filter.Type = SearchFilterTypePolicy.TEXT;
            filter.Operator = SearchFilterOperatorPolicy.CN_CONTAIN;
            filter.Value = valueTxt.GetValue();
            filters.Add(filter);

            filter = new SearchFilter();
            filter.Column = LocaleEntity.DB_LANG;
            filter.Type = SearchFilterTypePolicy.TEXT;
            filter.Operator = SearchFilterOperatorPolicy.SINGLE;
            filter.Value = (string)langCombo.GetValue();
            filters.Add(filter);

            filter = new SearchFilter();
            filter.Column = LocaleEntity.DB_NAME;
            filter.Type = SearchFilterTypePolicy.TEXT;
            filter.Operator = SearchFilterOperatorPolicy.CONTAIN;
            filter.Value = nameTxt.GetValue();
            filters.Add(filter);


            searchCriteria.Filter = filters.ToArray();

            return searchCriteria;
        }

        private void Search()
        {
            var data = localeRequest.FindBySearchCriteria(PackSearchCriteria());

            if (data != null) locales = data.Datas;

            gridViewPagination.SetTotal(data.Total);

            if (locales == null || locales.Length == 0)
            {
                ShowMessageBox.ShowInfo(securityMessagePolicy.ComposeMessage(SecurityMessagePolicy.GUI_WS_RECORD_NOT_FOUND));
                guiOperateHelper.ResetControls(this.dataGv);
                return;
            }

            dataGv.SetDataSource(locales);

            SetDisplayMode(true);
        }

        private void resetBut_Click(object sender, EventArgs e)
        {
            guiOperateHelper.ResetControls(this.mainPanel);

            SetDisplayMode(true);
        }

        private void DisplayPage(GuiDisplayMode mode)
        {
            this.DisplayMode = mode;

            SetDisplayMode(false);
        }


        private void amendBut_Click(object sender, EventArgs e)
        {
            DisplayPage(GuiDisplayMode.Amend);
        }

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

            return true;
        }

        private void saveBut_Click(object sender, EventArgs e)
        {
            HandleException(() => Save());
        }

        private void Save()
        {
            if (!SaveValidate()) return;

            LocaleData data = new LocaleData();
            data.Inserts = dataGv.GetAddRows<LocaleDisplayData>();
            data.Updates = dataGv.GetUpdateRows<LocaleDisplayData>();
            data.Deletes = dataGv.GetDeleteRows<LocaleDisplayData>();

            localeRequest.UpdateLocaleData(data);

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

            Search();
        }

        private void addBut_Click(object sender, EventArgs e)
        {
            dataGv.AddRow(new LocaleEntity() { CreatedBy = string.Empty, UpdatedBy = string.Empty, CreatedDatetime = DateTime.Now, UpdatedDatetime = DateTime.Now });
        }

        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 cancelBut_Click(object sender, EventArgs e)
        {
            HandleException(() => Cancel());
        }

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

            guiOperateHelper.ResetControls(this.dataGv);

            SetDisplayMode(true);

            Search();
        }
    }
}
