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

        public SitePriceService(
            ILogger<SitePriceService> logger,
            FMSContext context) {
            _logger = logger;
            _context = context;
        }

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

        public IQueryable<BemsSitePrice> Gets(int id, int siteId) {
            var data = _context.BemsSitePrice.Where(x => x.SiteId == siteId && x.FuelTypeId == id && x.PriceTypeId == id && x.PriceCode == id.ToString());
            return data;
        }

        public void Save(int siteId, int fuelTypeId, int priceTypeId, BemsSitePrice[] data) {
            var oldPriceTypeId = data[0].PriceTypeId;
            var persist = _context.BemsSitePrice.Where(x => x.SiteId == siteId && x.FuelTypeId == fuelTypeId && x.PriceTypeId == priceTypeId).ToList();
            if (persist.Count > 0) {
                if (priceTypeId != oldPriceTypeId) {
                    throw new ServiceException("존재하고 있는 요금제입니다.");
                }
            }

            using (var transaction = _context.Database.BeginTransaction()) {
                var oldPersist = _context.BemsSitePrice.Where(x => x.SiteId == siteId && x.FuelTypeId == fuelTypeId && x.PriceTypeId == oldPriceTypeId).ToList();
                _context.BemsSitePrice.RemoveRange(oldPersist);
                _context.SaveChanges();

                foreach (var item in data) {
                    item.PriceTypeId = priceTypeId;
                    _context.BemsSitePrice.Add(item);
                }
                _context.SaveChanges();

                //BemsPriceFormula Update
                //전기:100, 가스:101, 수도:102, 등유:104, LPG:105, 증온수:106
                int facilityTypeId = fuelTypeId == 1 ? 100 : fuelTypeId == 2 ? 101 : fuelTypeId == 3 ? 102 : fuelTypeId == 4 ? 104 : fuelTypeId == 5 ? 105 : 106;
                int? facilityCode = _context.CmFacility.Where(x => x.SiteId == siteId && x.FacilityTypeId == facilityTypeId).Select(x => x.FacilityCode).FirstOrDefault();
                int formulaId = 1;      //formulaId 전체로 매칭
                var formulaList = _context.BemsFormula.Where(x => x.SiteId == siteId && x.FacilityTypeId == facilityTypeId && x.FacilityCode == facilityCode && x.FormulaId == formulaId).ToList();
                if (formulaList.Count == 0) {
                    throw new Exception("수식을 먼저 설정하세요.");
                }

                if (oldPriceTypeId != 0) {
                    var persist2 = _context.BemsPriceFormula.Where(x => x.SiteId == siteId && x.PriceTypeId == oldPriceTypeId).ToList();
                    _context.BemsPriceFormula.RemoveRange(persist2);
                    _context.SaveChanges();

                    BemsPriceFormula oldPriceFormula = new BemsPriceFormula {
                        SiteId = siteId,
                        PriceTypeId = oldPriceTypeId,
                        FacilityTypeId = facilityTypeId,
                        FormulaId = (int)formulaId,
                        FacilityCode = (int)facilityCode,
                        UseYN = "N"
                    };
                    _context.BemsPriceFormula.Add(oldPriceFormula);
                    _context.SaveChanges();
                }
                if (facilityCode != null) {
                    var persist3 = _context.BemsPriceFormula.Where(x => x.SiteId == siteId && x.PriceTypeId == priceTypeId).ToList();
                    _context.BemsPriceFormula.RemoveRange(persist3);
                    _context.SaveChanges();

                    BemsPriceFormula newPriceFormula = new BemsPriceFormula {
                        SiteId = siteId,
                        PriceTypeId = priceTypeId,
                        FacilityTypeId = facilityTypeId,
                        FormulaId = (int)formulaId,
                        FacilityCode = (int)facilityCode,
                        UseYN = "Y"
                    };
                    _context.BemsPriceFormula.Add(newPriceFormula);
                    _context.SaveChanges();
                }

                transaction.Commit();
            }
        }

        public void Delete(int siteId, int fuelTypeId, int priceTypeId) {
            using (var transaction = _context.Database.BeginTransaction()) {
                var persist = _context.BemsSitePrice.Where(x => x.SiteId == siteId && x.FuelTypeId == fuelTypeId && x.PriceTypeId == priceTypeId);
                _context.BemsSitePrice.RemoveRange(persist);
                _context.SaveChanges();

                //BemsPriceFormula Update
                //전기:100, 가스:101, 수도:102, 등유:104, LPG:105, 증온수:106
                int facilityTypeId = fuelTypeId == 1 ? 100 : fuelTypeId == 2 ? 101 : fuelTypeId == 3 ? 102 : fuelTypeId == 4 ? 104 : fuelTypeId == 5 ? 105 : 106;
                int? facilityCode = _context.CmFacility.Where(x => x.SiteId == siteId && x.FacilityTypeId == facilityTypeId).Select(x => x.FacilityCode).FirstOrDefault();
                int formulaId = 1;      //formulaId 전체로 매칭
                var persist2 = _context.BemsPriceFormula.Where(x => x.SiteId == siteId && x.PriceTypeId == priceTypeId).ToList();
                _context.BemsPriceFormula.RemoveRange(persist2);
                _context.SaveChanges();

                BemsPriceFormula oldPriceFormula = new BemsPriceFormula {
                    SiteId = siteId,
                    PriceTypeId = priceTypeId,
                    FacilityTypeId = facilityTypeId,
                    FormulaId = formulaId,
                    FacilityCode = (int)facilityCode,
                    UseYN = "N"
                };
                _context.BemsPriceFormula.Add(oldPriceFormula);
                _context.SaveChanges();

                transaction.Commit();
            }
        }

        public IQueryable<BemsFuelType> GetFuelType() {
            var data = _context.BemsFuelType.Where(x => x.FuelTypeId != 0);
            return data;
        }

        private BemsPriceFormula GetBemsPriceFormula(int siteId, int fuelTypeId, int priceTypeId) {
            //전기:100, 가스:101, 수도:102, 등유:104, LPG:105, 증온수:106
            int facilityTypeId = fuelTypeId == 1 ? 100 : fuelTypeId == 2 ? 101 : fuelTypeId == 3 ? 102 : fuelTypeId == 4 ? 104 : fuelTypeId == 5 ? 105 : 106;
            int? facilityCode = _context.CmFacility.Where(x => x.SiteId == siteId && x.FacilityTypeId == facilityTypeId).Select(x => x.FacilityCode).FirstOrDefault();
            int formulaId = 1;      //formulaId 전체로 매칭
            var persist2 = _context.BemsPriceFormula.Where(x => x.SiteId == siteId && x.FacilityTypeId == facilityTypeId && x.FacilityCode == facilityCode && x.PriceTypeId == priceTypeId && x.FormulaId == formulaId).FirstOrDefault();

            return persist2;
        }
    }
}