using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Data.Linq.Mapping;
using System.Drawing;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace PTMedicalInsurance.Entity
{
    /// <summary>
    /// 后面出入参基本集成该类，将一些通用方法封装于该类
    /// 基线版的出入参需要包含Column属性，数据库字段名成，数据库字段类型(可以为入参给定类型)等
    /// 需要包含StringLength 属性，标明在表格中显示的宽度，实际显示宽度值 = 长度 * 字体大概像素宽度，其中各种字体的不同SIZE对应的像素宽度是不同的，具体每个字符的像素宽度也是不同的，因此只能估计
    /// 包含DisplayName属性，在表中的标题显示
    /// 以上属性均进行为空判断
    /// </summary>
    public class EntityBase
    {


        /// <summary>
        /// 动态增加datagridview列
        /// </summary>
        /// <param name="dgv"></param>
        /// <param name="headerText"></param>
        /// <param name="dataPropertyName"></param>
        protected void AddDGVColumn(DataGridView dgv, string headerText, string dataPropertyName, int width = 120,bool isAdapter = false)
        {
            DataGridViewColumn newColumn = new DataGridViewTextBoxColumn();
            newColumn.HeaderText = headerText;
            newColumn.Width = width;
            newColumn.DataPropertyName = dataPropertyName;
            newColumn.Name = dataPropertyName;
            if (isAdapter) newColumn.AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells;
            dgv.Columns.Add(newColumn);

            
        }

        public void SetHeaderText(DataGridView dgv,Font font)
        {
            Type type = this.GetType();
            var properties = type.GetProperties();
            dgv.AutoGenerateColumns = false;
            dgv.Columns.Clear();
            dgv.Font = font;
            foreach (var property in properties)
            {
                //获取显示名称
                var display = property.GetCustomAttribute<DisplayNameAttribute>();
                if (display == null) continue;
                string dispalyName = display.DisplayName;
                int disLen = CalculateVarCharLength(dispalyName);

                var strLength = property.GetCustomAttribute<StringLengthAttribute>();
                if (strLength == null) continue;
                int len = strLength.MaximumLength;
                int width =  len>disLen ? (int)(len*6.5f) : (int)(disLen * 6.5f);

                bool isAdapter = width > 200;
                
                AddDGVColumn(dgv, dispalyName, property.Name, width,isAdapter);

            }

            dgv.CellValueChanged += DataGridView_CellValueChanged;
        }



        /// <summary>
        /// 计算字符串在 VarChar 类型中的长度（以字节为单位）
        /// </summary>
        /// <param name="input">要计算长度的字符串</param>
        /// <returns>字符串在 VarChar 类型中的长度</returns>
        public static int CalculateVarCharLength(string input)
        {
            // 使用 UTF-16 编码计算字符串的字节数
            Encoding utf16Encoding = Encoding.UTF8;
            byte[] bytes = utf16Encoding.GetBytes(input);
            return bytes.Length;
        }


        /// <summary>
        /// 将实体类转换为数据库入参(Json)
        /// </summary>
        public  JObject ConvertToDBJson()
        {
            Type type = this.GetType();
            var properties = type.GetProperties();
            JObject joRtn = new JObject();
            foreach (var property in properties)
            {
                var attribute = property.GetCustomAttribute<ColumnAttribute>();
                if (attribute == null) continue;
                string fieldName = attribute.Name;

                // 使用 BindingFlags 来允许访问非公共属性
                object value = property.GetValue(this, null);

                // 保持原始数据类型
                JToken token = value == null ? JValue.CreateNull() : JToken.FromObject(value);

                joRtn.Add(fieldName, token);
            }
            return joRtn;
        }

        private static void DataGridView_CellValueChanged(object sender, DataGridViewCellEventArgs e)
        {
            // 只有在最后一列编辑完成时才会触发此事件
            if (e.RowIndex == -1 && e.ColumnIndex == -1)
            {
                AdjustColumnWidths((DataGridView)sender);
            }
        }

        private static void AdjustColumnWidths(DataGridView dataGridView)
        {
            for (int i = 0; i < dataGridView.Columns.Count; i++)
            {
                DataGridViewColumn column = dataGridView.Columns[i];


                // 获取列标题的宽度
                float titleSize = CalculateVarCharLength(column.HeaderText);
                float maxWidth = titleSize;

                // 遍历每一行
                foreach (DataGridViewRow row in dataGridView.Rows)
                {
                    if (!row.IsNewRow && !string.IsNullOrEmpty(row.Cells[i].Value?.ToString()))
                    {
                        float cellSize = CalculateVarCharLength(row.Cells[i].Value.ToString());
                        maxWidth = Math.Max(maxWidth, cellSize);
                    }
                }

                // 设置列宽
                column.Width = (int)Math.Ceiling(maxWidth) + 5; // 加上一点额外空间
            }
        }
    }
}
