using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Text;

using FMSAdmin.Data;
using FMSAdmin.Helpers;
using FMSAdmin.Entities;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using FMSAdmin.Models;

namespace FMSAdmin.Services {
    public class MaterialPurchaseRequestService {
        private readonly ILogger<MaterialPurchaseRequestService> _logger;
        private readonly FMSContext _context;
        private readonly StorageHelper _storage;

        public MaterialPurchaseRequestService(
            ILogger<MaterialPurchaseRequestService> logger,
            FMSContext context,
            StorageHelper storage) {
            _logger = logger;
            _context = context;
            _storage = storage;
        }

        public void Create(FmsMaterialPurchaseRequest data) {
            using (var transaction = _context.Database.BeginTransaction()) {
                if (_context.SiteConfig.Single().UseMaterialBuyAutoApproval) {
                    data.ProgressId = 2;     //신청승인
                    data.ApprovalDate = DateTime.Now;
                } else {
                    data.ProgressId = 1;     //구매신청
                    data.ApprovalDate = null;
                    data.ApprovalUserId = null;
                }
                data.BSameOrder = false;
                _context.FmsMaterialPurchaseRequest.Add(data);
                _context.SaveChanges();

                if (_context.SiteConfig.Single().UseMaterialPurchaseOrder && data.ProgressId == 2) {
                    //발주등록 모듈화
                    FmsMaterialPurchaseOrder pOrder = new FmsMaterialPurchaseOrder {
                        SiteId = data.SiteId,
                        BusinessFieldId = data.BusinessFieldId,
                        OrderDate = data.RequestDate,
                        OrderUserId = data.RequestUserId,
                        Title = data.Title + " 발주",
                        FmsMaterialPurchaseRequest = data
                    };
                    pOrder.FmsMaterialPurchaseRequest.ProgressId = 3;     //발주요청
                    pOrder.FmsMaterialPurchaseRequest.BSameOrder = true;    //구매신청 발주요청 자재비교

                    //자재등록
                    pOrder.FmsMaterialPurchaseOrderMaterial.Clear();
                    foreach (var item in data.FmsMaterialPurchaseRequestMaterial) {
                        var dMateril = _context.FmsMaterial.Where(x => x.SiteId == item.SiteId && x.MaterialId == item.MaterialId).FirstOrDefault();
                        pOrder.FmsMaterialPurchaseOrderMaterial.Add(new FmsMaterialPurchaseOrderMaterial() {
                            SiteId = item.SiteId,
                            BusinessFieldId = item.BusinessFieldId,
                            PurchaseOrderId = pOrder.PurchaseOrderId,
                            MaterialId = item.MaterialId,
                            MaterialCount = item.MaterialCount,
                            UnitCost = Util.ToInt(dMateril.FinalPrice)
                        });
                    }
                    _context.FmsMaterialPurchaseOrder.Add(pOrder);
                    _context.SaveChanges();
                }

                transaction.Commit();
            }
        }

        public void Edit(int id, int siteId, int businessFieldId, FmsMaterialPurchaseRequest data) {
            var persist = _context.FmsMaterialPurchaseRequest
                            .Where(x => x.PurchaseRequestId == id && x.SiteId == siteId && x.BusinessFieldId == businessFieldId).FirstOrDefault();
            if (persist == null) {
                throw new ServiceException("정보를 찾을 수 없습니다.");
            }

            using (var transaction = _context.Database.BeginTransaction()) {
                persist.SiteId = data.SiteId;
                persist.BusinessFieldId = data.BusinessFieldId;
                persist.PurchaseRequestId = data.PurchaseRequestId;
                persist.PurchaseTypeId = data.PurchaseTypeId;
                persist.RequestDate = data.RequestDate;
                persist.RequestUserId = data.RequestUserId;
                persist.PurchaseHopeDate = data.PurchaseHopeDate;
                persist.Title = data.Title;
                persist.Reason = (data.Reason != null) ? data.Reason : "";
                if (_context.SiteConfig.Single().UseMaterialBuyAutoApproval) {
                    persist.ProgressId = 2;     //신청승인
                    persist.ApprovalDate = DateTime.Now;
                    persist.ApprovalUserId = data.ApprovalUserId;
                } else {
                    persist.ProgressId = 1;     //구매신청
                    persist.ApprovalDate = null;
                    persist.ApprovalUserId = null;
                }
                persist.BSameOrder = data.BSameOrder;

                //자재등록
                persist.FmsMaterialPurchaseRequestMaterial.Clear();
                foreach (var item in data.FmsMaterialPurchaseRequestMaterial) {
                    persist.FmsMaterialPurchaseRequestMaterial.Add(new FmsMaterialPurchaseRequestMaterial() {
                        SiteId = persist.SiteId,
                        BusinessFieldId = persist.BusinessFieldId,
                        PurchaseRequestId = persist.PurchaseRequestId,
                        MaterialId = item.MaterialId,
                        MaterialCount = item.MaterialCount,
                    });
                }
                _context.FmsMaterialPurchaseRequest.Update(persist);
                _context.SaveChanges();

                if (_context.SiteConfig.Single().UseMaterialPurchaseOrder && persist.ProgressId == 2) {
                    //발주등록 모듈화
                    var persist2 = _context.FmsMaterialPurchaseOrder.Where(x => x.PurchaseRequestId == id && x.SiteId == siteId).FirstOrDefault();
                    if (persist2 == null) {
                        throw new ServiceException("정보를 찾을 수 없습니다.");
                    }

                    persist2.SiteId = data.SiteId;
                    persist2.BusinessFieldId = data.BusinessFieldId;
                    persist2.OrderDate = data.RequestDate;
                    persist2.OrderUserId = data.RequestUserId;
                    persist2.Title = data.Title + " 발주";
                    persist2.FmsMaterialPurchaseRequest = data;
                    persist2.FmsMaterialPurchaseRequest.ProgressId = 3;     //발주요청
                    persist2.FmsMaterialPurchaseRequest.BSameOrder = true;  //구매신청 발주요청 자재비교

                    //자재등록
                    persist2.FmsMaterialPurchaseOrderMaterial.Clear();
                    foreach (var item in data.FmsMaterialPurchaseRequestMaterial) {
                        var dMateril = _context.FmsMaterial.Where(x => x.SiteId == item.SiteId && x.MaterialId == item.MaterialId).FirstOrDefault();
                        persist2.FmsMaterialPurchaseOrderMaterial.Add(new FmsMaterialPurchaseOrderMaterial() {
                            SiteId = item.SiteId,
                            BusinessFieldId = item.BusinessFieldId,
                            PurchaseOrderId = persist2.PurchaseOrderId,
                            MaterialId = item.MaterialId,
                            MaterialCount = item.MaterialCount,
                            UnitCost = Util.ToInt(dMateril.FinalPrice)
                        });
                    }
                    _context.FmsMaterialPurchaseOrder.Update(persist2);
                    _context.SaveChanges();
                }

                transaction.Commit();
            }
        }

        public IQueryable<FmsMaterialPurchaseRequest> GetAll() {
            var query = _context.FmsMaterialPurchaseRequest/*.AsNoTracking()*/;
            return query;
        }

        public FmsMaterialPurchaseRequest Get(int id, int siteId, int businessFieldId) {
            var data = _context.FmsMaterialPurchaseRequest.Single(x => x.PurchaseRequestId == id && x.SiteId == siteId && x.BusinessFieldId == businessFieldId);
            return data;
        }

        public IQueryable<FmsMaterialPurchaseRequest> Gets(int id, int siteId, int businessFieldId) {
            var data = _context.FmsMaterialPurchaseRequest.Where(x => x.PurchaseRequestId == id && x.SiteId == siteId && x.BusinessFieldId == businessFieldId);
            return data;
        }

        public void Delete(int id, int siteId) {
            var data = _context.FmsMaterialPurchaseRequest.First(x => x.PurchaseRequestId == id && x.SiteId == siteId);
            var pOrder = _context.FmsMaterialPurchaseOrder.Where(x => x.PurchaseRequestId == id && x.SiteId == siteId).ToList();

            using (var transaction = _context.Database.BeginTransaction()) {
                if (_context.SiteConfig.Single().UseMaterialPurchaseOrder) {
                    //발주등록 모듈화
                    foreach (var item in pOrder) {
                        var pStored = _context.FmsMaterialStored.Where(x => x.PurchaseOrderId == item.PurchaseOrderId && x.SiteId == siteId).FirstOrDefault();
                        if (pStored != null) {
                            throw new ServiceException("입고등록된 내역이 있으므로 삭제할 수 없습니다.");
                        }
                    }
                    _context.FmsMaterialPurchaseOrder.RemoveRange(pOrder);
                    _context.SaveChanges();
                } else if (_context.SiteConfig.Single().UseMaterialBuyAutoApproval) {
                    //구매신청승인 모듈화
                    if (pOrder != null) {
                        throw new ServiceException("발주등록된 내역이 있으므로 삭제할 수 없습니다.");
                    }
                } else {
                    if (data.ProgressId > 1) {
                        throw new ServiceException("신청승인된 내역이 있으므로 삭제할 수 없습니다.");
                    }
                }

                _context.FmsMaterialPurchaseRequest.Remove(data);
                _context.SaveChanges();

                transaction.Commit();
            }
        }

        public void Approval(string userId, ICollection<FmsMaterialPurchaseRequest> data) {
            using (var transaction = _context.Database.BeginTransaction()) {
                foreach (var item in data) {
                    if (item.ApprovalDate != null) continue;

                    var persist = _context.FmsMaterialPurchaseRequest
                                .Where(x => x.PurchaseRequestId == item.PurchaseRequestId && x.SiteId == item.SiteId).FirstOrDefault();
                    if (persist == null) {
                        throw new ServiceException("정보를 찾을 수 없습니다.");
                    }
                    if (persist.ProgressId == 2) {
                        throw new ServiceException("승인 할 구매신청 항목이 없습니다. 이미 승인되었거나 선택된 항목이 없습니다.");
                    }

                    persist.ProgressId = 2;     //신청승인
                    persist.ApprovalDate = DateTime.Now;
                    persist.ApprovalUserId = userId;
                    _context.FmsMaterialPurchaseRequest.Update(persist);
                }
                _context.SaveChanges();

                transaction.Commit();
            }
        }

        public void ApprovalEach(int siteId, int id, string userId) {
            var persist = _context.FmsMaterialPurchaseRequest
                        .Where(x => x.PurchaseRequestId == id && x.SiteId == siteId).FirstOrDefault();
            if (persist == null) {
                throw new ServiceException("정보를 찾을 수 없습니다.");
            }

            using (var transaction = _context.Database.BeginTransaction()) {
                persist.ProgressId = 2;     //신청승인
                persist.ApprovalDate = DateTime.Now;
                persist.ApprovalUserId = userId;

                _context.FmsMaterialPurchaseRequest.Update(persist);
                _context.SaveChanges();

                transaction.Commit();
            }
        }
    }
}