using AMESCoreStudio.CommonTools.Result;
using AMESCoreStudio.WebApi.DTO.AMES;
using AMESCoreStudio.WebApi.Enum;
using AMESCoreStudio.WebApi.Models.AMES;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Dapper;
using System.Data;
using AMESCoreStudio.WebApi.Extensions;
using Microsoft.Extensions.Configuration;
using AMESCoreStudio.WebApi.Controllers;

namespace AMESCoreStudio.WebApi.Controllers.AMES
{
    /// <summary>
    /// 錫膏基本資料檔
    /// </summary>
    [Route("api/[controller]")]
    [ApiController]
    public class SolderPasteInfoController : ControllerBase
    {
        private readonly AMESContext _context;
        private readonly IConfiguration _config;

        public SolderPasteInfoController(AMESContext context, IConfiguration config)
        {
            _config = config;
            _context = context;
        }

        // GET: api/SolderPasteInfo
        [HttpGet]
        public async Task<ActionResult<IEnumerable<SolderPasteInfo>>> GetSolderPasteInfos()
        {
            return await _context.SolderPasteInfos.ToListAsync();
        }

        // GET: api/SolderPasteInfo/5
        [HttpGet("{id}")]
        public async Task<ActionResult<SolderPasteInfo>> GetSolderPasteInfo(int id)
        {
            var solderPasteInfo = await _context.SolderPasteInfos.FindAsync(id);

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

            return solderPasteInfo;
        }

        /// <summary>
        /// 錫膏資料查詢
        /// </summary>
        /// <param name="solderPasteNo">錫膏編號</param>
        /// <param name="description">規格</param>
        /// <param name="vendor">廠商</param>
        /// <param name="status">狀態</param>
        /// <param name="page">頁數</param>
        /// <param name="limit">筆數</param>
        /// <returns></returns>
        [HttpGet("SolderPasteInfoQuery")]
        public async Task<ResultModel<SolderPasteInfoDto>> GetSolderPasteInfo(string solderPasteNo, string description, string vendor, string status, int page = 0, int limit = 10)
        {
            var q = await _context.SolderPasteInfos.ToListAsync();

            if (!string.IsNullOrWhiteSpace(solderPasteNo))
            {
                q = q.Where(w => w.SolderPasteNo.Contains(solderPasteNo)).ToList();
            }

            if (!string.IsNullOrWhiteSpace(description))
            {
                q = q.Where(w => w.Description.Contains(description)).ToList();
            }

            if (!string.IsNullOrWhiteSpace(vendor))
            {
                q = q.Where(w => w.Vendor.Contains(vendor)).ToList();
            }

            if (!string.IsNullOrWhiteSpace(status))
            {
                q = q.Where(w => w.Status == status).ToList();
            }
            ResultModel<SolderPasteInfoDto> result = new ResultModel<SolderPasteInfoDto>();

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

            // Table 頁數
            if (page > 0)
            {
                q = q.Skip((page - 1) * limit).Take(limit).ToList();
            }
            result.Data = q.Select(s => new SolderPasteInfoDto
            {
                SolderPasteID = s.SolderPasteID,
                SolderPasteNo = s.SolderPasteNo,
                Description = s.Description,
                Alloy = s.Alloy,
                Vendor = s.Vendor,
                Lot = s.Lot,
                EffectiveDate = s.EffectiveDate,
                ManufactoringDate = s.ManufactoringDate,
                ReceiptDate = s.ReceiptDate,
                Status = s.Status,
                StatusName = EnumPCB.GetDisplayName((EnumPCB.EnumSolderPasteStatus)System.Enum.Parse(typeof(EnumPCB.EnumSolderPasteStatus), s.Status)),
                Remark = s.Remark
            }).ToList();
            return result;
        }

        /// <summary>
        /// 錫膏資料 By狀態 查詢
        /// </summary>
        /// <param name="id">狀態</param>
        /// <returns></returns>
        [HttpGet("SolderPasteInfoByStatus/{id}")]
        public async Task<List<SolderPasteInfo>> GetSolderPasteInfoByStatus(string id)
        {
            if (id != "X")
            {
                var result = await _context.SolderPasteInfos.Where(w => w.Status == id).OrderBy(o => o.SolderPasteNo).ToListAsync();
                return result;
            }
            else
            {
                // 要報廢 不找已經報廢或已經使用完的錫膏
                var result = await _context.SolderPasteInfos.Where(w => w.Status != "X" && w.Status != "C").OrderBy(o => o.SolderPasteNo).ToListAsync();
                return result;
            }
        }

        /// <summary>
        /// 錫膏資料 ByNO 查詢
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet("BySolderPasteNo/{id}")]
        public async Task<ActionResult<SolderPasteInfo>> GetSolderPasteInfo(string id)
        {
            var q = await _context.SolderPasteInfos.Where(w => w.SolderPasteNo == id).FirstOrDefaultAsync();
            return q;
        }




        /// <summary>
        /// 錫膏Report By產線
        /// </summary>
        /// <param name="solderPasteNo">錫膏編號</param>
        /// <param name="status">狀態</param>
        /// <param name="wipNo">工單號碼</param>
        /// <param name="strDate">開始_收貨時間</param>
        /// <param name="endDate">結束_收貨時間</param>
        /// <param name="page">頁數</param>
        /// <param name="limit">筆數</param>
        /// <returns></returns>
        [HttpGet("Report")]
        public ResultModel<PCB017ViewDto> GetSolderPasteInfoReport(string solderPasteNo, string status, string wipNo,
            string strDate, string endDate, int page = 0, int limit = 10)
        {
            ResultModel<PCB017ViewDto> result = new ResultModel<PCB017ViewDto>();
            var sql = @"SELECT 
                        I.SOLDER_PASTE_ID AS SolderPasteID ,
                        I.SOLDER_PASTE_NO AS SolderPasteNo ,
                        I.DESCRIPTION AS Description ,
                        I.VENDOR AS Vendor ,
                        I.ALLOY AS Alloy ,
                        I.LOT AS Lot ,
                        I.WIP_NO AS WipNo ,
                        I.STATUS AS StatusName ,
                        I.RECEIPT_DATE AS ReceiptDate,
                        I.MANUFACTORING_DATE AS ManufactoringDate,
                        I.EFFECTIVE_DATE AS EffectiveDate,
                        I.REMARK AS Remark ,
                        U.USER_NAME AS CreateUserName ,
                        I.CREATE_DATE AS CreateTime ,
                        -- 入冰箱
                        U1.USER_NAME AS InUserName ,
                        R1.CREATE_DATE AS InTime ,
                        -- 出冰箱
                        U2.USER_NAME AS OutUserName ,
                        R2.CREATE_DATE AS OutTime ,
                        -- 開封
                        U3.USER_NAME AS UseUserName ,
                        R3.CREATE_DATE AS UseTime ,
                        -- 用完
                        U5.USER_NAME AS CompletedUserName ,
                        R5.CREATE_DATE AS CompletedTime ,
                        -- 報廢
                        U4.USER_NAME AS ScrapUserName ,
                        R4.CREATE_DATE AS ScrapTime ,
                        -- 攪拌時間
                        CASE 
                                WHEN R3.CREATE_DATE IS NOT NULL THEN R3.CREATE_DATE - INTERVAL '2' MINUTE
                                ELSE NULL
                        END AS MixingTime
                        FROM JHAMES.SOLDER_PASTE_INFO I
                        INNER JOIN JHSYS.USER_INFO U ON I.CREATE_USERID = U.USER_ID 
                        LEFT JOIN JHAMES.SOLDER_PASTE_RECORD R1 ON I.SOLDER_PASTE_ID = R1.SOLDER_PASTE_ID AND R1.STATUS = 'I' -- 入冰箱
                        LEFT JOIN JHSYS.USER_INFO U1 ON R1.CREATE_USERID = U1.USER_ID 
                        LEFT JOIN JHAMES.SOLDER_PASTE_RECORD R2 ON I.SOLDER_PASTE_ID = R2.SOLDER_PASTE_ID AND R2.STATUS = 'O' -- 出冰箱
                        LEFT JOIN JHSYS.USER_INFO U2 ON R2.CREATE_USERID = U2.USER_ID 
                        LEFT JOIN JHAMES.SOLDER_PASTE_RECORD R3 ON I.SOLDER_PASTE_ID = R3.SOLDER_PASTE_ID AND R3.STATUS = 'U' -- 開封
                        LEFT JOIN JHSYS.USER_INFO U3 ON R3.CREATE_USERID = U3.USER_ID 
                        LEFT JOIN JHAMES.SOLDER_PASTE_RECORD R4 ON I.SOLDER_PASTE_ID = R4.SOLDER_PASTE_ID AND R4.STATUS = 'X' -- 報廢
                        LEFT JOIN JHSYS.USER_INFO U4 ON R4.CREATE_USERID = U4.USER_ID 
                        LEFT JOIN JHAMES.SOLDER_PASTE_RECORD R5 ON I.SOLDER_PASTE_ID = R5.SOLDER_PASTE_ID AND R5.STATUS = 'C' -- 用完
                        LEFT JOIN JHSYS.USER_INFO U5 ON R5.CREATE_USERID = U5.USER_ID 
                        WHERE NOT EXISTS (
                                            SELECT 1
                                            FROM JHAMES.SOLDER_PASTE_INFO I1
                                            WHERE I.SOLDER_PASTE_ID = I1.SOLDER_PASTE_ID
                                              AND I1.STATUS = 'WI'
                                        )";

            DynamicParameters p = new DynamicParameters();

            if (!string.IsNullOrWhiteSpace(solderPasteNo))
            {
                sql += " AND I.SOLDER_PASTE_NO LIKE :solderPasteNo ";
                p.Add("solderPasteNo", $"%{solderPasteNo}%", DbType.AnsiString);
            }

            if (!string.IsNullOrWhiteSpace(wipNo))
            {
                sql += " AND I.WIP_NO LIKE :wipNo ";
                p.Add("wipNo", $"%{wipNo}%", DbType.AnsiString);
            }

            if (!string.IsNullOrWhiteSpace(status))
            {
                sql += " AND I.STATUS = :status ";
                p.Add("status", status, DbType.AnsiString);
            }

            if (DateTime.TryParse(strDate, out _))
            {
                sql += " AND I.RECEIPT_DATE >= TO_DATE(:strDate, 'YYYY-MM-DD HH24:MI:SS')";
                p.Add("strDate", $"{strDate} 00:00:00");
            }

            if (DateTime.TryParse(endDate, out _))
            {
                sql += " AND I.RECEIPT_DATE <= TO_DATE(:endDate, 'YYYY-MM-DD HH24:MI:SS') ";
                p.Add("endDate", $"{endDate} 23:59:59");
            }

            try
            {
                var q = _context.Database.DapperQuery<PCB017ViewDto>(sql, p);

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

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

                result.Data = q;

                // 狀態
                result.Data = result.Data.Select(s =>
                {
                    s.StatusName = s.StatusName == "WO" ? "未使用" :
                                   s.StatusName == "I" ? "入冰箱" :
                                   s.StatusName == "O" ? "出冰箱" :
                                   s.StatusName == "U" ? "開封" :
                                   s.StatusName == "C" ? "使用完" :
                                   s.StatusName == "X" ? "報廢" : s.StatusName
                    ; return s;
                }).ToList();
            }
            catch (Exception ex)
            {
                result.Success = false;
                result.Msg = ex.Message;
            }


            return result;
        }

        /// <summary>
        /// 錫膏Report By倉庫
        /// </summary>
        /// <returns></returns>
        [HttpGet("ReportByWareHouse")]
        public async Task<ResultModel<dynamic>> GetSolderPasteInfoReportByWareHouse()
        {
            ResultModel<dynamic> result = new ResultModel<dynamic>();
            var sql = @" SELECT DESCRIPTION , COUNT(*) AS QTY FROM JHAMES.SOLDER_PASTE_INFO
                         WHERE STATUS = 'WI'
                         GROUP BY DESCRIPTION ";

            DynamicParameters p = new DynamicParameters();
            try
            {
                var q = await _context.Database.DapperQueryAsync<dynamic>(sql, p);

                // 紀錄筆數
                result.DataTotal = q.Count();
                result.Data = q;
            }
            catch (Exception ex)
            {
                result.Success = false;
                result.Msg = ex.Message;
            }
            return result;
        }

        /// <summary>
        /// 錫膏排程 報廢
        /// </summary>
        /// <returns></returns>
        [HttpGet("Scheduling")]
        public async Task<ResultModel<SolderPasteInfo>> GetSolderPasteInfoScheduling(int userId = 0)
        {
            ResultModel<SolderPasteInfo> result = new ResultModel<SolderPasteInfo>();
            var sql = @"SELECT I.SOLDER_PASTE_ID AS SolderPasteID ,
                        I.SOLDER_PASTE_NO AS SolderPasteNo ,
                        I.STATUS AS Status ,
                        R.CREATE_DATE AS CreateDate
                        FROM JHAMES.SOLDER_PASTE_INFO I 
                        INNER JOIN JHAMES.SOLDER_PASTE_RECORD R ON I.SOLDER_PASTE_ID = R.SOLDER_PASTE_ID
                        WHERE (I.STATUS = 'O' AND R.STATUS='O' AND R.CREATE_DATE + 7 < SYSDATE) -- 出冰箱後7天 
                        OR ((R.STATUS = 'U' AND I.STATUS ='U' AND R.CREATE_DATE + 1 < SYSDATE)) -- 開封後1天";

            try
            {
                DynamicParameters p = new DynamicParameters();
                var q = _context.Database.DapperQuery<SolderPasteInfo>(sql, p);
                if (q.Any())
                {
                    List<SolderPasteRecord> solderPasteRecords = q.Select(s => new SolderPasteRecord
                    {
                        SolderPasteID = s.SolderPasteID,
                        Status = "X",
                        CreateUserID = userId
                    }).ToList();

                    _context.SolderPasteRecords.AddRange(solderPasteRecords);
                    await _context.SaveChangesAsync();

                    // 更新基本檔的狀態
                    List<SolderPasteInfo> solderPasteInfos = solderPasteRecords.Select(s => new SolderPasteInfo
                    {
                        SolderPasteID = s.SolderPasteID,
                        Status = s.Status,
                        UpdateUserID = s.CreateUserID
                    }).ToList();
                    var query = @" UPDATE JHAMES.SOLDER_PASTE_INFO SET STATUS = :Status ,
                           UPDATE_USERID = :UpdateUserID ,
                           UPDATE_DATE = sysdate
                           WHERE SOLDER_PASTE_ID = :SolderPasteID ";
                    _context.Database.DapperExecute(query, solderPasteInfos);
                    result.Success = true;
                    result.Msg = "OK";

                    #region 發送Mail
                    if (q.Where(w => w.Status == "O").Any())
                    {
                        string MailGroup = "SOLDER_ALARM";
                        string Subject = $"[AMES系統通知] 錫膏需報廢通知";
                        string Body = "";

                        foreach (var item in q.Where(w => w.Status == "O"))
                        {
                            Body += $@"{item.SolderPasteNo}已出冰箱7天沒開封需報廢 + 越南文<br/>";
                        }

                        await new BLL.MailController(_context, _config).PostMail(Subject, Body, MailGroup, "", false);
                    }
                    #endregion
                }
            }
            catch (Exception ex)
            {
                result.Success = false;
                result.Msg = ex.Message;
            }

            return result;
        }

        /// <summary>
        /// 更新錫膏基本資料檔
        /// </summary>
        /// <param name="solderPasteInfo"></param>
        /// <returns></returns>
        [HttpPut]
        public async Task<ResultModel<SolderPasteInfo>> PutSolderPasteInfo(SolderPasteInfo solderPasteInfo)
        {
            ResultModel<SolderPasteInfo> result = new ResultModel<SolderPasteInfo>();
            _context.Entry(solderPasteInfo).State = EntityState.Modified;
            _context.Entry<SolderPasteInfo>(solderPasteInfo).Property("CreateDate").IsModified = false;
            _context.Entry<SolderPasteInfo>(solderPasteInfo).Property("CreateUserID").IsModified = false;
            _context.Entry<SolderPasteInfo>(solderPasteInfo).Property("Status").IsModified = false;
            _context.Entry<SolderPasteInfo>(solderPasteInfo).Property("WipNo").IsModified = false;

            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>
        /// <param name="solderPasteInfo"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ResultModel<SolderPasteInfo>> PostSolderPasteInfo(SolderPasteInfo solderPasteInfo)
        {
            ResultModel<SolderPasteInfo> result = new ResultModel<SolderPasteInfo>();
            Helper helper = new Helper(_context);
            solderPasteInfo.SolderPasteID = helper.GetIDKey("SOLDER_PASTE_ID").Result;
            solderPasteInfo.Description = solderPasteInfo.Description.Trim();
            _context.SolderPasteInfos.Add(solderPasteInfo);
            try
            {
                await _context.SaveChangesAsync();
                result.Success = true;
                result.Msg = "OK";
            }
            catch (Exception ex)
            {
                result.Success = false;
                result.Msg = ex.InnerException.Message;
            }
            return result;
        }

        [HttpDelete("{id}")]
        public async Task<ResultModel<SolderPasteInfo>> DeleteSolderPasteInfo(int id)
        {
            ResultModel<SolderPasteInfo> result = new ResultModel<SolderPasteInfo>();
            var solderPasteInfo = await _context.SolderPasteInfos.FindAsync(id);
            if (solderPasteInfo != null)
            {
                try
                {
                    _context.SolderPasteInfos.Remove(solderPasteInfo);
                    await _context.SaveChangesAsync();
                    result.Success = true;
                    result.Msg = "OK";
                }
                catch (Exception ex)
                {
                    result.Success = false;
                    result.Msg = ex.InnerException.Message;
                }
            }
            return result;
        }

        private bool SolderPasteInfoExists(int id)
        {
            return _context.SolderPasteInfos.Any(e => e.SolderPasteID == id);
        }
    }
}