using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using Microsoft.EntityFrameworkCore;
using Siger.Middlelayer.Common;
using Siger.Middlelayer.Common.Helpers;
using Siger.Middlelayer.Repository.Data;
using Siger.Middlelayer.Repository.Extensions;
using Siger.Middlelayer.Repository.Paged;
using Siger.Middlelayer.Repository.Response;
using Siger.Middlelayer.TpmRepository.Entities;
using Siger.Middlelayer.TpmRepository.Repositories.Interface;
using Siger.Middlelayer.Utility.ExcelImport;
using Siger.Middlelayer.Utility.ImportEntities;

namespace Siger.Middlelayer.TpmRepository.Repositories
{
    internal class SparepartTypeRepository : TpmRepositoryBase<siger_project_sparepart_type>, ISparepartTypeRepository
    {
        private readonly ApiTpmDbContext _context;
        public SparepartTypeRepository(ApiTpmDbContext context) : base(context)
        {
            _context = context;
        }
        public IPagedCollectionResult<ResponseGetSparepartType> GetPagedList(int id, string title, int projectid, int page, int pagesize, bool paged = true)
        {
            var translateHelper = new TranslateHelper(GetProjectLanguage(projectid) == (int)LanguageType.EN);
            var queryList = from q in _context.siger_project_sparepart_type
                            join qq in _context.siger_project_sparepart_type on q.parentid equals qq.id into temp
                            from type in temp.DefaultIfEmpty()
                            where q.status == (int)RowState.Valid && q.projectid == projectid
                            select new ResponseGetSparepartType
                            {
                                id = q.id,
                                description = q.description,
                                parentid = q.parentid,
                                pretitle = type != null ? type.title : translateHelper.GetTranslateText(TranslateEnEnum.TypeOfFirstClassSpareparts),
                                title = q.title,
                                userId=q.userId
                            };

            Expression<Func<ResponseGetSparepartType, bool>> idExpression = q => true;
            if (id > 0)
            {
                idExpression = q => (q.id == id || q.parentid == id);
            }

            Expression<Func<ResponseGetSparepartType, bool>> titleExpression = q => true;
            if (!string.IsNullOrEmpty(title))
            {
                titleExpression = q => q.title.Contains(title);
            }

            var query = idExpression.And(titleExpression);
            if (paged)
            {
                var totalCount = queryList.Count(query);
                var entities = queryList.Where(query).Skip((page - 1) * pagesize).Take(pagesize).AsNoTracking().ToList();

                return new PagedCollectionResult<ResponseGetSparepartType>(entities, totalCount);
            }
            else
            {
                var entities = queryList.Where(query).AsNoTracking().ToList();
                return new PagedCollectionResult<ResponseGetSparepartType>(entities, 0);
            }
        }

        public IEnumerable<SparepartTypeTree> GetLevelSparepartTypes(int projectid)
        {
            var list = new List<SparepartTypeTree>();
            var query = GetSonSparepartTypes(0, projectid);

            foreach (var section in query.ToList())
            {
                list.Add(new SparepartTypeTree { id = section.id, name = section.title, pid = section.parentid, label = section.title, value = section.id,title= section.title });
            }

            return list;
        }

        public IEnumerable<siger_project_sparepart_type> GetSonSparepartTypes(int parentId, int projectid)
        {
            var query = from c in _context.siger_project_sparepart_type
                        where c.parentid == parentId && c.projectid == projectid && c.status == (int)RowState.Valid
                        select c;

            return query.ToList().Concat(query.ToList().SelectMany(t => GetSonSparepartTypes(t.id, projectid)));
        }

        public CommonImportResult ImportSparepartType(IEnumerable<SparepartTypeList> types, int projectId)
        {
            var errors = new List<string>();
            var rowIndex = 1;
            foreach (var type in types)
            {
                rowIndex++;

                var entity = _context.siger_project_sparepart_type.FirstOrDefault(q => q.title == type.LevelOneType && q.projectid == projectId
                                                                                       && q.status == (int)RowState.Valid);
                if (entity != null)
                {
                    errors.Add($"{rowIndex},{(int)ImportEnum.SparepartTypeIsExist}");
                }
                if (errors.Any())
                {
                    return new CommonImportResult(0, string.Join(";", errors));
                }
            }

            try
            {
                var typeEntities = types.ToList();
                for (int i = 0; i < typeEntities.Count; i++)
                {
                    var type = typeEntities[i];

                    var oneTypeId = AddSparepartType(type.LevelOneType, 0, projectId);
                    if (!string.IsNullOrWhiteSpace(type.LevelTwoType))
                    {
                        var twoTypeId = AddSparepartType(type.LevelTwoType, oneTypeId, projectId);
                        if (!string.IsNullOrWhiteSpace(type.LevelThreeType))
                        {
                            var threeTypeId = AddSparepartType(type.LevelThreeType, twoTypeId, projectId);
                            if (!string.IsNullOrWhiteSpace(type.LevelThourType))
                            {
                                var fourTypeId = AddSparepartType(type.LevelThourType, threeTypeId, projectId);
                                if (!string.IsNullOrWhiteSpace(type.LevelFiveType))
                                {
                                    AddSparepartType(type.LevelFiveType, fourTypeId, projectId);
                                }
                            }
                        }
                    }
                }
                _context.SaveChanges();
                return new CommonImportResult(1, "1");
            }
            catch
            {
                throw;
            }
        }

        private int AddSparepartType(string title, int parentId, int projectId)
        {
            var type = _context.siger_project_sparepart_type.FirstOrDefault(q => q.title == title && q.projectid == projectId && q.status == (int)RowState.Valid);
            if (type == null)
            {
                var entity = new siger_project_sparepart_type
                {
                    title = title,
                    parentid = parentId,
                    projectid = projectId,
                };
                _context.siger_project_sparepart_type.Add(entity);
                _context.SaveChanges();
                return entity.id;
            }

            return type.id;
        }
    }
}
