using System.Collections;
using System.Data;
using System.Reflection;
using SqlSugar;
using Tiobon.Core.Common.DB.Dapper;

namespace Tiobon.Core.Api.Controllers;

/// <summary>
/// 学分记录(Controller)
/// </summary>
[Route("api/[controller]")]
[ApiController, GlobalActionFilter]
[Authorize(Permissions.Name), ApiExplorerSettings(GroupName = Grouping.GroupName_Ghre)]
public class Ghre_CreditPointController : BaseController<IGhre_CreditPointServices, Ghre_CreditPoint, Ghre_CreditPointDto, InsertGhre_CreditPointInput, EditGhre_CreditPointInput>
{
    public Ghre_CreditPointController(IGhre_CreditPointServices service) : base(service)
    {
    }

    #region 查询明细数据
    /// <summary>
    /// 查询明细数据
    /// </summary>
    /// <param name="body">body</param>
    /// <returns></returns>
    [HttpPost, Route("QueryTotal")]
    public async Task<ServicePageResult<Ghre_CreditPointTotal>> QueryTotal([FromBody] QueryBody body)
    {
        return await _service.QueryTotal(body, null);
    }



    #endregion

    #region 根据工号查询学分明细
    /// <summary>
    /// 根据工号查询学分明细
    /// </summary>
    /// <param name="body"></param>
    /// <param name="staffId">员工ID</param>
    /// <returns></returns>
    [HttpPost("QueryDetail/{staffId}")]
    public async Task<ServicePageResult<Ghre_CreditPointDetail>> QueryDetail([FromBody] QueryBody body, string staffId)
    {
        return await _service.QueryDetail(body, staffId);
    }
    #endregion



    [HttpPost, Route("ExportExcel")]
    public override async Task<ServiceResult<ExcelData>> ExportExcel([FromBody] QueryExport body)
    {
        QueryBody filter = new QueryBody();
        filter.pageNum = 1;
        filter.pageSize = 1000000;
        filter.langId = body.langId;

        var condition = "1=1";
        if (body.exportSet.SelectRowKeys != null && body.exportSet.SelectRowKeys.Any())
            condition += $" AND Id IN({string.Join(",", body.exportSet.SelectRowKeys)})";

        var data = await _service.QueryTotal(filter, condition);

        string sql = $@"SELECT *
                            FROM Ghrs_PageSettingQuery
                            WHERE     IsEnable = 1
                                  AND PageNo = '{body.menuName}'
                                  AND (defaultHidden = 'false' OR defaultHidden is null)
                            ORDER BY SortNo ASC";

        var columns = DbAccess.QueryList<QueryExportColumn>(sql);

        var fieldDescs = new Dictionary<string, string>();
        if (body.exportSet.ExFields.Any())
            body.exportSet.ExFields.ForEach(x =>
            {
                if (columns.Any(o => o.field == x))
                    fieldDescs.Add(x, columns.FirstOrDefault(o => o.field == x)?.label);
            });
        else
            fieldDescs = columns.ToDictionary(item => item.field, item => item.label);
        var dt = ToDataTable1(data.result.DT_TableDataT1, fieldDescs, null);
        // 获取所有列名
        var dtColumns = dt.Columns;

        var id = SnowFlakeSingle.instance.getID();
        var physicsPath = $"{Environment.CurrentDirectory}{Path.DirectorySeparatorChar}wwwroot";
        var path = $"{$"{Path.DirectorySeparatorChar}files{Path.DirectorySeparatorChar}export{Path.DirectorySeparatorChar}{id}{Path.DirectorySeparatorChar}"}";
        if (!Directory.Exists(physicsPath + path))
            Directory.CreateDirectory(physicsPath + path);

        path = path + body.exportSet.TitleName + ".xlsx";
        NPOIHelper.ExportExcel(dt, body.exportSet.TitleName, "sheet1", physicsPath + path);

        var result = new ExcelData();
        result.filePath = path;
        result.fileName = body.exportSet.TitleName + ".xlsx";
        return ServiceResult<ExcelData>.OprateSuccess("导出成功", result);
    }
    public static DataTable ToDataTable1(List<Ghre_CreditPointTotal> list, Dictionary<string, string> fieldDescs = null, params string[] propertyName)
    {
        var (fields, colunms) = Sort(fieldDescs, null);

        List<string> propertyNameList = new List<string>();
        if (propertyName != null)
        {
            propertyNameList.AddRange(propertyName);
        }
        DataTable result = new DataTable();
        if (list.Count > 0)
        {
            PropertyInfo[] propertys = list[0].GetType().GetProperties();
            for (int i = 0; i < fields.Count; i++)
            {
                foreach (PropertyInfo pi in propertys)
                {
                    if (propertyNameList.Count == 0)
                    {
                        //if (DBNull.Value.Equals(pi.PropertyType))
                        //{
                        //   // pi.PropertyType = DateTime;
                        //}
                        Type colType = pi.PropertyType;
                        if (colType.IsGenericType && colType.GetGenericTypeDefinition() == typeof(Nullable<>))
                        {
                            colType = colType.GetGenericArguments()[0];
                        }
                        if (fields[i] == pi.Name)
                        {
                            result.Columns.Add(colunms[i], colType);
                        }
                        //result.Columns.Add(pi.Name, pi.PropertyType);
                    }
                    else
                    {
                        if (propertyNameList.Contains(pi.Name))
                        {
                            if (fields[i] == pi.Name)
                                result.Columns.Add(fields[i], pi.PropertyType);
                        }
                    }
                }
            }
            for (int i = 0; i < list.Count; i++)
            {
                ArrayList tempList = new ArrayList();
                for (int j = 0; j < fields.Count; j++)
                {
                    foreach (PropertyInfo pi in propertys)
                    {
                        if (fields[j] == pi.Name)
                        {
                            if (propertyNameList.Count == 0)
                            {
                                object obj = pi.GetValue(list[i], null);
                                tempList.Add(obj);
                            }
                            else
                            {
                                if (propertyNameList.Contains(pi.Name))
                                {
                                    object obj = pi.GetValue(list[i], null);
                                    tempList.Add(obj);
                                }
                            }
                        }
                    }
                }
                object[] array = tempList.ToArray();
                result.LoadDataRow(array, true);
            }
        }
        return result;
    }
}