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

namespace AMESCoreStudio.WebApi.Controllers.AMES
{
    /// <summary>
    /// 
    /// </summary>
    [Route("api/[controller]")]
    [ApiController]
    public class WipLockController : Controller
    {
        private readonly AMESContext _context;
        private readonly IConfiguration _config;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="context"></param>
        public WipLockController(AMESContext context)
        {
            _config = new ConfigurationBuilder().SetBasePath(Environment.CurrentDirectory).AddJsonFile("appsettings.json").Build();
            _context = context;
        }

        /// <summary>
        /// 工單鎖定資料
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public async Task<ActionResult<IEnumerable<WipLock>>> GetWipLock()
        {
            IQueryable<WipLock> q = _context.WipLocks;
            q = q.OrderBy(p => p.WipNO);
            var WipLock = await q.ToListAsync();
            return WipLock;
        }

        /// <summary>
        /// 工單鎖定資料 to WipLockID
        /// </summary>
        /// <param name="id">WipLockID</param>
        /// <returns></returns>
        [HttpGet("{id}")]
        public async Task<ActionResult<IEnumerable<WipLock>>> GetWipLock(int id)
        {
            IQueryable<WipLock> q = _context.WipLocks;
            var wipLock = await q.Where(p => p.WipLockID == id).ToListAsync();

            //if (result.Data.Count() == 0)
            //{
            //    return NotFound();
            //}

            return wipLock;
        }

        /// <summary>
        /// 工單鎖定資料 to 工單號碼
        /// </summary>
        /// <param name="id">工單號碼</param>
        /// <returns></returns>
        [HttpGet("ByWipNO/{id}")]
        public async Task<ResultModel<WipLock>> GetWipLockByWipNO(string id)
        {
            IQueryable<WipLock> q = _context.WipLocks;

            ResultModel<WipLock> result = new ResultModel<WipLock>();
            result.Data = await q.Where(p => p.WipNO == id).ToListAsync();

            //if (result.Data.Count() == 0)
            //{
            //    return NotFound();
            //}

            return result;
        }

        /// <summary>
        ///  製程工單鎖定查詢
        /// </summary>
        /// <param name="wipNO">工單</param>
        /// <param name="lockstatus">工單狀態</param>
        /// <param name="locktype">鎖定類型</param>
        /// <param name="itemno">料號</param>
        /// <param name="lockreasontype">鎖定原因類別</param>
        /// <param name="stations">站別</param>
        /// <param name="date_str">鎖定日期起</param>
        /// <param name="date_end">鎖定日期迄</param>
        /// <returns></returns>
        [Route("[action]")]
        [HttpGet]
        public async Task<ResultModel<WipLockDto>> GetWipLockQuery(string wipNO, string lockstatus, string locktype
            , string itemno, string lockreasontype, int? stations, string date_str = null, string date_end = null
            , int page = 0, int limit = 10)
        {
            IQueryable<WipLockDto> q = from s in _context.WipLocks
                                       join q2 in _context.UserInfoes on s.LockUserID equals q2.UserID into cp2
                                       from q2 in cp2.DefaultIfEmpty()
                                       join q3 in _context.UserInfoes on s.UnLockUserID equals q3.UserID into cp3
                                       from q3 in cp3.DefaultIfEmpty()
                                       select new WipLockDto
                                       {
                                           WipNO = s.WipNO,
                                           WipLockID = s.WipLockID,
                                           ItemNO = s.WipAtt.ItemNO,
                                           LockDate = s.LockDate,
                                           UnLockDate = s.UnLockDate,
                                           LockUserID = s.LockUserID,
                                           LockReason = s.LockReason,
                                           LockStatus = s.LockStatus,
                                           UnLockUserID = s.UnLockUserID,
                                           UnLockReason = s.UnLockReason,
                                           LockReasonType = s.LockReasonType,
                                           LockReasonTypeName = s.LockReasonType,
                                           LockType = s.LockType,
                                           LockUserName = q2.UserName,
                                           UnLockUserName = q3.UserName,
                                           StationID = s.StationID,
                                           StationName = s.Stations.StationName
                                       };

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

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

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

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

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

            if (stations != null)
                q = q.Where(w => w.StationID == stations);

            if (DateTime.TryParse(date_str, out _))
            {
                q = q.Where(w => w.LockDate >= DateTime.Parse(date_str));
            }

            if (DateTime.TryParse(date_end, out _))
            {
                q = q.Where(w => w.LockDate <= DateTime.Parse(date_end));
            }

            ResultModel<WipLockDto> result = new ResultModel<WipLockDto>();

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

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

            var qq = await q.ToListAsync();
            qq = qq.Select(s =>
            {
                s.LockStatus = s.LockStatus == "0" ? "鎖定" : "解鎖";
                s.LockReasonTypeName = s.LockReasonType == "0" ? "3C認證工單" :
                                       s.LockReasonType == "1" ? "驗證工單" : "維修換料待分析"; return s;
            }).ToList();

            result.Data = qq;
            return result;
        }

        /// <summary>
        /// 根據料號批量鎖定工單
        /// </summary>
        /// <param name="itemNo">料號</param>
        /// <param name="lockReason">鎖定原因</param>
        /// <param name="lockUserNo">鎖定人員</param>
        /// <returns></returns>
        [Route("[action]")]
        [HttpPost]
        public async Task<ResultModel<WipLock>> PostWipLockByItemNo(string itemNo, string lockReason, string lockUserNo)
        {
            ResultModel<WipLock> result = new ResultModel<WipLock>();
            Helper helper = new Helper(_context);

            IQueryable<UserInfo> q1 = _context.UserInfoes;
            q1 = q1.Where(w => w.UserNo == lockUserNo);

            var user = await q1.ToListAsync();

            if (user.Count == 0)
            {
                result.Success = false;
                result.Msg = "查無鎖定人員";
            }
            else
            {
                var q = from a in _context.WipInfos
                        join b in _context.WipAtts on a.WipNO equals b.WipNO
                        select new
                        {
                            a.WipNO,
                            a.StatusNO,
                            b.ItemNO
                        };
                q = q.Where(w => !w.StatusNO.Equals("E") && !w.StatusNO.Equals("C"));

                if (itemNo != null)
                {
                    if (itemNo != "*")
                    {
                        q = q.Where(w => w.ItemNO == itemNo);
                    }
                }
                var wip_att = await q.ToListAsync();

                if (wip_att.Count == 0)
                {
                    result.Success = false;
                    result.Msg = "查無工程編號相關工單";
                }
                else
                {
                    string wip_no_list = "";
                    foreach (var data in wip_att)
                    {
                        WipLock wiplock = new WipLock();

                        wiplock.WipLockID = helper.GetIDKey("WIP_LOCK_ID").Result;
                        wiplock.WipNO = data.WipNO;
                        wiplock.LockReason = lockReason;
                        wiplock.LockUserID = user[0].UserID;
                        wiplock.UnLockUserID = 0;

                        wip_no_list = wip_no_list + data.WipNO + " | ";

                        _context.WipLocks.Add(wiplock);

                        try
                        {
                            await _context.SaveChangesAsync();
                            result.Success = true;
                            result.Msg = "OK";
                        }
                        catch (Exception ex)
                        {
                            result.Success = false;
                            result.Msg = ex.InnerException.Message;
                            break;
                        }
                    }


                    try
                    {
                        //发送鎖定工單资料

                        string mailSubject = "鎖定工單通知郵件" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                        string mailBody = "";
                        mailBody = mailBody + "PLM 單號:" + lockReason + "<br />";
                        mailBody = mailBody + "鎖定工程編號:" + itemNo + "<br />";
                        mailBody = mailBody + "鎖定工單:" + wip_no_list + "<br />";

                        string mailFrom = _config["MailFrom"].ToString();
                        //string mailTo = _config["MailTo"].ToString();
                        string mailSmtpServer = _config["MailSmtpServer"].ToString();
                        int mailSmtpPort = int.Parse(_config["MailSmtpPort"].ToString());
                        string mailUser = _config["MailUser"].ToString();
                        string mailPassword = _config["MailUserPassword"].ToString();

                        MailMessage mesMail = new MailMessage();
                        mesMail.From = new MailAddress(mailFrom);

                        IQueryable<MailGroup> q3 = _context.MailGroups;
                        q3 = q3.Where(p => p.GroupNo.Equals("WIP_LOCK"));
                        var mail1 = await q3.ToListAsync();

                        if (mail1.Count > 0)
                        {
                            var q4 = from a in _context.MailGroups
                                     join b in _context.MailGroupDetails on a.GroupID equals b.GroupID
                                     join c in _context.UserInfoes on b.UserID equals c.UserID
                                     select new
                                     {
                                         a.GroupID,
                                         b.UserID,
                                         c.UserEMail
                                     };

                            q4 = q4.Where(w => w.GroupID.Equals(mail1[0].GroupID));

                            var mail2 = await q4.ToListAsync();
                            if (mail2.Count > 0)
                            {
                                for (int i = 0; i < mail2.Count; i++)
                                {
                                    mesMail.To.Add(new MailAddress(mail2[i].UserEMail));
                                }
                            }

                            //mesMail.To.Add(new MailAddress(mailTo));

                            mesMail.Subject = mailSubject;
                            mesMail.SubjectEncoding = System.Text.Encoding.UTF8;
                            mesMail.Body = mailBody;
                            mesMail.IsBodyHtml = true;
                            mesMail.BodyEncoding = System.Text.Encoding.UTF8;

                            SmtpClient mailClient = new SmtpClient(mailSmtpServer, mailSmtpPort);

                            //mailClient.EnableSsl = true;
                            NetworkCredential nc = new NetworkCredential();
                            nc.UserName = mailUser;
                            nc.Password = mailPassword;
                            mailClient.Credentials = nc;

                            mailClient.Send(mesMail);

                        }
                    }
                    catch { }
                }

            }
            return result;
        }

        /// <summary>
        /// 新增工單鎖定資料檔
        /// </summary>
        /// <param name="wiplock"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ResultModel<WipLock>> PostWipLock([FromBody] WipLock wiplock)
        {
            ResultModel<WipLock> result = new ResultModel<WipLock>();
            Helper helper = new Helper(_context);
            wiplock.WipLockID = helper.GetIDKey("WIP_LOCK_ID").Result;
            _context.WipLocks.Add(wiplock);
            try
            {
                await _context.SaveChangesAsync();
                result.Success = true;
                result.Msg = "OK";
            }
            catch (Exception ex)
            {
                result.Success = false;
                result.Msg = ex.InnerException.Message;
            }
            return result;
        }

        /// <summary>
        /// 工單解鎖資料檔
        /// </summary>
        /// <returns></returns>
        [HttpPut]
        public async Task<ResultModel<WipLock>> PutWipLock([FromBody] WipLock wiplock)
        {
            ResultModel<WipLock> result = new ResultModel<WipLock>();
            _context.WipLocks.Attach(wiplock);
            wiplock.LockStatus = "1";
            wiplock.UnLockDate = DateTime.Now;
            // 指定更新某個欄位
            _context.Entry(wiplock).Property(p => p.UnLockReason).IsModified = true;
            _context.Entry(wiplock).Property(p => p.UnLockDate).IsModified = true;
            _context.Entry(wiplock).Property(p => p.UnLockUserID).IsModified = true;
            try
            {
                await _context.SaveChangesAsync();
                result.Success = true;
                result.Msg = "OK";
            }
            catch (Exception ex)
            {
                result.Success = false;
                result.Msg = ex.InnerException.Message;
            }
            return result;
        }
    }
}