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 MaterialOrderStatusByStoredService {
        private readonly ILogger<MaterialOrderStatusByStoredService> _logger;
        private readonly FMSContext _context;
        private readonly StorageHelper _storage;

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

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

        public FmsMaterialStored Get(int id, int siteId) {
            var data = _context.FmsMaterialStored.Single(x => x.MaterialStoredId == id && x.SiteId == siteId);
            return data;
        }

        public IQueryable<FmsMaterialPurchaseOrderMaterial> Gets(int orderId, int materialId, int siteId) {
            var data = _context.FmsMaterialPurchaseOrderMaterial.Where(x => x.PurchaseOrderId == orderId && x.SiteId == siteId && x.MaterialId == materialId);
            return data;
        }

        public void Stored(int siteId, int orderId, int materialId, string userId, bool authBusiness) {
            using (var transaction = _context.Database.BeginTransaction()) {
                var orderItem = _context.FmsMaterialPurchaseOrderMaterial.Where(x => x.SiteId == siteId && x.PurchaseOrderId == orderId && x.MaterialId == materialId).ToList();
                var userInfo = _context.CmUser.Where(x => x.UserId == userId).SingleOrDefault();

                foreach (var item in orderItem) {
                    var tmpWarehouse = _context.FmsMaterialWarehouse.Where(f => f.SiteId == item.SiteId && (f.BusinessFieldId == userInfo.BusinessFieldId || f.CmBusinessField.Name == "공통")).FirstOrDefault();
                    if (tmpWarehouse == null) {
                        if (authBusiness) {
                            throw new ServiceException("보관창고를 먼저 등록해 주세요.");
                        } else {
                            tmpWarehouse = _context.FmsMaterialWarehouse.Where(f => f.SiteId == item.SiteId).FirstOrDefault();
                            if (tmpWarehouse == null) {
                                throw new ServiceException("보관창고를 먼저 등록해 주세요.");
                            }
                        }
                    }

                    FmsMaterialStored storedItem = new FmsMaterialStored() {
                        SiteId = item.SiteId,
                        BusinessFieldId = item.FmsMaterialPurchaseOrder.BusinessFieldId,
                        StoredUserId = userId,
                        StoredDate = DateTime.Now,
                        PurchaseOrderId = item.PurchaseOrderId,
                        WarehouseId = tmpWarehouse.WarehouseId,
                        MaterialId = item.MaterialId,
                        StoredCount = item.MaterialCount - item.FmsMaterialPurchaseOrder.FmsMaterialStored.Where(f => f.MaterialId == item.MaterialId).Sum(f => f.StoredCount),
                        RemainStoredCount = item.MaterialCount - item.FmsMaterialPurchaseOrder.FmsMaterialStored.Where(f => f.MaterialId == item.MaterialId).Sum(f => f.StoredCount),      // 입고등록시 RemainStoredCount 에 입고수량 넣어야함 (출고시 RemainStoredCount 이용해서 출고함)
                        UnitCost = item.UnitCost,
                        StockCount = 0,
                        Note = "",
                        IsApproval = false,
                        LocationInWarehouse = "",
                    };

                    //해당 material 의 최신 입고 정보
                    var lastStoredItem = _context.FmsMaterialStored.Where(x => x.SiteId == item.SiteId && x.MaterialId == item.MaterialId).OrderByDescending(x => x.MaterialStoredId).FirstOrDefault();
                    //재고정보 업데이트
                    if (lastStoredItem != null) {
                        storedItem.StockCount += (lastStoredItem.StockCount + storedItem.StoredCount);
                    } else {
                        storedItem.StockCount = storedItem.StoredCount;
                    }

                    //자동승인
                    // if (_context.SiteConfig.Single().UseMaterialStoredAutoApproval) {
                    //     storedItem.ApprovalUserId = userId;
                    //     storedItem.ApprovalDate = DateTime.Now;
                    //     storedItem.IsApproval = true;
                    // }
                    _context.FmsMaterialStored.Add(storedItem);
                }
                _context.SaveChanges();

                // 발주요청과 입고를 비교하여 모두 입고되었다면 상태 변경
                var storedMaterialList = _context.FmsMaterialStored.Where(x => x.SiteId == siteId && x.PurchaseOrderId == orderId).ToList();
                var orderdMaterialList = _context.FmsMaterialPurchaseOrderMaterial.Where(x => x.SiteId == siteId && x.PurchaseOrderId == orderId).ToList();

                bool bAllStored = false;
                foreach (var order in orderdMaterialList) {
                    int storedCount = storedMaterialList.Where(x => x.MaterialId == order.MaterialId).Sum(x => x.StoredCount);

                    if (order.MaterialCount > storedCount) {
                        bAllStored = false;
                        break;
                    } else {
                        bAllStored = true;
                    }
                }
                if (bAllStored) {
                    var requestId = _context.FmsMaterialPurchaseOrder.Where(x => x.SiteId == siteId && x.PurchaseOrderId == orderId).Select(x => x.PurchaseRequestId).FirstOrDefault();
                    var materialRequiest = _context.FmsMaterialPurchaseRequest.Where(x => x.SiteId == siteId && x.PurchaseRequestId == requestId).FirstOrDefault();
                    if (materialRequiest != null) {
                        // if (_context.SiteConfig.Single().UseMaterialStoredAutoApproval) {
                        //     materialRequiest.ProgressId = 5;      //입고승인
                        // } else {
                        materialRequiest.ProgressId = 4;      //자재입고
                        // }
                        _context.FmsMaterialPurchaseRequest.Update(materialRequiest);
                        _context.SaveChanges();
                    }
                }

                transaction.Commit();
            }

        }
    }
}