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.WebApi.Models.BAS;
using AMESCoreStudio.CommonTools.Result;
using Microsoft.Extensions.Configuration;
using System.Net;
using System.Net.Mail;

namespace AMESCoreStudio.WebApi.Controllers.AMES
{
    /// <summary>
    /// 工單警報資料
    /// </summary>
    [Route("api/[controller]")]
    [ApiController]
    public class WipAlarmsController : ControllerBase
    {
        private readonly AMESContext _context;
        private readonly IConfiguration _config;

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

        /// <summary>
        /// 獲取全部警報資料
        /// </summary>
        /// <returns></returns>
        // GET: api/WipAlarms
        [HttpGet]
        public async Task<ActionResult<IEnumerable<WipAlarm>>> GetWipAlarm()
        {
            IQueryable<WipAlarm> q = _context.WipAlarms;
            q = q.OrderBy(p => p.AlarmTypeID);
            var wipAlarm = await q.ToListAsync();

            return wipAlarm;
        }

        /// <summary>
        /// 根據警報類型ID查詢警報資料
        /// </summary>
        /// <param name="alarmTypeID"></param>
        /// <param name="wipNO"></param>
        /// <param name="page"></param>
        /// <param name="limit"></param>
        /// <returns></returns>
        [Route("[action]")]
        [HttpGet]
        public async Task<ResultModel<WipAlarm>> GetWipAlarm2(int alarmTypeID, string wipNO, int page = 0, int limit = 10)
        {
            ResultModel<WipAlarm> result = new ResultModel<WipAlarm>();

            IQueryable<WipAlarm> q = _context.WipAlarms;

            if (alarmTypeID > 0)
            {
                q = q.Where(p => p.AlarmTypeID.Equals(alarmTypeID));
            }
            if (wipNO != "" && wipNO != null)
            {
                q = q.Where(p => p.WipNO.Equals(wipNO));
            }

            result.DataTotal = q.ToList().Count;

            if (page > 0)
            {
                q = q.OrderBy(p => p.AlarmDateTime).Skip((page - 1) * limit).Take(limit);
            }
            else
            {
                q = q.OrderBy(p => p.AlarmDateTime);
            }

            var wipAlarm = await q.ToListAsync();

            result.Data = wipAlarm;

            if (wipAlarm == null)
            {
                result.Success = false;
                result.Msg = "查无资料";
                return result;
            }

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

        /// <summary>
        /// 根據警報類型ID查詢警報資料
        /// </summary>
        /// <param name="id"></param>
        /// <param name="page"></param>
        /// <param name="limit"></param>
        /// <returns></returns>
        [HttpGet("Type/{id}")]
        public async Task<ResultModel<WipAlarm>> GetWipAlarm(int id, int page = 0, int limit = 10)
        {
            ResultModel<WipAlarm> result = new ResultModel<WipAlarm>();

            IQueryable<WipAlarm> q = _context.WipAlarms;

            if (id > 0)
            {
                q = q.Where(p => p.AlarmTypeID.Equals(id));
            }

            result.DataTotal = q.ToList().Count;

            if (page > 0)
            {
                q = q.OrderBy(p => p.AlarmDateTime).Skip((page - 1) * limit).Take(limit);
            }
            else
            {
                q = q.OrderBy(p => p.AlarmDateTime);
            }

            var wipAlarm = await q.ToListAsync();

            result.Data = wipAlarm;

            if (wipAlarm == null)
            {
                result.Success = false;
                result.Msg = "查无资料";
                return result;
            }

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

        /// <summary>
        /// 根據警報ID查詢警報資料
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        // GET: api/WipAlarms/5
        [HttpGet("{id}")]
        public async Task<ActionResult<IEnumerable<WipAlarm>>> GetWipAlarm(int id)
        {
            IQueryable<WipAlarm> q = _context.WipAlarms;
            q = q.Where(p => p.WipAlarmID.Equals(id));

            var wipAlarm = await q.ToListAsync();

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

            return wipAlarm;
        }

        /// <summary>
        /// By 工單號碼與治具編號查詢通知
        /// </summary>
        /// <param name="wipNo">工單號碼</param>
        /// <param name="outfitNo">治具編號</param>
        /// <returns></returns>
        [HttpGet("ByOutfit")]
        public async Task<ActionResult<IEnumerable<WipAlarm>>> GetWipAlarmByOutfit(string wipNo , string outfitNo)
        {
            IQueryable<WipAlarm> q = _context.WipAlarms.Where(w => w.WipNO == wipNo.Trim().ToUpper() && w.AlarmParam == outfitNo.Trim().ToUpper());
            var wipAlarm = await q.ToListAsync();
            return wipAlarm;
        }

        /// <summary>
        /// 修改警報資料
        /// </summary>
        /// <param name="id"></param>
        /// <param name="wipAlarm"></param>
        /// <returns></returns>
        // PUT: api/WipAlarms/5
        // 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.
        [HttpPut("{id}")]
        public async Task<ResultModel<WipAlarm>> PutWipAlarm(int id, WipAlarm wipAlarm)
        {
            ResultModel<WipAlarm> result = new ResultModel<WipAlarm>();

            if (id != wipAlarm.WipAlarmID)
            {
                result.Success = false;
                result.Msg = "警報編號錯誤";
                return result;
            }

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

            try
            {
                await _context.SaveChangesAsync();
            }
            catch (DbUpdateConcurrencyException)
            {
                if (!WipAlarmExists(id))
                {
                    result.Success = false;
                    result.Msg = "警報編號不存在";
                    return result;
                }
                else
                {
                    throw;
                }
            }

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

        /// <summary>
        /// 新增警報資料
        /// </summary>
        /// <param name="wipAlarm"></param>
        /// <returns></returns>
        // POST: api/WipAlarms
        // 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<WipAlarm>> PostWipAlarm(WipAlarm wipAlarm)
        {
            ResultModel<WipAlarm> result = new ResultModel<WipAlarm>();

            Helper helper = new Helper(_context);
            wipAlarm.WipAlarmID = helper.GetIDKey("WIP_ALARMID").Result;

            _context.WipAlarms.Add(wipAlarm);
            await _context.SaveChangesAsync();

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

        /// <summary>
        /// 判斷同一不良代碼累計預警
        /// </summary>
        /// <param name="wipNO">工單號碼</param>
        /// <param name="errorCode">不良代碼</param>
        /// <returns></returns>
        [Route("[action]")]
        [HttpPost]
        public async Task<ResultModel<string>> PostWipAlarm4ErrorCode(string wipNO, string errorCode)
        {
            ResultModel<string> result = new ResultModel<string>();

            //判断预警
            var q1 = from a in _context.NgComponents
                     join b in _context.NgInfos on a.NgID equals b.NgID
                     join c in _context.BarcodeInfoes on b.BarcodeID equals c.BarcodeID
                     join d in _context.WipInfos on c.WipID equals d.WipID
                     join e in _context.WipAtts on d.WipNO equals e.WipNO
                     join f in _context.NGReasons on a.NgNo equals f.NGReasonNo
                     join g in _context.Stationses on b.StationId equals g.StationID
                     join h in _context.UserInfoes on b.CreateUserID equals h.UserID
                     select new
                     {
                         a.NgNo,
                         f.NGReasonDesc,
                         d.WipNO,
                         d.WerksNO,
                         c.BarcodeNo,
                         g.StationName,
                         b.CreateDate,
                         h.UserName,
                         e.ItemNO,
                         e.ModelNO
                     };

            q1 = q1.Where(w => w.WipNO.Equals(wipNO));
            q1 = q1.Where(w => w.NgNo.Equals(errorCode));

            var data1 = await q1.ToListAsync();

            if (data1.Count > 3)
            {
                try
                {
                    string itemNo = data1[0].ItemNO;
                    string modelNo = data1[0].ModelNO;
                    string errorDesc = data1[0].NGReasonDesc;
                    string werksNo = data1[0].WerksNO;

                    //保存警报资料
                    string alarmDesc = string.Format("工單號碼{0}不良代碼{1}:{3}累積超過{2}次", wipNO, errorCode, data1.Count, errorDesc);

                    Helper helper = new Helper(_context);

                    WipAlarm wipAlarm = new WipAlarm();
                    wipAlarm.WipAlarmID = helper.GetIDKey("WIP_ALARMID").Result;
                    wipAlarm.AlarmTypeID = 1;
                    wipAlarm.WipNO = wipNO;
                    wipAlarm.AlarmParam = errorCode;
                    wipAlarm.AlarmValue = data1.Count.ToString();
                    wipAlarm.AlarmDesc = alarmDesc;
                    wipAlarm.AlarmDateTime = DateTime.Now;

                    _context.WipAlarms.Add(wipAlarm);
                    await _context.SaveChangesAsync();

                    //发送警报资料

                    string webSiteUrl = _config["WebSiteUrl"].ToString();
                    string viewUrl = webSiteUrl + "/QRS/QRS018A/" + wipNO;

                    //2023-08-20 BB.Wang Modify
                    //工單號碼 + (工程編號) + - +  異常原因;
                    //string mailSubject = "警報持續郵件" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                    string mailSubject = wipNO + " (" + itemNo + ")" + " - " + alarmDesc;

                    string mailBody = "";
                    mailBody = mailBody + "警報工單:" + wipNO + ",廠別:" + werksNo + ",工程編號:" + itemNo + ",機種:" + modelNo + "<br />";
                    mailBody = mailBody + "警報時間:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "<br />";
                    mailBody = mailBody + "警報原因:" + alarmDesc + "<br />";
                    mailBody = mailBody + "警報鏈接:<a href='" + viewUrl + "'>" + viewUrl + "</a><br />";

                    mailBody = mailBody + "詳細資訊:<br />";

                    string tableData = "";
                    tableData = tableData + "<table border = '1' width='100%' cellspacing='2px' cellpadding='10px'>";
                    tableData = tableData + "<tr bgcolor='#66CCFF' height='30'><td>生產序號</td><td>發生站別</td><td>不良代碼</td><td>不良描述</td><td>發生時間</td><td>作業人員</td></tr>";
                    for (int i = 0; i < data1.Count; i++)
                    {
                        string lineData = "<tr height='30'><td>" + data1[i].BarcodeNo + "</td><td>" + data1[i].StationName + "</td><td>" + data1[i].NgNo + "</td><td>" + data1[i].NGReasonDesc + "</td><td>" + data1[i].CreateDate.ToString("yyyy-MM-dd HH:mm:ss") + "</td><td>" + data1[i].UserName + "</td></tr>";
                        tableData = tableData + lineData;

                    }
                    tableData = tableData + "</table>";

                    mailBody = mailBody + tableData;

                    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_ALARM"));
                    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 { }

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

        /// <summary>
        /// 
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        // DELETE: api/WipAlarms/5
        [HttpDelete("{id}")]
        public async Task<ResultModel<WipAlarm>> DeleteWipAlarm(int id)
        {
            ResultModel<WipAlarm> result = new ResultModel<WipAlarm>();

            var wipAlarm = await _context.WipAlarms.FindAsync(id);
            if (wipAlarm == null)
            {
                result.Success = false;
                result.Msg = "警報編號不存在";
                return result;
            }

            _context.WipAlarms.Remove(wipAlarm);
            await _context.SaveChangesAsync();

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

        private bool WipAlarmExists(int id)
        {
            return _context.WipAlarms.Any(e => e.WipAlarmID == id);
        }
    }
}