using Microsoft.AspNetCore.Mvc;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using AMESCoreStudio.Web.Models;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using AMESCoreStudio.WebApi;
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc.Rendering;
using AMESCoreStudio.WebApi.Models.AMES;
using AMESCoreStudio.WebApi.Models.BAS;
using AMESCoreStudio.Web.ViewModels;
using AMESCoreStudio.Web.ViewModels.PCS;
using AMESCoreStudio.WebApi.DTO.AMES;
using System.Linq;
using AMESCoreStudio.CommonTools.Result;
using System;
using System.IO;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Hosting;
using System.ComponentModel.DataAnnotations;
using AspNetCore.Reporting;
using System.Text.Encodings;
using AMESCoreStudio.WebApi.Enum;
using AMESCoreStudio.WebApi.Controllers.AMES;

namespace AMESCoreStudio.Web.Controllers
{
    /// <summary>
    /// PCB管理模組
    /// </summary>
    public class PCBController : Controller
    {
        private readonly ILogger<PCBController> _logger;
        public readonly IPCB _pcbApi;
        private readonly IWebHostEnvironment _env;
        public readonly IPCS _pcsApi;
        public readonly IBLL _bllApi;
        public PCBController(ILogger<PCBController> logger, IPCB pcbApi, IWebHostEnvironment env, IPCS pcsApi, IBLL bllApi)
        {
            _logger = logger;
            _pcbApi = pcbApi;
            _env = env;
            _pcsApi = pcsApi;
            _bllApi = bllApi;
        }

        //#region 下拉選單
        /// <summary>
        /// SOP_Type
        /// </summary>
        /// <param name="SelectedValue"></param>
        private void GetSteelPlateStatusSelect(string SelectedValue = null)
        {
            List<string> values = new List<string>();
            if (SelectedValue != null)
            {
                values = SelectedValue.Split(',').ToList();
            }
            var q = Enum.GetValues(typeof(EnumPCB.EnumSteelPlateStatus)).Cast<EnumPCB.EnumSteelPlateStatus>()
                       .Select(s => new SelectListItem
                       {
                           Text = EnumPCB.GetDisplayName(s).ToString(),
                           Value = s.ToString()
                       }).ToList();

            ViewBag.GetSteelPlateStatusSelect = q;
        }
        //#endregion

        #region PCB013 鋼板量測紀錄
        public ActionResult PCB013()
        {
            return View();
        }

        public async Task<IActionResult> PCB013QueryAsync(string steelPlateNo, string pcbPartNo
                     , string side, string status, int page = 0, int limit = 10)
        {
            IResultModel<SteelPlateInfoDto> result = await _pcbApi.GetSteelPlateInfoQuery(steelPlateNo: steelPlateNo, pcbPartNo: pcbPartNo
            , side: side, status: status, page: page, limit: limit);

            if (result.Data.Count() != 0)
            {
                return Json(new Table() { code = 0, msg = "", data = result.Data, count = result.DataTotal });
            }
            return Json(new Table() { count = 0, data = null });
        }

        //新增頁面
        public IActionResult PCB013C()
        {
            return View();
        }

        //修改页面
        [HttpGet]
        public async Task<IActionResult> PCB013U(int id)
        {
            var result = await _pcbApi.GetSteelPlateInfo(id);
            return View(result);
        }

        //頁面提交,id=0 添加,id>0 修改
        [HttpPost]
        public async Task<IActionResult> PCB013Async(SteelPlateInfo model)
        {
            if (ModelState.IsValid)
            {
                IResultModel result;
                if (model.SteelPlateID == 0)
                {
                    model.CreateUserID = GetLogInUserID();
                    model.CreateDate = DateTime.Now;
                    model.UpdateUserID = GetLogInUserID();
                    model.UpdateDate = DateTime.Now;
                    result = await _pcbApi.PostSteelPlateInfo(JsonConvert.SerializeObject(model));
                }
                else
                {
                    model.UpdateUserID = GetLogInUserID();
                    model.UpdateDate = DateTime.Now;
                    result = await _pcbApi.PutSteelPlateInfo(JsonConvert.SerializeObject(model));
                }

                if (result.Success)
                {
                    var _msg = model.SteelPlateID == 0 ? "新增成功!" : "修改成功!";
                    return RedirectToAction("Refresh", "Home", new { msg = _msg });
                }
                else
                {

                    ModelState.AddModelError("error", result.Msg);
                }
            }

            if (model.SteelPlateID == 0)
            {
                return View("PCB013C", model);
            }
            return View("PCB013U", model);
        }


        public IActionResult PCB013A(int steelPlateID, string steelPlateNo)
        {
            GetSteelPlateStatusSelect();
            ViewBag.steelPlateID = steelPlateID;
            ViewBag.steelPlateNo = steelPlateNo;
            return View();
        }

        /// <summary>
        /// 鋼板量測記錄
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<IActionResult> PCB013ASave(SteelPlateMeasure model)
        {

            IResultModel result;
            // 量測基準 35 小於通知寄信
            if (double.Parse(model.Tension1) < 35 || double.Parse(model.Tension2) < 35 || double.Parse(model.Tension3) < 35 ||
                double.Parse(model.Tension4) < 35 || double.Parse(model.Tension5) < 35)
            {
                model.MeasureResult = "F";
                //string Subject = $"FQC自動派送發信 FQC單號:{inhouseNo} 料號:{Material}";
                //string Body = $@"FQC單號:{inhouseNo} 料號:{Material} <br/>
                //                 檢驗結果為:{Result}";

                //await _bllApi.PostToMail(Subject, Body, string.Join(',', MailGroup), "", false, path);
            }
            else
            {
                model.MeasureResult = "P";
            }    
            model.CreateUserID = GetLogInUserID();
            model.CreateDate = DateTime.Now;
            model.UpdateUserID = GetLogInUserID();
            model.UpdateDate = DateTime.Now;
            result = await _pcbApi.PostSteelPlateMeasure(JsonConvert.SerializeObject(model));


            if (result.Success)
            {
                var _msg = "新增量測記錄成功!";
                return RedirectToAction("Refresh", "Home", new { msg = _msg });
            }
            else
            {

                ModelState.AddModelError("error", result.Msg);
            }


            if (model.SteelPlateID == 0)
            {
                return View("PCB013A", model);
            }
            return View("PCB013A", model);
        }

        /// <summary>
        /// 鋼板量測紀錄 View
        /// </summary>
        /// <param name="steelPlateID"></param>
        /// <param name="steelPlateNo"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult PCB013V(int steelPlateID, string steelPlateNo)
        {
            ViewBag.steelPlateID = steelPlateID;
            ViewBag.steelPlateNo = steelPlateNo;
            return View();
        }

        [HttpGet]
        public async Task<IActionResult> PCB013VQuery(int steelPlateID, string steelPlateNo, int page = 0, int limit = 10)
        {
            var result = await _pcbApi.GetSteelPlateMeasureBySteelPlateID(steelPlateID, page, limit);

            if (result.DataTotal > 0)
            {
                return Json(new Table() { code = 0, msg = "", data = result.Data, count = result.DataTotal });
            }

            return Json(new Table() { count = 0, data = null });
        }
        #endregion

        #region PCB014 錫膏使用管控
        public ActionResult PCB014()
        {
            return View();
        }

        public async Task<IActionResult> PCB014QueryAsync(string solderPasteNo, string status, int page = 0, int limit = 10)
        {
            IResultModel<SolderPasteInfoDto> result = await _pcbApi.GetSolderPasteInfoQuery(solderPasteNo: solderPasteNo, status: status, page: page, limit: limit);

            if (result.Data.Count() != 0)
            {
                return Json(new Table() { code = 0, msg = "", data = result.Data, count = result.DataTotal });
            }
            return Json(new Table() { count = 0, data = null });
        }

        //新增頁面
        public IActionResult PCB014C()
        {
            return View();
        }

        //修改页面
        [HttpGet]
        public async Task<IActionResult> PCB014U(int id)
        {
            var result = await _pcbApi.GetSolderPasteInfo(id);
            return View(result);
        }

        //頁面提交,id=0 添加,id>0 修改
        [HttpPost]
        public async Task<IActionResult> PCB014Async(SolderPasteInfo model)
        {
            // 日期判斷
            if (model.EffectiveDate < model.ManufactoringDate)
            {
                ModelState.AddModelError("error", "有效日期不能小於製造日期");
            }
            else if (ModelState.IsValid)
            {
                IResultModel result;

                if (model.SolderPasteID == 0)
                {
                    model.CreateUserID = GetLogInUserID();
                    model.CreateDate = DateTime.Now;
                    model.UpdateUserID = GetLogInUserID();
                    model.UpdateDate = DateTime.Now;
                    result = await _pcbApi.PostSolderPasteInfo(JsonConvert.SerializeObject(model));
                }
                else
                {
                    model.UpdateUserID = GetLogInUserID();
                    model.UpdateDate = DateTime.Now;
                    result = await _pcbApi.PutSolderPasteInfo(JsonConvert.SerializeObject(model));
                }

                if (result.Success)
                {
                    var _msg = model.SolderPasteID == 0 ? "新增成功!" : "修改成功!";
                    return RedirectToAction("Refresh", "Home", new { msg = _msg });
                }
                else
                {
                    ModelState.AddModelError("error", result.Msg);
                }
            }


            if (model.SolderPasteID == 0)
            {
                return View("PCB014C", model);
            }
            return View("PCB014U", model);
        }
        #endregion


        #region PCB015連板綁定作業

        public async Task<IActionResult> PCB015(int WipID)
        {

            return View();
        }

        public async Task<IActionResult> PCB015V(int WipID)
        {

            WipDataViewModel model = new WipDataViewModel();
            var q = await _pcsApi.GetWipInfo(WipID);
            if (q.Count != 0)
            {
                model.wipInfo = q.FirstOrDefault();
                model.wipAtt = await _pcsApi.GetWipAtt(model.wipInfo.WipNO);
                model.wipBarcodes = await _pcsApi.GetWipBarcode(model.wipInfo.WipNO);
                model.wipBarcode = model.wipBarcodes.FirstOrDefault();
                model.ruleStations = await _pcsApi.GetRuleStationByWipNo(model.wipInfo.WipNO, model.wipInfo.FlowRuleID);

            }
            
            return View("PCB015V", model);
        }


        public async Task<IActionResult> PCB015GetGroupAsync(int id, string groupID =null , int page = 0, int limit = 10)
        {
          var result = await _pcbApi.GetBarcodeGroupsByWipID(id: id , groupID : groupID, page: page, limit: limit);
            //groupID = '' 抓全部
            //groupID = 0 不抓資料

            if (result.Data.Count() != 0)
            {
                return Json(new Table() { code = 0, msg = "", data = result.Data, count = result.DataTotal });
            }
            return Json(new Table() { count = 0, data = null });
        }
        public async Task<IActionResult> GetWipInfoAsync(string id,string unit_No)
        {

            var result = await _pcsApi.GetWipAtt(id);
            if (result != null)
            {
                var result1 = await _pcsApi.GetWipInfoByWipNO(id);
                var GroupData = await _pcbApi.GetBarcodeGroupsByWipID(result1.Where(w => w.UnitNO == unit_No).Select(s => s.WipID).FirstOrDefault(), "");
                string GroupQTY = GroupData.DataTotal.ToString();

                result.Side = result1.Where(w => w.UnitNO == unit_No).Select(s => s.WipID).FirstOrDefault();
                result.CPN = GroupQTY + "/" + result1.Where(w => w.UnitNO == unit_No).Select(s => s.PlanQTY).FirstOrDefault().ToString();
                result.PBType = result1.Where(w => w.UnitNO == unit_No).Select(s => s.PlanQTY).FirstOrDefault().ToString();

                if (result != null)
                {
                    return Json(new Result() { success = true, msg = "", data = result });
                   // return Json(new Table() { code = 0, msg = "", data = result, count = 1 });
                }
            }

            // return Json(new Table() { count = 0, msg = "查無工單資料", data = null });
            return Json(new Result() { success = false, msg = "查無工單資料", data = null });
        }

        /// <summary>
        /// 刪除連板群組
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<IActionResult> PCB015DAsync(int id)
        {
          var result =   await _pcsApi.DeleteBarcodeGroupByGroupID(id);
            return Json(new Result() { success = true, msg = "刪除成功" });
        }


        public async Task<IActionResult> CheckBarcodeNOandGroupAsync(string BarcodeNo, string WipNo,int WipID,int Boards,string PlanQTY)
        {
            //生產序號不在工單區間
            var WipBarcode = await _pcbApi.GetWipBarcodesCheckInRange(WipNo, BarcodeNo);
            int snLen = PlanQTY.Length;
            if (snLen < 4) snLen = 4;
            if (WipBarcode.Count > 0 )
            {
                #region 取區間內最大號
                int Maxnumber = 0;
                string WipBarcodeEnd = WipBarcode.Select(s => s.EndNO).LastOrDefault();
                if (WipBarcodeEnd.Length < 4)
                {
                    return Json(new Result() { success = false, msg = "生產序號區間長度不可小於4", data = WipBarcodeEnd });
                }
                bool conversionSuccessful = int.TryParse(WipBarcodeEnd.Substring(WipBarcodeEnd.Length - snLen, snLen), out Maxnumber);
                if (!conversionSuccessful)
                {

                    return Json(new Result() { success = false, msg = "生產序號區間未" + snLen.ToString() + "碼不為數字", data = WipBarcodeEnd });
                }
                #endregion

                #region 依連板展開序號
                //此段在展開序號可判斷是否已超出結束序號,若有超出則乎略
                List<string> serialNumbers = Enumerable.Range(0, Boards)
               .Select(i =>
               {
                    string newSerialNumber = $"{BarcodeNo.Substring(0, BarcodeNo.Length - snLen)}{(int.Parse(BarcodeNo.Substring(BarcodeNo.Length - snLen)) + i).ToString().PadLeft(snLen, '0')}";
                   return newSerialNumber;
               })
               .TakeWhile(serialNumber => int.Parse(serialNumber.Substring(serialNumber.Length - snLen)) <= Maxnumber)
               .ToList();


                #endregion

                #region 展開的序號是否在區間內

                #endregion

                #region  判斷展開的序號是否已綁Group & 產生BarcodeInfo 
                foreach (var item in serialNumbers)
                {
                    var BarCodeinto = await _pcsApi.GetBarcodeInfoesByNo(item);
                    if (BarCodeinto.Count() > 0)
                    {
                        var BarcodeGroup = await _pcsApi.GetBarcodeGroupByBarCodeID(BarCodeinto.Select(s => s.BarcodeID).FirstOrDefault());
                        if (BarcodeGroup.Count() > 0)
                        {
                            return Json(new Result() { success = false, msg = "生產序號" + item + "已綁定群組"+ BarcodeGroup.Select(s=>s.GroupID).FirstOrDefault()+ ",不可重覆綁定", data = null });
                        }
                    }
                    else
                    {
                       var barcodeInfo = new BarcodeInfo
                        {
                            BarcodeNo = item,
                            StationID = -1,
                            LocationID = -1,
                            WipID = WipID,
                            RuleStatus = "P",
                            StatusID = -1,
                            SysType = "S",
                            StatusNo = "-1",
                            CreateUserID = GetLogInUserID()
                       };
                   
                      var PostResult =   await _pcsApi.PostBarcodeInfoes(JsonConvert.SerializeObject(barcodeInfo));

                    }
                }
                #endregion

                #region 綁定Group
               var barcodeinfo = await _pcsApi.GetBarcodeInfoesByWipNo(WipNo);
                barcodeinfo = barcodeinfo.Where(w => serialNumbers.Contains(w.BarcodeNo)).OrderBy(o=>o.BarcodeNo).ToList();
                int GroupID = 0;
                int SEQ = 1;
                int UserID = GetLogInUserID();
            
                List<BarcodeGroup> barcodeGroups = barcodeinfo
                .Select((b, index) => new BarcodeGroup
                {
                    BarcodeID = b.BarcodeID,
                    GroupID = 0,
                    Sequence = index + 1,
                    CreateUserID = UserID
                })
                .ToList();

                var BarCodeGroup = await _pcbApi.PostBarcodeGroupList(JsonConvert.SerializeObject(barcodeGroups));

                //foreach (var item in barcodeinfo)
                //{
                //    var x = new BarcodeGroup
                //    {
                //        GroupID = GroupID,
                //        BarcodeID = item.BarcodeID,
                //        Sequence = SEQ,
                //        CreateUserID = GetLogInUserID()
                //    };

                //    var BarCodeGroup = await _pcsApi.PostBarcodeGroup(JsonConvert.SerializeObject(x));
                //    if (GroupID == 0)
                //    {
                //        var result = await _pcsApi.GetBarcodeGroupByBarCodeID(item.BarcodeID);
                //        if (result.Count() > 0)
                //        {
                //            GroupID = result.Select(s => s.GroupID).FirstOrDefault();
                //            SEQ++;
                //        }
                //    }
                //    else
                //        SEQ++;
                //}

               



                return Json(new Result() { success = true, msg = "綁定成功", data = BarCodeGroup.Data.Select(s=>s.GroupID).FirstOrDefault() });

                #endregion

            }
            return Json(new Result() { success = false, msg = "生產序號不在工單區間內", data = null });


        }
        #endregion

        /// <summary>
        /// 登入UserID
        /// </summary>
        /// <returns></returns>
        public int GetLogInUserID()
        {
            int user_id = -1;
            HttpContext.Request.Cookies.TryGetValue("UserID", out string userID);

            if (userID != null)
            {
                if (int.Parse(userID.ToString()) >= 0)
                {
                    user_id = int.Parse(userID.ToString());
                }
            }
            return user_id;
        }
    }
}