using Microsoft.Extensions.Logging;
using FMSAdmin.Data;
using System.Linq;
using FMSAdmin.Helpers;
using FMSAdmin.Entities;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections;
using System.Collections.Generic;

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

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

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

        public IQueryable<CmSite> Get(int siteId) {
            var data = _context.CmSite.Where(x => x.SiteId == siteId);
            return data;
        }

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


                checkName(data);
                var image = data.ImageFile;
                data.ImageFile = null;
                _context.CmSite.Add(data);
                _context.SaveChanges();

                if (image != null && image.IsUpload) {
                    var category = _context.CmFileCategory.First(x => x.Name == "site");
                    data.ImageFile = image;
                    data.ImageFile.SiteId = data.SiteId;
                    data.ImageFile.FileCategory = category;
                    data.ImageFile.CreatedDate = DateTime.Now;

                    _context.CmSite.Update(data);
                    _context.SaveChanges();
                }

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

                var businessField = new CmBusinessField {
                    Name = "공통",
                    IsUse = true
                };
                _context.CmBusinessField.Add(businessField);
                _context.SaveChanges();

                if (!_context.SiteConfig.Single().UseMaterialType) {
                    var meterialType = new FmsMaterialCodeType {
                        //SiteId = data.SiteId,
                        Name = "자재구분미사용",
                        Nickname = "자재구분미사용",
                        IsUse = true
                    };
                    _context.FmsMaterialCodeType.Add(meterialType);
                    _context.SaveChanges();
                }
                //휴일 작업 구분 자동 생성
                CreateWorkCodeHolidayWorkType(data.SiteId);
                //작업 주기 코드 자동생성
                CreateWorkCodeCycleUnit(data.SiteId);
                //휴일(토/일) 주말 설정 자동생성
                CreateHolidayWeekend(data.SiteId);

                //CmPartnerType 자동생성 최초 사이트 생성시 
                if (_context.CmPartnerType.Count() == 0) {
                    var partnerType = new CmPartnerType {
                        Name = "검사기관",
                        IsUse = true
                    };
                    _context.CmPartnerType.Add(partnerType);
                    _context.SaveChanges();
                }

                //빌딩 자동 생성
                var building = new CmBuilding {
                    SiteId = data.SiteId,
                    Name = data.Name,
                    IsUse = true
                };
                _context.CmBuilding.Add(building);
                _context.SaveChanges();

                transaction.Commit();
            }
        }


        public void Edit(int siteId, CmSite 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 == "site");
                    data.ImageFile.FileCategory = category;
                    data.ImageFile.CreatedDate = DateTime.Now;
                }

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

                if (!persist.Name.Equals(data.Name)) {
                    checkName(data);
                }
                _logger.LogInformation("수정");
                persist.Name = data.Name;
                persist.PhoneNo = data.PhoneNo;
                persist.AddressZip1 = data.AddressZip1;
                persist.CompletionDate = data.CompletionDate;
                persist.Address1 = data.Address1;
                persist.Adderss2 = data.Adderss2;
                persist.BuildingSize = data.BuildingSize;
                persist.GrossArea = data.GrossArea;
                persist.BuildingArea = data.BuildingArea;
                persist.FloorAreaRatio = data.FloorAreaRatio;
                persist.BuildingCoverageRatio = data.BuildingCoverageRatio;
                persist.MainUse = data.MainUse;
                persist.MainUseIndex = data.MainUseIndex;
                persist.IsControlSchedule = data.IsControlSchedule;
                persist.ScheduleCheckHour = data.ScheduleCheckHour;
                persist.Standard = data.Standard;
                persist.Hdd = data.Hdd;
                persist.Cdd = data.Cdd;
                persist.Url = data.Url;
                persist.IsUse = data.IsUse;
                persist.ApiSido = data.ApiSido;
                persist.ApiSigun = data.ApiSigun;
                persist.ImageMapX = data.ImageMapX;
                persist.ImageMapY = data.ImageMapY;
                persist.DesignSupervision = data.DesignSupervision;
                persist.ConstructionCompany = data.ConstructionCompany;
                persist.ConstructionPeriod = data.ConstructionPeriod;
                persist.Structure = data.Structure;
                persist.LobbyFloor = data.LobbyFloor;
                persist.OfficeFloor = data.OfficeFloor;
                persist.ToiletFloor = data.ToiletFloor;
                persist.EVHall = data.EVHall;
                persist.ParkingLot = data.ParkingLot;
                persist.ParkingFacilities = data.ParkingFacilities;
                persist.OuterWall = data.OuterWall;
                persist.LandArea = data.LandArea;
                persist.LandscapingArea = data.LandscapingArea;
                persist.BuildingFloors = data.BuildingFloors;
                persist.BuildingHeight = data.BuildingHeight;
                persist.ConversionRate = data.ConversionRate;
                persist.AuditoriumFacilities = data.AuditoriumFacilities;

                if (data.ImageFile != null && data.ImageFile.IsUpload) {
                    persist.ImageFile = data.ImageFile;
                }
                persist.Comment = data.Comment;

                _context.CmSite.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 void CreateWorkCodeCycleUnit(int siteId) {
            IList<FmsWorkCodeCycleUnit> workCodeCyleUnits = new List<FmsWorkCodeCycleUnit>();
            workCodeCyleUnits.Add(new FmsWorkCodeCycleUnit {
                SiteId = siteId,
                CycleUnitId = 1,
                Name = "일간",
                Description = "매일 처리해야하는 작업"
            });
            workCodeCyleUnits.Add(new FmsWorkCodeCycleUnit {
                SiteId = siteId,
                CycleUnitId = 2,
                Name = "주간",
                Description = "일주일 단위로 처리해야 하는작업"
            });
            workCodeCyleUnits.Add(new FmsWorkCodeCycleUnit {
                SiteId = siteId,
                CycleUnitId = 3,
                Name = "월간",
                Description = "매월 처리해야하는 작업"
            });
            workCodeCyleUnits.Add(new FmsWorkCodeCycleUnit {
                SiteId = siteId,
                CycleUnitId = 4,
                Name = "분기",
                Description = "분기에 1회씩 처리해야하는 작업"
            });
            workCodeCyleUnits.Add(new FmsWorkCodeCycleUnit {
                SiteId = siteId,
                CycleUnitId = 5,
                Name = "반기",
                Description = "6개월에 1회씩 처리해야하는 작업"
            });
            workCodeCyleUnits.Add(new FmsWorkCodeCycleUnit {
                SiteId = siteId,
                CycleUnitId = 6,
                Name = "년간",
                Description = "1년에 한번씩 처리해야 하는 작업"
            });

            _context.FmsWorkCodeCycleUnit.AddRange(workCodeCyleUnits);
            _context.SaveChanges();
        }

        //휴일 작업 구분 자동 생성
        public void CreateWorkCodeHolidayWorkType(int siteId) {
            IList<FmsWorkCodeHolidayWorkType> holidayWorkTypes = new List<FmsWorkCodeHolidayWorkType>();
            holidayWorkTypes.Add(new FmsWorkCodeHolidayWorkType {
                SiteId = siteId,
                HolidayWorkTypeId = 0,
                Name = "사용 안 함",
                IsUse = true
            });

            holidayWorkTypes.Add(new FmsWorkCodeHolidayWorkType {
                SiteId = siteId,
                HolidayWorkTypeId = 1,
                Name = "휴일작업",
                IsUse = true
            });

            holidayWorkTypes.Add(new FmsWorkCodeHolidayWorkType {
                SiteId = siteId,
                HolidayWorkTypeId = 2,
                Name = "익일작업",
                IsUse = true
            });
            _context.FmsWorkCodeHolidayWorkType.AddRange(holidayWorkTypes);
            _context.SaveChanges();
        }

        public void checkName(CmSite data) {
            var check = _context.CmSite.Where(x => x.Name == data.Name).Count();
            if (check > 0) {
                throw new ServiceException("이미 동일 이름이 존재합니다.");
            }
        }

        public void Delete(int siteId) {
            var data = _context.CmSite.First(x => x.SiteId == siteId);
            data.IsUse = false;
            _context.SaveChanges();
        }

        //휴일(토/일) 주말 설정 자동생성
        public void CreateHolidayWeekend(int siteId) {
            CmHolidayWeekend holiday = new CmHolidayWeekend {
                SiteId = siteId,
                Saturday = true,
                Sunday = true,
                IsUse = true
            };
            _context.CmHolidayWeekend.Add(holiday);
            _context.SaveChanges();
        }
    }
}