using System;
using System.Collections.Generic;
using System.Linq;

using FMSAdmin.Data;
using FMSAdmin.Helpers;
using FMSAdmin.Entities;
using Microsoft.Extensions.Logging;
using FMSAdmin.Models;

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

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

        public void Create(FmsEquipmentRentInfo data) {
            using (var transaction = _context.Database.BeginTransaction()) {

                data.EquipmentStateTypeId = 2;
                data.RentDate = DateTime.Now;
                foreach (var history in data.FmsEquipmentHistory) {
                    FmsEquipmentHistory last = _context.FmsEquipmentHistory.Where(x => x.EquipmentId == history.EquipmentId).OrderByDescending(x => x.EquipmentHistoryId).First();

                    history.CurrentRentCount = history.RentCount;
                    history.ReturnCount = 0;
                    history.LossCount = 0;
                    history.StoredCount = 0;
                    history.EquipmentStateTypeId = 2;
                    history.IsReturned = false;
                    history.SiteId = data.SiteId;
                    history.TotalStockCount = last.TotalStockCount;
                    history.CurrentStockCount = last.CurrentStockCount - history.RentCount;
                    history.AddDate = DateTime.Now;
                    history.UpdateDate = DateTime.Now;
                    history.IsReturnApproval = false;
                }
                _context.FmsEquipmentRentInfo.Add(data);
                _context.SaveChanges();
                transaction.Commit();
            }
        }


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

            persist.SiteId = data.SiteId;
            persist.Title = data.Title;
            _context.FmsEquipmentRentInfo.Update(persist);
            _context.SaveChanges();

        }

        public void CreateReturnInfo(int historyId, int siteId, FmsEquipmentRentInfo data) {
            using (var transaction = _context.Database.BeginTransaction()) {
                var rentHistory = _context.FmsEquipmentHistory.Where(x => x.SiteId == siteId && x.EquipmentHistoryId == historyId).SingleOrDefault();

                var persist = _context.FmsEquipmentRentInfo
                                .Where(x => x.EquipmentRentId == rentHistory.EquipmentRentId && x.SiteId == siteId).FirstOrDefault();
                if (persist == null) {
                    throw new ServiceException("정보를 찾을 수 없습니다.");
                }

                data.EquipmentStateTypeId = 3;
                if (data.ReturnCount > 0 && data.LossCount > 0) {
                    data.EquipmentStateTypeId = 4;
                } else if (data.LossCount > 0) {
                    data.EquipmentStateTypeId = 5;
                }
                FmsEquipmentHistory last = persist.FmsEquipmentHistory.Where(x => x.EquipmentId == rentHistory.EquipmentId).OrderByDescending(x => x.EquipmentHistoryId).FirstOrDefault();

                var totReturnCnt = data.ReturnCount.GetValueOrDefault() + data.LossCount.GetValueOrDefault();

                var history = new FmsEquipmentHistory {
                    SiteId = data.SiteId,
                    EquipmentRentId = data.EquipmentRentId,
                    EquipmentId = last.EquipmentId,
                    TotalStockCount = last.FmsEquipment.FmsEquipmentHistory.OrderByDescending(x => x.EquipmentHistoryId).FirstOrDefault().TotalStockCount - data.LossCount.GetValueOrDefault(),
                    CurrentStockCount = last.CurrentStockCount + data.ReturnCount.GetValueOrDefault(),
                    RentCount = last.RentCount,
                    CurrentRentCount = last.CurrentRentCount - totReturnCnt,
                    ReturnCount = data.ReturnCount.GetValueOrDefault(),
                    LossCount = data.LossCount.GetValueOrDefault(),
                    StoredCount = 0,
                    EquipmentStateTypeId = data.EquipmentStateTypeId,
                    AddDate = DateTime.Now,
                    UpdateDate = DateTime.Now,
                    IsReturned = last.CurrentRentCount == totReturnCnt ? true : false,
                    ReturnReason = data.ReturnReason,
                    IsReturnApproval = false
                };

                if (data.CmFile != null && data.CmFile.IsUpload) {
                    var category = _context.CmFileCategory.First(x => x.Name == "equipmentReturn");

                    history.CmFile = data.CmFile;
                    history.CmFile.SiteId = data.SiteId;
                    history.CmFile.FileCategory = category;
                    history.CmFile.CreatedDate = DateTime.Now;
                } else {
                    data.CmFile = null;
                }

                last.IsReturned = true;
                persist.FmsEquipmentHistory.Add(last);
                persist.FmsEquipmentHistory.Add(history);
                if (last.CurrentRentCount == totReturnCnt) {
                    persist.ReturnFixDate = DateTime.Now;
                    persist.EquipmentStateTypeId = data.EquipmentStateTypeId;
                }
                _context.FmsEquipmentRentInfo.Update(persist);
                _context.SaveChanges();

                if (data.CmFile != null && data.CmFile.IsUpload) {
                    // 카피
                    _storage.CopyEntity(data.CmFile.Path, data.CmFile);
                }

                transaction.Commit();
            }
        }

        public IQueryable<FmsEquipmentRentInfo> GetAll() {
            var query = from p in _context.FmsEquipmentRentInfo
                        select p;
            return query;
        }

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

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

        public void Delete(int siteId, int id) {
            var data = _context.FmsEquipmentRentInfo.First(x => x.EquipmentRentId == id && x.SiteId == siteId);
            if (data.FmsEquipmentHistory.Where(x => x.IsReturnApproval == true).Count() > 0)
                throw new ServiceException("승인 이력이 있어 삭제할 수 없습니다.");
            _context.FmsEquipmentRentInfo.Remove(data);
            _context.SaveChanges();
        }



    }
}