using Infrastructure;
using Infrastructure.Attribute;
using Infrastructure.Enums;
using Infrastructure.Model;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using ZR.Admin.WebApi.Extensions;
using ZR.Admin.WebApi.Filters;
using ZR.Common;
using Microsoft.AspNetCore.Authorization;
using MiniExcelLibs;
using ZR.Service.Business;
using ZR.Service.Business.IBusinessService.Inspect;
using ZR.Model.Dto.Inspect;
using ZR.Model.Models.Inspect;
using System.ComponentModel.DataAnnotations;
using AspectCore.DynamicProxy.Parameters;
using ExcelDataReader;
using System.Data;
using Microsoft.IdentityModel.Tokens;
using Aliyun.OSS;

namespace ZR.Admin.WebApi.Controllers.Inspect
{
    /// <summary>
    /// 接口管理/SAP交验单记录表Controller
    /// 
    /// @tableName sap_deliver_record
    /// @author admin
    /// @date 2023-05-05
    /// </summary>
    [Verify]
    [Route("business/SapDeliverRecord")]
    public class SapDeliverRecordController : BaseController
    {
        /// <summary>
        /// 接口管理/SAP交验单记录表接口
        /// </summary>
        private readonly ISapDeliverRecordService _SapDeliverRecordService;

        public SapDeliverRecordController(ISapDeliverRecordService SapDeliverRecordService)
        {
            _SapDeliverRecordService = SapDeliverRecordService;
        }

        /// <summary>
        /// 查询接口管理/SAP交验单记录表列表
        /// </summary>
        /// <param name="parm"></param>
        /// <returns></returns>
        [HttpGet("list")]
        [ActionPermissionFilter(Permission = "business:sapdeliverrecord:list")]
        public IActionResult QuerySapDeliverRecord([FromQuery] SapDeliverRecordQueryDto parm)
        {
            var response = _SapDeliverRecordService.GetList(parm);
            return SUCCESS(response);
        }


        /// <summary>
        /// 查询接口管理/SAP交验单记录表详情
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        [HttpGet("{Id}")]
        [ActionPermissionFilter(Permission = "business:sapdeliverrecord:query")]
        public IActionResult GetSapDeliverRecord(int Id)
        {
            var response = _SapDeliverRecordService.GetFirst(x => x.Id == Id);

            return SUCCESS(response);
        }

        /// <summary>
        /// 添加接口管理/SAP交验单记录表
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        [ActionPermissionFilter(Permission = "business:sapdeliverrecord:add")]
        [Log(Title = "接口管理/SAP交验单记录表", BusinessType = BusinessType.INSERT)]
        public IActionResult AddSapDeliverRecord([FromBody] SapDeliverRecordDto parm)
        {
            if (parm == null)
            {
                throw new CustomException("请求参数错误");
            }
            var modal = parm.Adapt<SapDeliverRecord>().ToCreate(HttpContext);

            var response = _SapDeliverRecordService.AddSapDeliverRecord(modal);

            return ToResponse(response);
        }

        /// <summary>
        /// 更新接口管理/SAP交验单记录表
        /// </summary>
        /// <returns></returns>
        [HttpPut]
        [ActionPermissionFilter(Permission = "business:sapdeliverrecord:edit")]
        [Log(Title = "接口管理/SAP交验单记录表", BusinessType = BusinessType.UPDATE)]
        public IActionResult UpdateSapDeliverRecord([FromBody] SapDeliverRecordDto parm)
        {
            if (parm == null)
            {
                throw new CustomException("请求实体不能为空");
            }
            var modal = parm.Adapt<SapDeliverRecord>().ToUpdate(HttpContext);

            var response = _SapDeliverRecordService.UpdateSapDeliverRecord(modal);

            return ToResponse(response);
        }

        /// <summary>
        /// 删除接口管理/SAP交验单记录表
        /// </summary>
        /// <returns></returns>
        [HttpDelete("{ids}")]
        [ActionPermissionFilter(Permission = "business:sapdeliverrecord:delete")]
        [Log(Title = "接口管理/SAP交验单记录表", BusinessType = BusinessType.DELETE)]
        public IActionResult DeleteSapDeliverRecord(string ids)
        {
            int[] idsArr = Tools.SpitIntArrary(ids);
            if (idsArr.Length <= 0) { return ToResponse(ApiResult.Error($"删除失败Id 不能为空")); }

            var response = _SapDeliverRecordService.Delete(idsArr);

            return ToResponse(response);
        }

        /// <summary>
        /// 导入
        /// </summary>
        /// <param name="formFile">使用IFromFile必须使用name属性否则获取不到文件</param>
        /// <param name="category"></param>
        /// <returns></returns>
        [HttpPost("importData")]
        [Log(Title = "交验单导入", BusinessType = BusinessType.IMPORT, IsSaveRequestData = false, IsSaveResponseData = false)]
        [ActionPermissionFilter(Permission = "business:sapdeliverrecord:import")]
        public IActionResult ImportData([FromForm(Name = "file")] IFormFile formFile, [FromForm(Name = "category")] string category)
        {
            //List<dynamic>? list = new();

            DataSet dataSet = ExcelReader.ReadExcel(formFile);

            if (dataSet == null)
            {
                return SUCCESS("导入失败。<br/><br/>导入交验单文件错误。文件不是xls文件也不是xlsx文件。");
            }
            //if (!dataSet.Tables[0].Rows[0][0].ToString().Contains("北京七星华创"))
            //{
            //    return SUCCESS($"导入失败。<br/><br/>导入Excel的【{dataSet.Tables[0].TableName}】中<br/>表头为：{dataSet.Tables[0].Rows[0][0]}<br/>请确认文件无误。");
            //}
            //通过交验单号，验证是否以存在交验单
            string checkDeliverNo = dataSet.Tables[1].Rows[1][2].ToString().Trim();
            if (string.IsNullOrEmpty(checkDeliverNo))
            {
                return SUCCESS($"导入失败。<br/><br/>导入Excel的【{dataSet.Tables[1].TableName}】中<br/>C列交验单号有误。");
            }
            var response = _SapDeliverRecordService.GetList(
                new SapDeliverRecordQueryDto { DeliverNo = checkDeliverNo });
            if (response.Result.Count > 0)
            {
                return SUCCESS($"导入失败。<br/><br/>导入交验单【{checkDeliverNo}】已存在。");
            }

            //MiniExcel读取导入的Excel文件，因不支持xls格式，弃用。
            //var SheetNames = stream.GetSheetNames();
            //list = stream.Query(sheetName: SheetNames[1]).ToList();


            List<SapDeliverRecord> sapDeliverRecords = new();
            //实例化交验单表对象
            for (int i = 1; i < dataSet.Tables[1].Rows.Count - 1; i++)
            //去除第一行标题行，和最后一行合计行
            {
                //row中空单元格会转化为空字符串而不是null
                SapDeliverRecord sapDeliverRecord = new();
                if (string.IsNullOrEmpty(dataSet.Tables[1].Rows[i][2].ToString().Trim()))
                {
                    return SUCCESS($"导入失败。<br/><br/>导入Excel的【{dataSet.Tables[1].TableName}】中{i + 1}行C列，交验单编号有误。");
                }
                else
                    sapDeliverRecord.DeliverNo = dataSet.Tables[1].Rows[i][2].ToString().Trim();//*
                sapDeliverRecord.CheckName = dataSet.Tables[1].Rows[i][32].ToString().Trim();
                if (string.IsNullOrEmpty(dataSet.Tables[1].Rows[i][14]!.ToString().Trim()))
                {
                    return SUCCESS($"导入失败。<br/><br/>导入Excel的【{dataSet.Tables[1].TableName}】中{i + 1}行O列，生产令号有误。");
                }
                else
                    sapDeliverRecord.BomNo = dataSet.Tables[1].Rows[i][14].ToString().Trim();//*
                if (string.IsNullOrEmpty(dataSet.Tables[1].Rows[i][3].ToString().Trim()))
                {
                    return SUCCESS($"导入失败。<br/><br/>导入Excel的【{dataSet.Tables[1].TableName}】中{i + 1}行D列，行项目有误。");
                }
                else
                    sapDeliverRecord.RowNo = Convert.ToInt32(dataSet.Tables[1].Rows[i][3]);//*
                if (string.IsNullOrEmpty(dataSet.Tables[1].Rows[i][15].ToString().Trim()))
                {
                    return SUCCESS($"导入失败。<br/><br/>导入Excel的【{dataSet.Tables[1].TableName}】中{i + 1}行P列，采购订单号有误。");
                }
                else
                    sapDeliverRecord.PurchaseOrder = dataSet.Tables[1].Rows[i][15].ToString().Trim();//*
                if (string.IsNullOrEmpty(dataSet.Tables[1].Rows[i][17].ToString().Trim()))
                {
                    return SUCCESS($"导入失败。<br/><br/>导入Excel的【{dataSet.Tables[1].TableName}】中{i + 1}行R列，物料编码有误。");
                }
                else
                    sapDeliverRecord.MaterialCode = dataSet.Tables[1].Rows[i][17].ToString().Trim();//*

                if (string.IsNullOrEmpty(dataSet.Tables[1].Rows[i][18].ToString().Trim()))
                {
                    return SUCCESS($"导入失败。<br/><br/>导入Excel的【{dataSet.Tables[1].TableName}】中{i + 1}行S列，物料名称有误。");
                }
                else
                    sapDeliverRecord.MaterialName = dataSet.Tables[1].Rows[i][18].ToString().Trim();//*
                if (string.IsNullOrEmpty(dataSet.Tables[1].Rows[i][19].ToString().Trim()))
                {
                    return SUCCESS($"导入失败。<br/><br/>导入Excel的【{dataSet.Tables[1].TableName}】中{i + 1}行T列，规格型号/图号有误。");
                }
                else
                    sapDeliverRecord.MaterialSpec = dataSet.Tables[1].Rows[i][19].ToString().Trim();//*

                sapDeliverRecord.Category = category;//*
                sapDeliverRecord.KeyFlag = i % 2 > 0;//*//非空 模拟数据

                if (string.IsNullOrEmpty(dataSet.Tables[1].Rows[i][21].ToString().Trim()))
                {
                    return SUCCESS($"导入失败。<br/><br/>导入Excel的【{dataSet.Tables[1].TableName}】中{i + 1}行V列，物料数量有误。");
                }
                else
                    sapDeliverRecord.Qty = Convert.ToInt32(dataSet.Tables[1].Rows[i][21]);//*
                if (string.IsNullOrEmpty(dataSet.Tables[1].Rows[i][23].ToString().Trim()))
                {
                    return SUCCESS($"导入失败。<br/><br/>导入Excel的【{dataSet.Tables[1].TableName}】中{i + 1}行X列，抽检数量有误。");
                }
                else
                    sapDeliverRecord.SpotCheckQty = Convert.ToInt32(dataSet.Tables[1].Rows[i][23]);//*

                //sapDeliverRecord.CheckQty = string.IsNullOrEmpty(dataSet.Tables[1].Rows[i][27].ToString().Trim()) ? 0 : Convert.ToInt32(dataSet.Tables[1].Rows[i][27].ToString().Trim());
                //sapDeliverRecord.InstoreResult = 99;//*//非空 模拟数据

                sapDeliverRecord.CheckQty = 0;
                sapDeliverRecord.InstoreQty = 0;

                sapDeliverRecord.CreateBy = HttpContext.GetName();
                sapDeliverRecord.CreateTime = DateTime.Now;
                sapDeliverRecord.UpdateBy = HttpContext.GetName();
                sapDeliverRecord.UpdateTime = DateTime.Now;
                sapDeliverRecord.Remark = "导入数据";
                string v = sapDeliverRecord.SpotCheckQty > 0 ? ((sapDeliverRecord.CheckQty < sapDeliverRecord.SpotCheckQty) ? (sapDeliverRecord.CheckQty > 0 ? "PartOK" : "NG") : "OK") : "Wait";
                //sapDeliverRecord.CheckResult = v;//计算质检结果，抽检数量为0是未质检Wait，合格数为0则NG，大于零小于抽检数则PartOK，合格数量等于抽检数量则全合格OK
                sapDeliverRecord.CheckResult = "Wait";
                sapDeliverRecords.Add(sapDeliverRecord);

            }

            #region MiniExcel读取导入的Excel文件，因不支持xls格式，弃用。
            //for (int i = 1; i < list.Count; i++)
            //{
            //    if (string.IsNullOrEmpty($"{list[i].A}"))
            //    {
            //        break;//序号一列出现空，即交验单内容结束
            //    }
            //    SapDeliverRecord sapDeliverRecord = new()
            //    {
            //        DeliverNo = list[i].C,
            //        CheckName = list[i].AG,
            //        BomNo = list[i].O,
            //        RowNo = Convert.ToInt32(list[i].D),
            //        PurchaseOrder = list[i].P.ToString(),
            //        MaterialCode = $"MAT{list[i].T}",//非空 模拟数据（交验单中没有这个编码，要自己规范一个吗？
            //        MaterialName = list[i].S,
            //        MaterialSpec = list[i].T,
            //        Category = category,
            //        KeyFlag = i % 2 > 0,//非空 模拟数据
            //        Qty = Convert.ToInt32(list[i].V),
            //        SpotCheckQty = Convert.ToInt32(list[i].X),
            //        CheckQty = Convert.ToInt32(list[i].AB),
            //        CheckResult = list[i].X > 0 ? ((list[i].AB < list[i].X) ? (list[i].AB > 0 ? "PartOK" : "NG") : "OK") : "Wait",//计算质检结果，抽检数量为0是未质检Wait，合格数为0则NG，大于零小于抽检数则PartOK，合格数量等于抽检数量则全合格OK
            //        InstoreResult = 99,//非空 模拟数据

            //        CreateBy = HttpContext.GetName(),
            //        CreateTime = DateTime.Now,
            //        Remark = "导入数据"
            //    };
            //    sapDeliverRecords.Add(sapDeliverRecord);
            //}

            #endregion

            string msg = _SapDeliverRecordService.ImportDatas(sapDeliverRecords);

            //TODO 业务逻辑,自行插入数据到db
            return SUCCESS("交验单导入成功！");
        }

        /// <summary>
        /// 用户导入模板下载  //这里是根据对象字段自动生成的模板，不符合实际使用需要。
        /// </summary>
        /// <returns></returns>
        [HttpGet("importTemplate")]
        [Log(Title = "交验单模板", BusinessType = BusinessType.EXPORT, IsSaveRequestData = false, IsSaveResponseData = false)]
        [AllowAnonymous]
        public IActionResult ImportTemplateExcel()
        {
            List<SapDeliverRecordImportTemplete> list = new();
            MemoryStream stream = new();

            var fileInfo = DownloadImportTemplate(list, stream, "交验单");
            return ExportExcel(fileInfo.Item1, fileInfo.Item2);
        }


        #region 2023 0524 孙亚龙 新增
        /// <summary>
        /// 查询未质检完成的交验单号数据
        /// </summary>
        /// <param name="parm">交验单查询Dto实体类 -- 无分页参数</param>
        /// <returns></returns>
        [HttpPost("QuerySapDeliverData")]
        [ActionPermissionFilter(Permission = "business:sapdeliverrecord:QuerySapDeliverData")]
        public IActionResult QuerySapDeliverData([FromBody] SapDeliverQueryNoPageDto parm)
        {
            var response = _SapDeliverRecordService.GetListNoPage(parm);
            return SUCCESS(response);
        }

        /// <summary>
        /// 根据交验单号获取交验单明细数据
        /// </summary>
        /// <param name="deliverNo">交验单号</param>
        /// <returns></returns>
        [HttpPost("QuerySapDeliverDtlData")]
        [ActionPermissionFilter(Permission = "business:sapdeliverrecord:QuerySapDeliverDtlData")]
        public IActionResult QuerySapDeliverDtlData(string deliverNo)
        {
            var response = _SapDeliverRecordService.GetSapDeliverRecordList(deliverNo);
            return SUCCESS(response);
        }
        [HttpPost("GetSapDeliverRecordSum")]
        public IActionResult GetSapDeliverRecordSum(string materialSpecCode, string deliverNo)
        {
            var response = _SapDeliverRecordService.GetSapDeliverRecordSum(materialSpecCode,deliverNo);
            return SUCCESS(response);
        }

        #endregion
    }
}