using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using AMESCoreStudio.WebApi;
using AMESCoreStudio.WebApi.Models.AMES;
using AMESCoreStudio.CommonTools.Result;
using AMESCoreStudio.WebApi.DTO.AMES;

namespace AMESCoreStudio.WebApi.Controllers.AMES
{
    /// <summary>
    /// 巡檢類別資料维护
    /// </summary>
    [Route("api/[controller]")]
    [ApiController]
    public class InspectionResultMastersController : ControllerBase
    {
        private readonly AMESContext _context;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="context"></param>
        public InspectionResultMastersController(AMESContext context)
        {
            _context = context;
        }

        /// <summary>
        /// 获取全部巡檢類別資料
        /// </summary>
        /// <returns></returns>
        // GET: api/InspectionResultMasters
        [HttpGet]
        public async Task<ActionResult<IEnumerable<InspectionResultMaster>>> GetInspectionResultMasters()
        {
            IQueryable<InspectionResultMaster> q = _context.InspectionResultMasters;
            q = q.OrderBy(p => p.InspectionID);

            var InspectionResultMasters = await q.ToListAsync();

            return InspectionResultMasters;
        }

        /// <summary>
        /// 用ID获取该巡檢類別資料
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        // GET: api/InspectionResultMasters/5
        [HttpGet("{id}")]
        public async Task<ActionResult<IEnumerable<InspectionResultMaster>>> GetInspectionResultMasters(int id)
        {

            IQueryable<InspectionResultMaster> q = _context.InspectionResultMasters;
            q = q.Where(p => p.InspectionID.Equals(id));
            var InspectionResultMaster = await q.ToListAsync();

            if (InspectionResultMaster == null)
            {
                return NotFound();
            }

            return InspectionResultMaster;
        }

        /// <summary>
        /// 用FormID获取该巡檢結果资料
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        // GET: api/InspectionItems/5
        [HttpGet("Form/{id}")]
        public async Task<ActionResult<IEnumerable<InspectionResultMaster>>> GetInspectionResultMastersByFormID(int id)
        {

            IQueryable<InspectionResultMaster> q = _context.InspectionResultMasters;
            q = q.Where(p => p.InspectionFormID.Equals(id));
            q = q.OrderBy(p => p.InspectionID);
            var InspectionResultMaster = await q.ToListAsync();

            if (InspectionResultMaster == null)
            {
                return NotFound();
            }

            return InspectionResultMaster;
        }

        /// <summary>
        /// 用FormID获取该巡檢結果资料
        /// </summary>
        /// <param name="WipNo"></param>
        /// <param name="ItemNo"></param>
        /// <param name="BarcodeNo"></param>
        /// <param name="StatusNo"></param>
        /// <returns></returns>
        // GET: api/InspectionItems/5
        [HttpGet("Query/{WipNo}/{ItemNo}/{BarcodeNo}/{StatusNo}")]
        public async Task<ActionResult<IEnumerable<InspectionResultMaster>>> GetInspectionResultMastersByQuery(string WipNo, string ItemNo, string BarcodeNo, string StatusNo)
        {

            IQueryable<InspectionResultMaster> q = _context.InspectionResultMasters;

            if (!string.IsNullOrWhiteSpace(WipNo))
                q = q.Where(w => w.WipNo == WipNo);

            if (!string.IsNullOrWhiteSpace(ItemNo))
                q = q.Where(w => w.ItemNo == ItemNo);

            if (!string.IsNullOrWhiteSpace(BarcodeNo))
                q = q.Where(w => w.BarcodeNo == BarcodeNo);

            if (!string.IsNullOrWhiteSpace(StatusNo))
                q = q.Where(w => w.StatusNo == StatusNo);

            var InspectionResultMaster = await q.ToListAsync();

            if (InspectionResultMaster == null)
            {
                return InspectionResultMaster;
            }

            return InspectionResultMaster;
        }

        /// <summary>
        /// IPQC查詢報表QRS015
        /// </summary>
        /// <returns></returns>
        [Route("[action]")]
        [HttpGet]
        public async Task<ResultModel<dynamic>> GetIPQCHeaderData4QRS015(string wipNO, string itemNO, string modelNO, string dateStart, string dateEnd)
        {
            //yiru modify 2022-12-19
            ResultModel<dynamic> result = new ResultModel<dynamic>();

            var d = _context.InspectionResultDetails;

            var q = from q0 in _context.InspectionTypes.Where(w => w.InspectionNo.Contains("IPQC"))
                    join q1 in _context.InspectionForms on q0.InspectionTypeID equals q1.InspectionTypeID
                    join q4 in _context.InspectionResultMasters.Where(w => w.StatusNo == "C") on q1.InspectionFormID equals q4.InspectionFormID
                    join q5 in _context.WipAtts on q4.WipNo equals q5.WipNO into cp5
                    from q5 in cp5.DefaultIfEmpty()
                    join q6 in _context.CalendarTables on q4.CreateDate.Date equals q6.TimeID

                    select new
                    {
                        q1.InspectionFormID,
                        q4.CreateDate,
                        q4.WipNo,
                        q5.ItemNO,
                        q5.ModelNO,
                        Result = d.Where(w => w.InspectionID == q4.InspectionID && w.Result == "F").Select(s => s.Result).Count() > 0 ? "F" : "P",
                        IPQCWeek = q6.WeekOfYear
                    };

            if (wipNO != null && wipNO != "")
            {
                q = q.Where(w => w.WipNo == wipNO);
            }
            if (itemNO != null && itemNO != "")
            {
                q = q.Where(w => w.ItemNO == itemNO);
            }
            if (modelNO != null && modelNO != "")
            {
                q = q.Where(w => w.ModelNO == modelNO);
            }
            if (dateStart != null && dateStart != "" && dateEnd != null && dateEnd != "")
            {
                q = q.Where(w => w.CreateDate >= DateTime.Parse(dateStart + " 00:00:00") && w.CreateDate <= DateTime.Parse(dateEnd + " 23:59:59"));
            }

            q = q.OrderBy(w => w.CreateDate);



            //EF.Functions
            var g = q.GroupBy(x => new { x.IPQCWeek }).Select(x => new
            {
                IPQCWeek = x.Key.IPQCWeek,
                IPQCCnt = x.Count(),
                PassCnt = x.Count(i => i.Result == "P"),
                FailCnt = x.Count(i => i.Result == "F")
            });

            g = g.OrderBy(y => y.IPQCWeek);

            //紀錄筆數
            result.DataTotal = g.Count();

            result.Data = await g.ToListAsync();

            if (result == null)
            {
                result.Msg = "查無資料";
                result.Success = false;
                return result;
            }

            result.Success = true;
            result.Msg = "OK";
            return result;
        }


        /// <summary>
        /// 查詢IPQC明細資料
        /// </summary>
        /// <returns></returns>
        [Route("[action]")]
        [HttpGet]
        public async Task<ResultModel<dynamic>> GetIPQCDetailData(string wipNO, string itemNO, string modelNO, string dateStart, string dateEnd, string weekCode, int page = 0, int limit = 10)
        {
            ResultModel<dynamic> result = new ResultModel<dynamic>();

            var d = _context.InspectionResultDetails;

            var q = from q0 in _context.InspectionTypes.Where(w => w.InspectionNo.Contains("IPQC"))
                    join q1 in _context.InspectionForms on q0.InspectionTypeID equals q1.InspectionTypeID
                    join q4 in _context.InspectionResultMasters.Where(w => w.StatusNo == "C") on q1.InspectionFormID equals q4.InspectionFormID
                    join q5 in _context.WipAtts on q4.WipNo equals q5.WipNO into cp5
                    from q5 in cp5.DefaultIfEmpty()
                    join q6 in _context.CalendarTables on q4.CreateDate.Date equals q6.TimeID


                    select new
                    {
                        q1.InspectionFormID,
                        q4.InspectionID,
                        q4.CreateDate,
                        q4.WipNo,
                        q5.ItemNO,
                        q5.ModelNO,
                        q4.BarcodeNo,
                        IPQCWeek = q6.WeekOfYear,
                        Result = d.Where(w => w.InspectionID == q4.InspectionID && w.Result == "F").Select(s => s.Result).Count() > 0 ? "F" : "P"
                    };




            //var q = from q1 in _context.InspectionForms
            //        join q2 in _context.InspectionItems on q1.InspectionFormID equals q2.InspectionFormID
            //        join q3 in _context.InspectionResultDetails on q2.InspectionItemID equals q3.InspectionItemID
            //        join q4 in _context.InspectionResultMasters on q1.InspectionFormID equals q4.InspectionFormID
            //        join q5 in _context.WipAtts on q4.WipNo equals q5.WipNO
            //        join q6 in _context.CalendarTables on q1.CreateDate.Date equals q6.TimeID
            //        join q7 in _context.LineInfoes on q3.LineID equals q7.LineID
            //        select new
            //        {
            //            q1.InspectionFormID,
            //            q1.InspectionNo,
            //            q1.CreateDate,
            //            q4.WipNo,
            //            q5.ItemNO,
            //            q5.ModelNO,
            //            q7.LineDesc,
            //            StationName = q3.Stations.StationName,
            //            q4.BarcodeNo,
            //            q3.Result,
            //            IPQCWeek = q6.WeekOfYear
            //        };

            if (wipNO != null && wipNO != "")
            {
                q = q.Where(w => w.WipNo == wipNO);
            }
            if (itemNO != null && itemNO != "")
            {
                q = q.Where(w => w.ItemNO == itemNO);
            }
            if (modelNO != null && modelNO != "")
            {
                q = q.Where(w => w.ModelNO == modelNO);
            }
            if (dateStart != null && dateStart != "" && dateEnd != null && dateEnd != "")
            {
                q = q.Where(w => w.CreateDate >= DateTime.Parse(dateStart) && w.CreateDate <= DateTime.Parse(dateEnd));
            }
            if (weekCode != null && weekCode != "")
            {
                q = q.Where(w => w.IPQCWeek.Equals(int.Parse(weekCode)));
            }

            //紀錄筆數
            result.DataTotal = q.Count();

            //Table 頁數
            if (page > 0)
            {
                q = q.Skip((page - 1) * limit).Take(limit);
            }

            result.Data = await q.ToListAsync();

            if (result == null)
            {
                result.Msg = "查無資料";
                result.Success = false;
                return result;
            }

            result.Success = true;
            result.Msg = "OK";
            return result;
        }


        /// <summary>
        /// 用FormID获取该巡檢結果资料
        /// </summary>
        /// <param name="id"></param>
        /// <param name="WipNo"></param>
        /// <param name="ItemNo"></param>
        /// <param name="BarcodeNo"></param>
        /// <param name="StatusNo"></param>
        /// <param name="sdate"></param>
        /// <param name="edate"></param>v
        /// <returns></returns>
        // GET: api/InspectionItems/5
        [HttpGet("QueryAll/{id}/{WipNo}/{ItemNo}/{BarcodeNo}/{StatusNo}/{sdate}/{edate}")]
        public async Task<ResultModel<InspectionResultMasterDto>> GetInspectionResultMastersByQueryAll(int id, string WipNo, string ItemNo, string BarcodeNo, string StatusNo, string sdate, string edate, int page = 0, int limit = 10)
        {
            ResultModel<InspectionResultMasterDto> result = new ResultModel<InspectionResultMasterDto>();

            var q = from q1 in _context.InspectionResultMasters
                    join q3 in _context.InspectionResultDetails on q1.InspectionID equals q3.InspectionID
                    //  from q3 in j1.DefaultIfEmpty()

                    select new InspectionResultMasterDto
                    {
                        InspectionID = q1.InspectionID,
                        InspectionFormID = q1.InspectionFormID,
                        BarcodeNo = q1.BarcodeNo,
                        WipNo = q1.WipNo,
                        ItemNo = q1.ItemNo,
                        StatusNo = q1.StatusNo,
                        CreateUserID = q1.CreateUserID,
                        CreateDate = q1.CreateDate,
                        UpdateUserID = q1.UpdateUserID,
                        UpdateDate = q1.UpdateDate,
                        DetailItem = q3.Result != "" ? "1" : "0",
                        DetailPass = q3.Result == "P" ? "1" : "0",
                        DetailFail = q3.Result == "F" ? "1" : "0",
                        DetailNA = q3.Result == "NA" ? "1" : "0",

                    };





            //yiru 2022-11-17
            //    ResultModel<InspectionResultMaster> result = new ResultModel<InspectionResultMaster>();
            //    IQueryable<InspectionResultMaster> q = _context.InspectionResultMasters;

            if (id.ToString() != "-99" && id.ToString() != "0")
                q = q.Where(p => p.InspectionFormID.Equals(id));

            if (WipNo != "*")
                q = q.Where(w => w.WipNo == WipNo);

            if (ItemNo != "*")
                q = q.Where(w => w.ItemNo == ItemNo);

            if (BarcodeNo != "*")
                q = q.Where(w => w.BarcodeNo == BarcodeNo);

            if (StatusNo != "*")
                q = q.Where(w => w.StatusNo == StatusNo);


            DateTime dateValue;
            if (sdate != "*")
            {

                if (DateTime.TryParse(sdate, out dateValue))
                {
                    q = q.Where(p => p.CreateDate >= DateTime.Parse(sdate));
                }
            }
            if (edate != "*")
            {
                if (DateTime.TryParse(edate, out dateValue))
                {
                    q = q.Where(p => p.CreateDate <= DateTime.Parse(edate));
                }

            }
            // 紀錄筆數

            var q0 = q.GroupBy(q => q.InspectionID).Select(cl => new InspectionResultMasterDto
            {
                InspectionID = cl.Max(m => m.InspectionID),
                InspectionFormID = cl.Max(m => m.InspectionFormID),
                BarcodeNo = cl.Max(m => m.BarcodeNo),
                WipNo = cl.Max(m => m.WipNo),
                ItemNo = cl.Max(m => m.ItemNo),
                StatusNo = cl.Max(m => m.StatusNo),
                CreateUserID = cl.Max(m => m.CreateUserID),
                CreateDate = cl.Max(m => m.CreateDate),
                UpdateUserID = cl.Max(m => m.UpdateUserID),
                UpdateDate = cl.Max(m => m.UpdateDate),
                DetailItem = cl.Count(c => c.DetailItem == "1").ToString(),
                DetailPass = cl.Count(c => c.DetailPass == "1").ToString(),
                DetailFail = cl.Count(c => c.DetailFail == "1").ToString(),
                DetailNA = cl.Count(c => c.DetailNA == "1").ToString()

            });






            result.DataTotal = q0.Count();

            // Table 頁數
            if (page > 0)
            {
                q0 = q0.Skip((page - 1) * limit).Take(limit);
            }

            result.Data = await q0.ToListAsync();
            result.Data = result.Data.Select(s =>
            {
                s.StatusNo = s.StatusNo == "C" ? "保存" : "暫存";

                return s;
            }).ToList();

            if (result == null)
            {
                result.Msg = "查無資料";
                result.Success = false;
                return result;
            }

            result.Success = true;
            result.Msg = "OK";
            return result;
        }


        /// <summary>
        /// 用FormID获取该巡檢結果资料
        /// </summary>
        /// <returns></returns>
        [HttpGet("NewID")]
        public ActionResult GetInspectionResultMastersNewID()
        {
            var InspectionResultMasterID = 0;
            Helper helper = new Helper(_context);
            InspectionResultMasterID = helper.GetIDKey("IRMID").Result;
            string str = InspectionResultMasterID.ToString();
            return Content(str);
        }

        /// <summary>
        /// FQC 檢驗 Detail 相關資料 OS CUP RAM BIOS 
        /// </summary>
        /// <param name="wipNo">工單號碼</param>
        /// <returns></returns>
        [HttpGet("ByFQCDetail/{wipNo}")]
        public async Task<ResultModel<dynamic>> GetInsepctionResultMasterByFQCDetail(string wipNo)
        {
            List<string> inspectionItemNames = new List<string> { "OS", "CPU test", "RAM test", "BIOS Ver" };
            ResultModel<dynamic> result = new ResultModel<dynamic>();


            var q = from q1 in _context.InspectionResultMasters.Where(w => w.WipNo.Trim().ToUpper() == wipNo.Trim().ToUpper())
                    join q2 in _context.InspectionResultDetails on q1.InspectionID equals q2.InspectionID
                    join q3 in _context.InspectionItems on q2.InspectionItemID equals q3.InspectionItemID
                    where inspectionItemNames.Contains(q3.InspectionItemName)
                    select new
                    {
                        q1.WipNo,
                        q1.BarcodeNo,
                        q3.InspectionItemName,
                        q2.MissingRemark
                    };


            //紀錄筆數
            result.DataTotal = q.Count();

            result.Data = await q.ToListAsync();

            if (result.Data.Count() == 0)
            {
                result.Msg = "查無資料";
                result.Success = false;
                return result;
            }

            result.Success = true;
            result.Msg = "OK";
            return result;
        }

        /// <summary>
        /// 更新巡檢類別資料
        /// </summary>
        /// <param name="id"></param>
        /// <param name="InspectionResultMaster"></param>
        /// <returns></returns>
        [HttpPut("{id}")]
        public async Task<ResultModel<InspectionResultMaster>> PutInspectionResultMasters(int id, [FromBody] InspectionResultMaster InspectionResultMaster)
        {
            ResultModel<InspectionResultMaster> result = new ResultModel<InspectionResultMaster>();
            _context.Attach(InspectionResultMaster);

            // 指定更新某個欄位
            _context.Entry(InspectionResultMaster).Property(p => p.StatusNo).IsModified = true;
            _context.Entry(InspectionResultMaster).Property(p => p.UpdateDate).IsModified = true;
            _context.Entry(InspectionResultMaster).Property(p => p.UpdateUserID).IsModified = true;

            if (id != InspectionResultMaster.InspectionID)
            {
                result.Success = false;
                result.Msg = "序號錯誤";
                return result;
            }

            _context.Entry(InspectionResultMaster).State = EntityState.Modified;

            try
            {
                await _context.SaveChangesAsync();
            }
            catch (Exception e)
            {
                result.Success = false;
                result.Msg = e.Message;
                return result;
            }

            result.Success = true;
            result.Msg = InspectionResultMaster.InspectionID.ToString();
            return result;
        }

        /// <summary>
        /// 新增巡檢類別資料
        /// </summary>
        /// <param name="InspectionResultMaster"></param>
        /// <returns></returns>
        // POST: api/InspectionResultMasters
        // To protect from overposting attacks, enable the specific properties you want to bind to, for
        // more details, see https://go.microsoft.com/fwlink/?linkid=2123754.
        [HttpPost]
        public async Task<ResultModel<InspectionResultMaster>> PostInspectionResultMasters(InspectionResultMaster InspectionResultMaster)
        {
            ResultModel<InspectionResultMaster> result = new ResultModel<InspectionResultMaster>();
            //Helper helper = new Helper(_context);
            //var InspectionResultMasterID = helper.GetIDKey("IRMID").Result;//先獨立出來給form上船文件就有ID了
            //請RITA加ID
            //InspectionResultMaster.InspectionID = InspectionResultMasterID;
            _context.InspectionResultMasters.Add(InspectionResultMaster);
            try
            {
                await _context.SaveChangesAsync();
            }
            catch (Exception e)            //catch (DbUpdateException)
            {

                result.Success = false;
                result.Msg = e.Message;
                return result;

            }

            result.Success = true;
            result.Msg = InspectionResultMaster.InspectionID.ToString();
            return result;

        }

        /// <summary>
        /// 刪除巡檢類別資料
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        // DELETE: api/InspectionResultMasters/5
        [HttpDelete("{id}")]
        public async Task<ResultModel<InspectionResultMaster>> DeleteInspectionResultMasters(int id)
        {
            ResultModel<InspectionResultMaster> result = new ResultModel<InspectionResultMaster>();
            var inspectionType = await _context.InspectionResultMasters.Where(m => m.InspectionID == id).FirstOrDefaultAsync();
            if (inspectionType == null)
            {
                result.Success = false;
                result.Msg = "序號不存在";
                return result;
            }

            _context.InspectionResultMasters.Remove(inspectionType);
            await _context.SaveChangesAsync();

            result.Success = true;
            result.Msg = "OK";
            return result;
        }

        private bool InspectionResultMastersExists(int id)
        {
            return _context.InspectionResultMasters.Any(e => e.InspectionID == id);
        }

    }
}