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_ExamRecordController : BaseController<IGhre_ExamRecordServices, Ghre_ExamRecord, Ghre_ExamRecordDto, InsertGhre_ExamRecordInput, EditGhre_ExamRecordInput>
{
    public Ghre_ExamRecordController(IGhre_ExamRecordServices service) : base(service)
    {
    }


    #region 根据条件查询数据
    /// <summary>
    /// 根据条件查询数据
    /// </summary>
    /// <param name="examId">examId</param>
    /// <param name="body">条件</param>
    /// <returns></returns>
    [HttpPost, Route("QueryList/{examId}")]
    public async Task<ServicePageResult<Ghre_ExamRecordDto>> Query(string examId, [FromBody] QueryBody body)
    {
        return await _service.Query(examId, body);
    }
    #endregion

    [HttpPost("ModifyAdjustScore/{examRecordId}")]
    public async Task<ServiceResult> ModifyAdjustScore(string examRecordId, [FromBody] EditGhre_ExamRecordInput edit)
    {
        return await _service.ModifyAdjustScore(examRecordId, edit);
    }

    [HttpPost("ModifyActualScore/{examRecordId}")]
    public async Task<ServiceResult> ModifyActualScore(string examRecordId, [FromBody] EditGhre_ExamRecordInput edit)
    {
        return await _service.ModifyActualScore(examRecordId, edit);
    }
    [HttpPost("ModifyFinallyIsPass/{examRecordId}")]
    public async Task<ServiceResult> ModifyFinallyIsPass(string examRecordId, [FromBody] EditGhre_ExamRecordInput edit)
    {
        return await _service.ModifyFinallyIsPass(examRecordId, edit);
    }

    /// <summary>
    /// 获取考试记录明细扩展接口
    /// </summary>
    /// <param name="examRecordId"></param>
    /// <returns></returns>
    [HttpPost("QueryExtend/{examRecordId}")]
    public async Task<ServiceResult<Ghre_ExamRecordExtend>> ExtendAsync(long examRecordId)
    {
        return await _service.ExtendAsync(examRecordId, null);
    }
    /// <summary>
    /// 获取考试记录明细扩展接口
    /// </summary>
    /// <param name="examRecordId"></param>
    /// <param name="groupId"></param>
    /// <returns></returns>
    [HttpPost("QueryExtend/{examRecordId}/{groupId}")]
    public async Task<ServiceResult<Ghre_ExamRecordExtend>> ExtendAsync(long examRecordId, long groupId)
    {
        return await _service.ExtendAsync(examRecordId, groupId);
    }

    /// <summary>
    /// 提交评语接口
    /// </summary>
    /// <param name="extend"></param>
    /// <param name="examRecordId"></param>
    /// <returns></returns>
    [HttpPost("Comment/{examRecordId}")]
    public async Task<ServiceResult> CommentAsync([FromBody] Ghre_ExamRecordExtend extend, long examRecordId)
    {
        return await _service.CommentAsync(extend, examRecordId);
    }


    /// <summary>
    /// 获取考试信息
    /// </summary>
    /// <param name="id">学习记录ID/考试记录ID</param> 
    /// <returns></returns>
    [HttpPost("QueryExam/{id}")]
    public async Task<ServiceResult<QueryExam>> QueryExamAsync(long id)
    {
        return await _service.QueryExamAsync(id);
    }

    /// <summary>
    /// 开始考试
    /// </summary> 
    /// <param name="examRecordId"></param>
    /// <returns></returns>
    [HttpPost("StartExam/{examRecordId}")]
    public async Task<ServiceResult> StartExamAsync(long examRecordId)
    {
        return await _service.StartExamAsync(examRecordId);
    }

    /// <summary>
    /// 重新考试
    /// </summary> 
    /// <param name="examRecordId"></param>
    /// <returns></returns>
    [HttpPost("RetakeExam/{examRecordId}")]
    public async Task<ServiceResult> RetakeExamAsync(long examRecordId)
    {
        return await _service.RetakeExamAsync(examRecordId);
    }


    /// <summary>
    /// 答题
    /// </summary> 
    /// <param name="studyRecordId">学习记录ID</param>
    /// <param name="answers"></param>
    /// <returns></returns>
    [HttpPost("AnswerExam/{studyRecordId}")]
    public async Task<ServiceResult> AnswerExamAsync(long studyRecordId, [FromBody] List<DefaultGhre_ExamPaperPreview> answers)
    {
        return await _service.AnswerExamAsync(answers, studyRecordId);
    }

    /// <summary>
    /// 记录查看试卷
    /// </summary> 
    /// <param name="examRecordId"></param>
    /// <returns></returns>
    [HttpPost("ViewExamPaperCallBack/{examRecordId}")]
    public async Task<ServiceResult> ViewExamPaperCallBackAsync(long examRecordId)
    {
        return await _service.ViewExamPaperCallBackAsync(examRecordId);
    }

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

        var condition = $"ExamId='{examId}'";
        if (body.exportSet.SelectRowKeys != null && body.exportSet.SelectRowKeys.Any())
            condition += $" AND Id IN({string.Join(",", body.exportSet.SelectRowKeys)})";
        var data = await _service.QueryFilterPage(filter, condition);
        //var data = await _service.Query(examId, filter) 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_ExamRecordDto> 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)
                        {
                            if (!result.Columns.Contains(colunms[i]))
                                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;
    }

    /// <summary>
    /// 提交附件
    /// </summary> 
    /// <param name="examRecordId"></param>
    /// <returns></returns>
    [HttpPost("SubmitAttachment/{examRecordId}")]
    public async Task<ServiceResult> SubmitAttachment(long examRecordId, [FromBody] List<InsertGhre_AttachmentInput> attachments)
    {
        return await _service.SubmitAttachment(examRecordId, attachments);
    }

    /// <summary>
    /// 查询考试组
    /// </summary> 
    /// <param name="examRecordId"></param>
    /// <returns></returns>
    [HttpPost("QueryGroups/{examRecordId}")]
    public async Task<ServiceResult<List<ExamGroup>>> QueryGroups(long examRecordId)
    {
        return await _service.QueryGroups(examRecordId);
    }


    /// <summary>
    /// IssueCertificate
    /// </summary>  
    /// <returns></returns>
    [HttpPost("IssueCertificate")]
    public async Task<ServiceResult> IssueCertificate()
    {
        return await _service.IssueCertificate();
    }
}