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

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

        public void ImportExcel(IList<FmsEquipment> list) {
            using (var transaction = _context.Database.BeginTransaction()) {
                foreach (var data in list) {
                    data.FmsEquipmentHistory.Add(AddHistory(data));
                }
                _context.FmsEquipment.AddRange(list);
                _context.SaveChanges();

                if (!_context.SiteConfig.Single().UseEquipmentRent) {
                    foreach (var data in list) {
                        AddRentInfo(data);
                    }
                }
                transaction.Commit();
            }
        }

        public void Create(FmsEquipment data) {

            using (var transaction = _context.Database.BeginTransaction()) {
                checkName(data);
                if (data.ImageFile != null && data.ImageFile.IsUpload) {
                    data.ImageFile.SiteId = data.SiteId;
                    var category = _context.CmFileCategory.First(x => x.Name == "equipment");
                    data.ImageFile.FileCategory = category;
                    data.ImageFile.CreatedDate = DateTime.Now;
                } else {
                    data.ImageFile = null;
                }
                data.FmsEquipmentHistory.Add(AddHistory(data));
                data.AddDate = DateTime.Now;
                data.UpdateDate = DateTime.Now;

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

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

                // 대여 미사용시 데이터 생성
                if (!_context.SiteConfig.Single().UseEquipmentRent) {
                    AddRentInfo(data);
                }
                transaction.Commit();
            }
        }

        public void Edit(int id, int siteId, FmsEquipment data) {


            using (var transaction = _context.Database.BeginTransaction()) {
                if (data.ImageFile != null && data.ImageFile.IsUpload) {
                    data.ImageFile.SiteId = data.SiteId;
                    var category = _context.CmFileCategory.First(x => x.Name == "equipment");
                    data.ImageFile.FileCategory = category;
                    data.ImageFile.CreatedDate = DateTime.Now;
                }

                var persist = _context.FmsEquipment
                                .Where(x => x.EquipmentId == id && x.SiteId == siteId).FirstOrDefault();
                if (persist == null) {
                    throw new ServiceException("정보를 찾을 수 없습니다.");
                }
                if (!persist.EquipmentTypeId.Equals(data.EquipmentTypeId)) {
                    checkName(data);
                }
                if (!persist.Name.Equals(data.Name)) {
                    checkName(data);
                }
                if (!Util.IsNullOrEmpty(data.Standard)) {
                    if (!persist.Standard.Equals(data.Standard))
                        checkName(data);
                }
                persist.SiteId = data.SiteId;
                persist.Name = data.Name;
                persist.EquipmentTypeId = data.EquipmentTypeId;
                persist.Standard = data.Standard;
                persist.Unit = data.Unit;
                persist.WarehouseId = data.WarehouseId;
                persist.SupplierName = data.SupplierName;
                persist.SupplierPhoneNo = data.SupplierPhoneNo;
                persist.UpdateDate = DateTime.Now;
                if (data.ImageFile != null && data.ImageFile.IsUpload) {
                    persist.ImageFile = data.ImageFile;
                }
                _context.FmsEquipment.Update(persist);
                _context.SaveChanges();

                if (data.ImageFile != null && data.ImageFile.IsUpload) {
                    // 카피
                    _storage.CopyEntity(data.ImageFile.Path, persist.ImageFile);
                    if (persist.ImageFile != null) {
                        // 파일 삭제시 진짜 DB삭제?
                    }
                }
                transaction.Commit();
            }
        }
        public int checkName(FmsEquipment data, bool isExcel = false) {
            var check = _context.FmsEquipment.Where(x => x.SiteId == data.SiteId && x.EquipmentTypeId == data.EquipmentTypeId && x.Name == data.Name && x.Standard == data.Standard).Count();
            if (!isExcel && check > 0) {
                throw new ServiceException("동일 정보가 존재합니다. [공기구분류-공기구명-규격]");
            }
            return check;
        }

        public FmsEquipmentHistory AddHistory(FmsEquipment data) {
            var history = new FmsEquipmentHistory {
                EquipmentStateTypeId = 1,
                StoredCount = data.StoredCount,
                TotalStockCount = data.StoredCount,
                CurrentStockCount = data.StoredCount,
                ReturnCount = 0,
                AddDate = DateTime.Now,
                UpdateDate = DateTime.Now,
                IsReturnApproval = false
            };
            return history;
        }

        public void AddRentInfo(FmsEquipment data) {
            var rentInfo = new FmsEquipmentRentInfo {
                SiteId = data.SiteId,
                RegisterUserId = data.RegisterUserId,
                RentUserId = data.RegisterUserId,
                RentDate = DateTime.Now,
                EquipmentStateTypeId = 2,
                Comment = "입고",
                Title = "입고",
            };
            var rentHistory = new FmsEquipmentHistory {
                EquipmentId = data.EquipmentId,
                SiteId = data.SiteId,
                TotalStockCount = data.StoredCount,
                CurrentStockCount = 0,
                RentCount = data.StoredCount,
                CurrentRentCount = data.StoredCount,
                ReturnCount = 0,
                LossCount = 0,
                StoredCount = 0,
                EquipmentStateTypeId = 2,
                IsReturned = false,
                AddDate = DateTime.Now,
                UpdateDate = DateTime.Now,
                IsReturnApproval = false
            };
            rentInfo.FmsEquipmentHistory.Add(rentHistory);
            _context.FmsEquipmentRentInfo.Add(rentInfo);
            _context.SaveChanges();
        }

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

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

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

        public void Delete(int id, int siteId) {
            using (var transaction = _context.Database.BeginTransaction()) {

                var history = _context.FmsEquipmentHistory.Where(x => x.EquipmentId == id && x.SiteId == siteId);
                _context.FmsEquipmentHistory.RemoveRange(history);
                _context.SaveChanges();

                var data = _context.FmsEquipment.First(x => x.EquipmentId == id && x.SiteId == siteId);
                _context.FmsEquipment.Remove(data);
                _context.SaveChanges();
                transaction.Commit();
            }
        }

        public IQueryable<FmsEquipmentHistory> GetHistory() {
            var query = _context.FmsEquipmentHistory;
            return query;
        }
    }
}