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;
using System.Transactions;

namespace FMSApp.Services {
    public class FacilityService {
        private readonly ILogger<FacilityService> _logger;
        private readonly FMSContext _context;

        private readonly AppSettings _appSettings;
        private readonly StorageHelper _storage;

        public FacilityService(
            ILogger<FacilityService> logger,
            FMSContext context,
            IOptions<AppSettings> appSettings,
            StorageHelper storage
            ) {
            _logger = logger;
            _context = context;
            _appSettings = appSettings.Value;
            _storage = storage;
        }

        public void Save(CmFacility data) {
            using (var trans = new TransactionScope()) {

                var persist = _context.CmFacility
                                .Where(x => x.SiteId == data.SiteId
                                    && x.FacilityCode == data.FacilityCode).FirstOrDefault();
                if (persist == null) {
                    var check = _context.CmFacility.Where(x => x.SiteId == data.SiteId
                        && x.FacilityCode == data.FacilityCode).Count();
                    if (check > 0) {
                        throw new ServiceException("아이디가 중복됩니다.");
                    }

                    if (data.CmFile != null && data.CmFile.IsUpload) {
                        data.CmFile.SiteId = data.SiteId;
                        var category = _context.CmFileCategory.First(x => x.Name == "facility");
                        data.CmFile.FileCategory = category;
                        data.CmFile.CreatedDate = DateTime.Now;
                    } else {
                        data.CmFile = null;
                    }

                    // 첫번째 유형으로 넣음
                    //data.FacilityTypeId = _context.BemsFacilityType.Where(x => x.FacilityTypeId < 99).OrderBy(x => x.FacilityTypeId).Select(x => x.FacilityTypeId).FirstOrDefault();

                    if (data.FacilityTypeId >= 99) {
                        data.IsVirtualFacility = true;
                    }
                    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);
                    }

                } else {
                    if (data.CmFile != null && data.CmFile.IsDelete) {
                        persist.CmFile = null;
                        persist.FileId = null;
                    } else if (data.CmFile != null && data.CmFile.IsUpload) {
                        var category = _context.CmFileCategory.First(x => x.Name == "facility");
                        persist.CmFile = new CmFile {
                            SiteId = data.SiteId,
                            FileCategory = category,
                            CreatedDate = DateTime.Now,
                            Name = data.CmFile.Name,
                            FileSize = data.CmFile.FileSize,
                            ContentType = data.CmFile.ContentType,
                        };
                    }

                    if (data.FacilityTypeId >= 99) {
                        persist.IsVirtualFacility = true;
                    }

                    persist.FacilityTypeId = data.FacilityTypeId;
                    persist.DeviceType = data.DeviceType;
                    persist.Name = data.Name;
                    persist.Nickname = data.Nickname;
                    persist.FacilityUsage = data.FacilityUsage;
                    persist.IsUse = data.IsUse;
                    persist.FirstClassId = data.FirstClassId;
                    persist.SecondClassId = data.SecondClassId;
                    persist.ThirdClassId = data.ThirdClassId;
                    persist.FacilityCapacity = data.FacilityCapacity;
                    persist.Rfid = data.Rfid.Trim();
                    persist.RatedPowerConsumption = data.RatedPowerConsumption;
                    persist.RatedCop = data.RatedCop;
                    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.MainContactorUserId = data.MainContactorUserId;
                    persist.SubContactorUserId = data.SubContactorUserId;
                    persist.FacilityCost = data.FacilityCost;
                    persist.FacilityCount = data.FacilityCount;
                    persist.FuelTypeId = data.FuelTypeId;
                    persist.ContractType = data.ContractType;
                    persist.Note = data.Note;
                    persist.Multiple = data.Multiple;
                    _context.CmFacility.Update(persist);
                    _context.SaveChanges();

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

                }

                trans.Complete();
            }
        }

        public void Delete(int siteId, int facilityCode) {
            var data = _context.CmFacility.First(x => x.SiteId == siteId && x.FacilityCode == facilityCode);
            _context.CmFacility.Remove(data);
            _context.SaveChanges();
        }

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