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

namespace AMESCoreStudio.WebApi.Controllers.BAS
{
    /// <summary>
    /// 流程資料維護
    /// </summary>
    [Route("api/[controller]")]
    [ApiController]
    public class FlowRulesController : ControllerBase
    {
        private readonly AMESContext _context;

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

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        // GET: api/FlowRules
        [HttpGet]
        public async Task<ActionResult<IEnumerable<FlowRule>>> GetFlowRule()
        {
            IQueryable<FlowRule> q = _context.FlowRules;

            q = q.OrderBy(p => p.UnitNo + p.FlowRuleName);

            var flowRule = await q.ToListAsync();

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

            return flowRule;
            //return await _context.FlowRule.ToListAsync();
        }

        /// <summary>
        /// 根据製程單位代碼NO獲取該製程流程資料
        /// </summary>
        /// <param name="no"></param>
        /// <returns></returns>
        // GET: api/FlowRules/Unit/S
        [HttpGet("Unit/{no}")]
        public async Task<ActionResult<IEnumerable<FlowRule>>> GetFlowRuleByUnit(string no, int page = 0, int limit = 10)
        {
            IQueryable<FlowRule> q = _context.FlowRules;

            if (no != null)
            {
                if (no != "*")
                {
                    q = q.Where(p => p.UnitNo.Equals(no));
                }
            }
            if (page > 0)
            {
                q = q.OrderBy(p => p.FlowRuleID).Skip((page - 1) * limit).Take(limit);
            }
            else
            {
                q = q.OrderBy(p => p.FlowRuleID);
            }
            q = q.OrderBy(p => p.FlowRuleName);

            var flowRule = await q.ToListAsync();

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

            return flowRule;
        }

        /// <summary>
        /// 根據流程ID獲取指定單一資料
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        // GET: api/FlowRules/5
        [HttpGet("{id}")]
        public async Task<ActionResult<IEnumerable<FlowRule>>> GetFlowRule(int id)
        {
            IQueryable<FlowRule> q = _context.FlowRules;

            q = q.Where(p => p.FlowRuleID.Equals(id));

            var flowRule = await q.ToListAsync();

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

            return flowRule;
        }

        /// <summary>
        /// 更新流程資料
        /// </summary>
        /// <param name="id"></param>
        /// <param name="flowRule"></param>
        /// <returns></returns>
        // PUT: api/FlowRules/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<FlowRule>> PutFlowRule(int id, [FromBody] FlowRule flowRule)
        {
            ResultModel<FlowRule> result = new ResultModel<FlowRule>();
            _context.Entry(flowRule).State = EntityState.Modified;
            flowRule.UpdateDate = DateTime.Now;

            if (id != flowRule.FlowRuleID)
            {
                result.Success = false;
                result.Msg = "流程編號錯誤";
                return result;
            }
            _context.Entry(flowRule).State = EntityState.Modified;

            try
            {
                /*
                //判斷流程是否使用
                IQueryable<WipInfo> q = _context.WipInfos;

                q = q.Where(p => p.FlowRuleID.Equals(id));
                q = q.OrderByDescending(p => p.CreateDate);

                var wipInfos = await q.ToListAsync();

                if (wipInfos.Count > 0)
                {
                    result.Success = false;
                    result.Msg = "流程已經在工單" + wipInfos[0].WipNO + "使用,不可修改";

                    return result;
                }
                */

                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="flowRule"></param>
        /// <returns></returns>
        // POST: api/FlowRules
        // 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<FlowRule>> PostFlowRule([FromBody] FlowRule flowRule)
        {
            ResultModel<FlowRule> result = new ResultModel<FlowRule>();
            Helper helper = new Helper(_context);
            flowRule.FlowRuleID = helper.GetIDKey("FLOW_RULE_ID").Result;
            flowRule.CreateDate = DateTime.Now;

            _context.FlowRules.Add(flowRule);
            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="id"></param>
        /// <param name="flowRule"></param>
        /// <returns></returns>
        // POST: api/FlowRules
        // 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("{id}")]
        public async Task<ResultModel<FlowRule>> PostFlowRuleCopy(int id,[FromBody] FlowRule flowRule)
        {
            ResultModel<FlowRule> result = new ResultModel<FlowRule>();

            var copyFlowRule = await _context.FlowRules.Where(p => p.FlowRuleID.Equals(id)).FirstOrDefaultAsync();

            IQueryable<RuleStation> q = _context.RuleStations;

            q = q.Where(p => p.FlowRuleID.Equals(id));

            var copyRuleStation = await q.ToListAsync();

            Helper helper = new Helper(_context);
            flowRule.FlowRuleID = helper.GetIDKey("FLOW_RULE_ID").Result;
            flowRule.FlowStatus = copyFlowRule.FlowStatus;
            flowRule.FlowType = copyFlowRule.FlowType;
            flowRule.ProcessTypeNo = copyFlowRule.ProcessTypeNo;
            flowRule.SysType = copyFlowRule.SysType;
            flowRule.UnitNo = copyFlowRule.UnitNo;
            flowRule.CreateDate = DateTime.Now;

            _context.FlowRules.Add(flowRule);
            try
            {
                await _context.SaveChangesAsync();

                for (int i = 0; i < copyRuleStation.Count; i++)
                {
                    int copyStationId = copyRuleStation[i].StationID;
                    int ruleStationId = helper.GetIDKey("RULE_STATION_ID").Result;

                    RuleStation ruleStation = new RuleStation();
                    ruleStation = copyRuleStation[i];
                    ruleStation.RuleStationID = ruleStationId;
                    ruleStation.FlowRuleID = flowRule.FlowRuleID;
                    ruleStation.CreateDate = DateTime.Now;
                    ruleStation.CreateUserId = flowRule.CreateUserId;
                    ruleStation.UpdateDate = DateTime.Now;
                    

                    _context.RuleStations.Add(ruleStation);
                    await _context.SaveChangesAsync();

                    IQueryable<Rules> q1 = _context.Ruleses;

                    q1 = q1.Where(p => p.StationID.Equals(copyStationId) && p.FlowRuleID.Equals(id));

                    var copyRules = await q1.ToListAsync();

                    for (int j = 0; j < copyRules.Count; j++)
                    {
                        Rules rules = new Rules();
                        rules = copyRules[j];
                        rules.RuleID = helper.GetIDKey("RULE_ID").Result;
                        rules.FlowRuleID = flowRule.FlowRuleID;
                        rules.StationID = copyStationId;
                        rules.CreateDate = DateTime.Now;
                        rules.CreateUserId = flowRule.CreateUserId;
                        rules.UpdateDate = DateTime.Now;

                        _context.Ruleses.Add(rules);
                        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="id"></param>
        /// <returns></returns>
        // DELETE: api/FlowRules/5
        [HttpDelete("{id}")]
        public async Task<ResultModel<FlowRule>> DeleteFlowRule(int id)
        {
            ResultModel<FlowRule> result = new ResultModel<FlowRule>();
            var flowRule = await _context.FlowRules.FindAsync(id);
            if (flowRule == null)
            {
                result.Success = false;
                result.Msg = "序號錯誤";
                return result;
            }

            /*
            //判斷流程是否使用
            IQueryable<WipInfo> q = _context.WipInfos;

            q = q.Where(p => p.FlowRuleID.Equals(id));
            q = q.OrderByDescending(p => p.CreateDate);

            var wipInfos = await q.ToListAsync();

            if (wipInfos.Count > 0)
            {
                result.Success = false;
                result.Msg = "流程已經在工單" + wipInfos[0].WipNO + "使用,不可刪除";

                return result;
            }
            */

            _context.FlowRules.Remove(flowRule);

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

            return result;
        }

        private bool FlowRuleExists(int id)
        {
            return _context.FlowRules.Any(e => e.FlowRuleID == id);
        }
    }
}