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

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

        public void Create(FmsMaterialPurchaseOrder data) {
            using (var transaction = _context.Database.BeginTransaction()) {
                var persist = _context.FmsMaterialPurchaseRequest
                            .Where(x => x.PurchaseRequestId == data.PurchaseRequestId && x.SiteId == data.SiteId).FirstOrDefault();
                data.FmsMaterialPurchaseRequest = persist;
                data.FmsMaterialPurchaseRequest.ProgressId = 3;       //발주요청    

                _context.FmsMaterialPurchaseOrder.Add(data);
                _context.SaveChanges();

                //자재 정보 최종가격 업데이트
                MaterialPriceUpdate(data.SiteId, data.PurchaseOrderId);

                //구매신청, 발주신청 자재 비교
                MaterialCompare(data.SiteId, data.PurchaseOrderId, data.PurchaseRequestId);

                transaction.Commit();
            }
        }

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

            using (var transaction = _context.Database.BeginTransaction()) {
                persist.SiteId = data.SiteId;
                persist.BusinessFieldId = data.BusinessFieldId;
                persist.PurchaseOrderId = id;
                persist.PurchaseRequestId = data.PurchaseRequestId;
                persist.TradeCompanyId = data.TradeCompanyId;
                persist.OrderDate = data.OrderDate;
                persist.OrderUserId = data.OrderUserId;
                persist.Title = data.Title;
                persist.Reason = (data.Reason != null) ? data.Reason : "";
                persist.StoredDueDate = data.StoredDueDate;
                persist.FmsMaterialPurchaseRequest.ProgressId = 3;       //발주요청

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

                //자재 정보 최종가격 업데이트
                MaterialPriceUpdate(persist.SiteId, persist.PurchaseOrderId);

                //구매신청, 발주신청 자재 비교
                MaterialCompare(data.SiteId, data.PurchaseOrderId, data.PurchaseRequestId);

                transaction.Commit();
            }
        }

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

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

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

        public void Delete(int id, int siteId) {
            var data = _context.FmsMaterialPurchaseOrder.First(x => x.PurchaseOrderId == id && x.SiteId == siteId);
            _context.FmsMaterialPurchaseOrder.Remove(data);
            _context.SaveChanges();
        }

        public void MaterialCompare(int siteId, int purchaseOrderId, int purchaseRequestId) {
            //구매신청, 발주신청 자재 비교
            var query = _context.FmsMaterialPurchaseRequestMaterial.Where(x => x.SiteId == siteId && x.PurchaseRequestId == purchaseRequestId).ToList();
            var query2 = _context.FmsMaterialPurchaseOrderMaterial.Where(x => x.SiteId == siteId && x.PurchaseOrderId == purchaseOrderId).ToList();

            bool bSame = false;
            if (query.Count() == query2.Count()) {
                foreach (var r in query) {
                    var fM = query2.SingleOrDefault(x => x.MaterialId == r.MaterialId && x.MaterialCount == r.MaterialCount);
                    if (fM == null) {
                        bSame = false;
                        break;
                    } else {
                        bSame = true;
                    }
                }
            } else {
                bSame = false;
            }

            var persist = _context.FmsMaterialPurchaseRequest.Where(x => x.SiteId == siteId && x.PurchaseRequestId == purchaseRequestId).FirstOrDefault();
            if (persist != null) {
                persist.BSameOrder = bSame;
                _context.FmsMaterialPurchaseRequest.Update(persist);
                _context.SaveChanges();
            }
        }

        public void MaterialPriceUpdate(int siteId, int orderId) {
            var data_b = _context.FmsMaterialPurchaseOrderMaterial.Where(x => x.SiteId == siteId && x.PurchaseOrderId == orderId).ToList();
            var d_material = _context.FmsMaterial.Where(x => x.SiteId == siteId);
            foreach (FmsMaterialPurchaseOrderMaterial m in data_b) {
                m.FmsMaterial = d_material.Where(f => f.MaterialId == m.MaterialId).FirstOrDefault();
                m.FmsMaterial.FinalPrice = (m.FmsMaterial.FinalPrice != m.UnitCost) ? m.UnitCost : m.FmsMaterial.FinalPrice;
                _context.FmsMaterialPurchaseOrderMaterial.Update(m);
            }
            _context.SaveChanges();
        }
    }
}