using AMESCoreStudio.CommonTools.Result;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System.Threading.Tasks;
using System;
using Microsoft.Extensions.Configuration;
using System.Net;
using System.Linq;
using System.Collections.Generic;
using AMESCoreStudio.WebApi.Controllers.AMES;
using AMESCoreStudio.WebApi.Controllers.BAS;

namespace AMESCoreStudio.WebApi.Controllers.BLL
{
    /// <summary>
    /// QRS統計資料
    /// </summary>
    [Route("api/[controller]")]
    [ApiController]
    public class QRSPPMController : ControllerBase
    {
        private readonly AMESContext _context;
        private readonly IConfiguration _config;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="context"></param>
        public QRSPPMController(AMESContext context, IConfiguration config)
        {
            _config = config;
            _context = context;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="wipNO"></param>
        /// <param name="itemNO"></param>
        /// <param name="customer"></param>
        /// <param name="dateStart"></param>
        /// <param name="dateEnd"></param>
        /// <param name="page"></param>
        /// <param name="limit"></param>
        /// <returns></returns>
        [HttpGet("GetQRS024Data")]
        public async Task<ResultModel<PcbaPPMDTO>> GetQRS024Data(string wipNO, string itemNO, string customer, string dateStart, string dateEnd, string bdateStart, string bdateEnd, int page = 0, int limit = 10)
        {

            ResultModel<PcbaPPMDTO> result = new ResultModel<PcbaPPMDTO>();
            List<PcbaPPMDTO> PPMData = new List<PcbaPPMDTO>();
            List<PcbaPPMDTO> PPMDataPage = new List<PcbaPPMDTO>();
            
            IQueryable<PcbaPPMDTO> queryd;

            try
            {
                if ((bdateStart != null && bdateEnd != null) || (dateStart != null && dateEnd != null))
                {
                    if (bdateStart != null && bdateEnd != null)
                    {


                        queryd = from b in _context.BarcodeStation.Where(w => w.InputDate >= DateTime.Parse(bdateStart) && w.InputDate <= DateTime.Parse(bdateEnd).AddDays(1))
                                 join w in _context.WipInfos on b.WipID equals w.WipID
                                 join a in _context.WipAtts on w.WipNO equals a.WipNO
                                 join f in _context.FactoryUnits.Where(w => w.UnitNo == "S" || w.UnitNo == "D") on w.UnitNO equals f.UnitNo
                                 select new PcbaPPMDTO
                                 {
                                     UnitNo = w.UnitNO,
                                     UnitName = f.UnitName,
                                     UnitCode = f.UnitCode,
                                     WipID = w.WipID,
                                     WipNo = w.WipNO,
                                     ItemNo = a.ItemNO,
                                     PlanQty = w.PlanQTY,
                                     FlowRuleID = w.FlowRuleID
                                 };
                    }
                    else
                    {
                        queryd = from b in _context.NgInfos.Where(w => w.CreateDate >= DateTime.Parse(dateStart) && w.CreateDate <= DateTime.Parse(dateEnd).AddDays(1))
                                 join w in _context.WipInfos on b.WipId equals w.WipID
                                 join a in _context.WipAtts on w.WipNO equals a.WipNO
                                 join f in _context.FactoryUnits.Where(w => w.UnitNo == "S" || w.UnitNo == "D") on w.UnitNO equals f.UnitNo
                                 select new PcbaPPMDTO
                                 {
                                     UnitNo = w.UnitNO,
                                     UnitName = f.UnitName,
                                     UnitCode = f.UnitCode,
                                     WipID = w.WipID,
                                     WipNo = w.WipNO,
                                     ItemNo = a.ItemNO,
                                     PlanQty = w.PlanQTY,
                                     FlowRuleID = w.FlowRuleID
                                 };

                    }

                    if (wipNO != null)
                    {
                        queryd = queryd.Where(p => p.WipNo.Equals(wipNO));
                    }
                    if (itemNO != null)
                    {
                        queryd = queryd.Where(p => p.ItemNo.Equals(itemNO));
                    }
                    if (customer != null)
                    {
                        queryd = queryd.Where(p => p.ItemNo.StartsWith(customer));
                    }
                    var q = queryd.Select(s => new { s.UnitNo, s.UnitName, s.UnitCode, s.WipNo, s.WipID, s.ItemNo, s.FlowRuleID, s.PlanQty }).Distinct();
                    foreach (var item in q)
                    {

                        #region 查詢完工數
                        RuleStationsController ruleStationsController = new RuleStationsController(_context);
                        var ruleStations = ruleStationsController.GetRuleStationByFlow(item.FlowRuleID, 0).Result.Value.ToList();
                        int FinishStationID = 0;

                        if (ruleStations.Count > 0)
                        {
                            int Sequence = ruleStations.Where(w => w.StationID == 1000).Select(s => s.Sequence).FirstOrDefault();
                            FinishStationID = ruleStations.Where(w => w.Sequence == Sequence - 1).Select(s => s.StationID).FirstOrDefault();
                        }

                        BarcodeStationController barcodeStationController = new BarcodeStationController(_context);
                        var barcodeStatios = await barcodeStationController.GetBarcodeStationByDateInputQty(item.WipID, FinishStationID);

                        #endregion
                        var FinishQTYDate = barcodeStatios;
                        if (FinishQTYDate.Count() > 0)
                        {
                            #region 查詢A/B面零件數
                            var plmBom = await _context.PlmBoms.Where(w => w.MatnrP == item.ItemNo + "-" + item.UnitCode).ToListAsync();
                            //  PlmBomsController  plmBomsController = new PlmBomsController(_context);
                            //  var plmBom = plmBomsController.GetPlmBombyMATERP(item.ItemNo + "-" + item.UnitCode);
                            string joinedString = string.Join(",", plmBom.Select(s => s.Ebort1 + s.Ebort2));
                            int PartsA = 0;
                            int PartsB = 0;

                            var parts = joinedString.Split(",");
                            PartsA = parts.Count(s => s.StartsWith("A"));
                            PartsB = parts.Count(s => s.StartsWith("B"));


                            #endregion


                            foreach (var itemQty in FinishQTYDate)
                            {
                                #region 查詢不良零件數
                                int ngPartsA = 0;
                                int ngPartsB = 0;

                                if (itemQty.barcodeID != null)
                                {
                                    NgInfoController ngInfoController = new NgInfoController(_context);
                                    var ngpart = await ngInfoController.GetNgInfoByWipID(item.WipID);
                                    ngpart.Data = ngpart.Data.Where(w => w.NGDateTime >= DateTime.Parse(itemQty.FinishDate) && w.NGDateTime <= DateTime.Parse(itemQty.FinishDate).AddDays(1));

                                    if (ngpart.Data.Count() > 0)
                                    {

                                        var listc = ngpart.Data
                                           .SelectMany(w =>
                                               parts.Where(s =>
                                                   w.LocationNo.Length + 1 == s.Length && s.EndsWith(w.LocationNo)))
                                           .Distinct()
                                           .ToList();
                                        ngPartsA += listc.Count(w => w.StartsWith("A"));
                                        ngPartsB += listc.Count(w => w.StartsWith("B"));
                                    }
                                }
                                #endregion
                                #region 計算PPM
                                double PPMA = 0;
                                double PPMB = 0;
                                if (PartsA != 0 && ngPartsA != 0)
                                {
                                    PPMA = ((double)ngPartsA / (PartsA * itemQty.FinishQty)) * 1000000.0;
                                }
                                if (PartsB != 0 && ngPartsB != 0)
                                {
                                    PPMB = ((double)ngPartsB / (PartsB * itemQty.FinishQty)) * 1000000.0;
                                }

                                #endregion
                                PPMData.Add(new PcbaPPMDTO
                                {
                                    WipID = item.WipID,
                                    WipNo = item.WipNo,
                                    ItemNo = item.ItemNo,
                                    UnitNo = item.UnitNo,
                                    UnitName = item.UnitName,
                                    PlanQty = item.PlanQty,
                                    FinishDate = itemQty.FinishDate,
                                    FinishQty = itemQty.FinishQty,
                                    Site = "A",
                                    ComponentQty = PartsA, //bom零件數分A/B面
                                    NGQty = ngPartsA,
                                    PPM = PPMA
                                });

                                PPMData.Add(new PcbaPPMDTO
                                {
                                    WipID = item.WipID,
                                    WipNo = item.WipNo,
                                    ItemNo = item.ItemNo,
                                    UnitNo = item.UnitNo,
                                    UnitName = item.UnitName,
                                    PlanQty = item.PlanQty,
                                    FinishDate = itemQty.FinishDate,
                                    FinishQty = itemQty.FinishQty,
                                    Site = "B",
                                    ComponentQty = PartsB, //bom零件數分A/B面
                                    NGQty = ngPartsB,
                                    PPM = PPMB
                                });
                            }
                        }
                    }
                    if (page > 0)
                    {
                        PPMDataPage = PPMData.Skip((page - 1) * limit).Take(limit).ToList();
                    }
                }
                result.DataTotal = PPMData.Count();
                result.Data = PPMDataPage.ToList();
                result.Success = true;
                return result;

            }
            catch (Exception ex)
            {
                result.Success = false;
                result.Msg = ex.Message;
                return result;
            }



        }

        /// <summary>
        /// 查詢生產效率PPM
        /// </summary>
        /// <param name="itemNO"></param>
        /// <param name="customer"></param>
        /// <param name="dateStart"></param>
        /// <param name="dateEnd"></param>
        /// <returns></returns>
        [HttpGet("GetQRS026Data")]
        public async Task<ResultModel<dynamic>> GetQRS026Data(string itemNO, string customer, string dateStart, string dateEnd)
        {

            ResultModel<dynamic> result = new ResultModel<dynamic>();
            List<PcbaPPMDTO> PPMData = new List<PcbaPPMDTO>();
            try
            {
              var   queryd = from b in _context.BarcodeStation.Where(w => w.InputDate >= DateTime.Parse(dateStart) && w.InputDate <= DateTime.Parse(dateEnd).AddDays(1))
                                 join w in _context.WipInfos on b.WipID equals w.WipID
                                 join a in _context.WipAtts on w.WipNO equals a.WipNO
                                 join f in _context.FactoryUnits.Where(w => w.UnitNo == "S" || w.UnitNo == "D")  on w.UnitNO equals f.UnitNo
                                 select new PcbaPPMDTO
                                 {
                                     UnitNo = w.UnitNO,
                                     UnitName = f.UnitName,
                                     UnitCode = f.UnitCode,
                                     WipID = w.WipID,
                                     WipNo = w.WipNO,
                                     ItemNo = a.ItemNO,
                                     PlanQty = w.PlanQTY,
                                     FlowRuleID = w.FlowRuleID
                                 };



                if (itemNO != null)
                {
                    queryd = queryd.Where(p => p.ItemNo.Equals(itemNO));
                }
                if (customer != null)
                {
                    queryd = queryd.Where(p => p.ItemNo.StartsWith(customer));
                }
                    var q = queryd.Select(s => new { s.UnitNo, s.UnitName, s.UnitCode, s.WipNo, s.WipID, s.ItemNo, s.FlowRuleID, s.PlanQty }).Distinct();
                foreach (var item in q)
                {

                    #region 查詢完工數
                    RuleStationsController ruleStationsController = new RuleStationsController(_context);
                    var ruleStations = await ruleStationsController.GetRuleStationByFlow(item.FlowRuleID, 0);
                    int FinishStationID = 0;

                    if (ruleStations.Value.Count() > 0)
                    {
                        int Sequence = ruleStations.Value.Where(w => w.StationID == 1000).Select(s => s.Sequence).FirstOrDefault();
                        FinishStationID = ruleStations.Value.Where(w => w.Sequence == Sequence - 1).Select(s => s.StationID).FirstOrDefault();
                    }

                    BarcodeStationController barcodeStationController = new BarcodeStationController(_context);
                    var FinishQty = await barcodeStationController.GetBarcodeStationByDateInputQty(item.WipID, FinishStationID);
                    FinishQty = FinishQty.Where(w => DateTime.Parse(w.FinishDate) >= DateTime.Parse(dateStart) && DateTime.Parse(w.FinishDate) <= DateTime.Parse(dateEnd).AddDays(1));
                    #endregion

                    #region 查詢零件數
                    var plmBom = await _context.PlmBoms.Where(w => w.MatnrP == item.ItemNo + "-" + item.UnitCode).ToListAsync();
                    string joinedString = string.Join(",", plmBom.Select(s => s.Ebort1 + s.Ebort2));
                    var parts = joinedString.Split(",");
                    parts = parts.Where(s => !string.IsNullOrEmpty(s)).ToArray();
                    int PartsALL = parts.Count();
                    #endregion
                    #region 查詢不良零件數

                    int ngPartsALL = 0;

                    NgInfoController ngInfoController = new NgInfoController(_context);
                    var ngpart = await ngInfoController.GetNgInfoByWipID(item.WipID);
                    ngpart.Data = ngpart.Data.Where(w => w.NGDateTime >= DateTime.Parse(dateStart) && w.NGDateTime <= DateTime.Parse(dateEnd).AddDays(1));
                    if (ngpart.Data.Count() > 0)
                    {
                        ngpart.Data = ngpart.Data.Where(w => w.LocationNo != "NA" && w.LocationNo != "N/A" && !string.IsNullOrEmpty(w.LocationNo));
                        
                        ngPartsALL = ngpart.Data.Count();
                    }
                    #endregion
                    PPMData.Add(new PcbaPPMDTO
                    {
                        WipID = item.WipID,
                        WipNo = item.WipNo,
                        ItemNo = item.ItemNo,
                        UnitNo = item.UnitNo,
                        UnitName = item.UnitName,
                        PlanQty = item.PlanQty,
                        FinishQty = FinishQty.Sum(s => s.FinishQty),
                        ComponentQty = PartsALL, //bom零件數(1PCS)
                        NGQty = ngPartsALL,

                    });

                }

                var g=  PPMData.GroupBy(item => item.UnitNo).Select(group => new PcbaPPMRate
                {
                         UnitNo = group.Key,
                         Parts = group.Sum(item => item.FinishQty * item.ComponentQty),
                         NgParts = group.Sum(item => item.NGQty),
                         IPC = (group.Sum(item => item.FinishQty * item.ComponentQty) == 0) ? 0
                         : Math.Round((group.Sum(item => item.NGQty) / group.Sum(item => item.FinishQty * item.ComponentQty)) * 1000000,2)}).ToList();

                if (g.Count() < 2)
                {
                    if (g.Where(w => w.UnitNo == "D").Count() == 0)
                    {
                        g.Add(new PcbaPPMRate
                        {
                            UnitNo = "D",
                            Parts = 0,
                            NgParts = 0,
                            IPC = 0
                        });
                    }
                    if (g.Where(w => w.UnitNo == "S").Count() == 0)
                    {
                        g.Add(new PcbaPPMRate
                        {
                            UnitNo = "S",
                            Parts = 0,
                            NgParts = 0,
                            IPC = 0
                        });
                    }
                }

                result.DataTotal = g.Count();
                result.Data =  g; 
                result.Success = true;
                return result;

            }
            catch (Exception ex)
            {
                result.Success = false;
                result.Msg = ex.Message;
                return result;
            }



        }



    }
}