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 System.Transactions;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using FMSAdmin.Models;

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

        public FacilityService(
            ILogger<FacilityService> logger,
            FMSContext context,
            StorageHelper storage,
            QrCodeHelper qrCodeHelper) {
            _logger = logger;
            _context = context;
            _storage = storage;
            _qrCodeHelper = qrCodeHelper;
        }


        public int checkName(CmFacility data, bool isExcel = false) {
            var check = _context.CmFacility.Where(x => x.Name == data.Name && x.Nickname == data.Nickname && x.SiteId == data.SiteId).Count();
            if (!isExcel && check > 0) {
                throw new ServiceException("동일 정보가 존재합니다.");
            }
            return check;
        }

        public int checkRfid(CmFacility data, bool isExcel = false) {
            var check = _context.CmFacility.Where(x => x.Rfid == data.Rfid && x.SiteId == data.SiteId).Count();
            if (!isExcel && check > 0) {
                throw new ServiceException("QR코드값이 중복되었습니다.");
            }
            return check;
        }


        public void ImportExcel(IList<CmFacility> list) {
            using (var transaction = _context.Database.BeginTransaction()) {
                _context.CmFacility.AddRange(list);
                _context.SaveChanges();

                transaction.Commit();
            }
        }

        public void Save(CmFacility data) {


            using (var trans = new TransactionScope()) {

                var persist = _context.CmFacility
                                .Where(x => x.FacilityCode == data.FacilityCode).FirstOrDefault();

                //var facilityTypeId = data.FacilityTypeId == 99 ? 99 : _context.BemsFacilityType.Where(x => x.FacilityTypeId < 99).OrderBy(x => x.FacilityTypeId).Select(x => x.FacilityTypeId).FirstOrDefault();

                if (persist == null) {

                    checkName(data);
                    if (!Util.IsNullOrEmpty(data.Rfid)) checkRfid(data);

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

                        data.CmFile.SiteId = data.SiteId;
                        data.CmFile.FileCategory = category;
                        data.CmFile.CreatedDate = DateTime.Now;

                    } else {
                        data.CmFile = null;
                    }

                    // /data.FacilityTypeId = Util.ToInt(facilityTypeId);
                    if (data.FacilityTypeId > 99) {
                        data.IsVirtualFacility = true;
                    }
                    data.Multiple = 1;
                    data.Rfid = data.Rfid.Trim();
                    _context.CmFacility.Add(data);
                    _context.SaveChanges();

                    if (data.CmFile != null && data.CmFile.IsUpload) {
                        // 카피
                        _storage.CopyEntity(data.CmFile.Path, data.CmFile);
                    }
                    if (!string.IsNullOrEmpty(data.Rfid)) {
                        _qrCodeHelper.Save(data.Rfid, $"{data.SiteId}_{data.FacilityCode}", "Facility");
                    }
                } else {
                    if (!persist.Name.Equals(data.Name) && !persist.Name.Equals(data.Nickname)) checkName(data);
                    if (!Util.IsNullOrEmpty(data.Rfid)) {
                        if (Util.IsNullOrEmpty(persist.Rfid) || !persist.Rfid.Equals(data.Rfid)) checkRfid(data);
                    }

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

                        data.CmFile.SiteId = data.SiteId;
                        data.CmFile.FileCategory = category;
                        data.CmFile.CreatedDate = DateTime.Now;
                        data.CmFile.Name = data.CmFile.Name;

                        // persist.CmFile = new CmFile {
                        //     SiteId = data.SiteId,
                        //     FileCategory = category,
                        //     CreatedDate = DateTime.Now,
                        //     Name = data.CmFile.Name,
                        //     FileSize = data.CmFile.FileSize,
                        //     ContentType = data.CmFile.ContentType,
                        // };

                    } else if (data.CmFile != null && data.CmFile.IsDelete) {
                        persist.FileId = null;
                        persist.CmFile = null;
                    }

                    // QR코드 재생성
                    var qrRefresh = !string.IsNullOrEmpty(data.Rfid) && persist.Rfid != data.Rfid;

                    persist.SiteId = data.SiteId;
                    persist.FacilityTypeId = data.FacilityTypeId;
                    //persist.FacilityCode = data.FacilityCode;
                    persist.FirstClassId = data.FirstClassId;
                    persist.SecondClassId = data.SecondClassId;
                    persist.ThirdClassId = data.ThirdClassId;
                    persist.DeviceType = data.DeviceType;
                    persist.ParentFacilityCode = data.ParentFacilityCode;
                    persist.Name = data.Name;
                    persist.Nickname = data.Nickname;
                    persist.Rfid = data.Rfid.Trim();
                    persist.Manufacturer = data.Manufacturer;
                    persist.ManufactureDate = data.ManufactureDate;
                    persist.ManufactureSerial = data.ManufactureSerial;
                    persist.ManufactureModel = data.ManufactureModel;
                    persist.Supplier = data.Supplier;
                    persist.SupplierPhoneNo = data.SupplierPhoneNo;
                    persist.BuildingId = data.BuildingId;
                    persist.FloorId = data.FloorId;
                    persist.ZoneId = data.ZoneId;
                    persist.InstallDate = data.InstallDate;
                    persist.OperationStartDate = data.OperationStartDate;
                    persist.FacilityCapacity = data.FacilityCapacity;
                    persist.FacilityCost = data.FacilityCost;
                    persist.FacilityCount = data.FacilityCount;
                    persist.FacilitySeviceLifeYear = data.FacilitySeviceLifeYear;
                    persist.FacilityUsage = data.FacilityUsage;
                    persist.RatedPowerConsumption = data.RatedPowerConsumption;
                    persist.RatedCop = data.RatedCop;
                    persist.MainContactorUserId = data.MainContactorUserId;
                    persist.SubContactorUserId = data.SubContactorUserId;
                    persist.Note = data.Note;
                    persist.Reserved1 = data.Reserved1;
                    persist.Reserved2 = data.Reserved2;
                    persist.IsUse = data.IsUse;
                    persist.Multiple = data.Multiple;
                    //persist.FileId = data.FileId;
                    if (data.CmFile != null && data.CmFile.IsUpload) {
                        persist.CmFile = data.CmFile;
                    }
                    if (data.FacilityTypeId > 99) {
                        persist.IsVirtualFacility = true;
                    } else {
                        persist.IsVirtualFacility = false;
                    }
                    //persist.IsVirtualFacility = data.IsVirtualFacility;
                    persist.FuelTypeId = data.FuelTypeId;
                    persist.ContractType = data.ContractType;

                    _context.SaveChanges();

                    if (data.CmFile != null && data.CmFile.IsUpload) {
                        // 카피
                        _storage.CopyEntity(data.CmFile.Path, persist.CmFile);
                        if (persist.CmFile != null) {
                            // 파일 삭제시 진짜 DB삭제?
                        }
                    }

                    if (qrRefresh) {
                        _qrCodeHelper.Save(data.Rfid, $"{data.SiteId}_{data.FacilityCode}", "Facility");
                    }
                }
                trans.Complete();
            }
        }

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

        public IQueryable<CmFacility> Get(int id, int siteId) {
            var data = _context.CmFacility.Where(x => x.FacilityCode == id && x.SiteId == siteId);
            return data;
        }

        public void Delete(int id, int siteId) {
            using (var trans = new TransactionScope()) {
                var data = _context.CmFacility.First(x => x.FacilityCode == id && x.SiteId == siteId);
                _context.CmFacility.Remove(data);
                //data.IsUse = false;
                _context.SaveChanges();
                trans.Complete();
            }
        }
    }
}