using Microsoft.EntityFrameworkCore;
using Siger.Middlelayer.Common;
using Siger.Middlelayer.QmsRepository.Entities;
using Siger.Middlelayer.QmsRepository.Repositories.Interface;
using Siger.Middlelayer.QmsRepository.Response;
using Siger.Middlelayer.Repository.Paged;
using Siger.Middlelayer.Utility.ImportEntities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

namespace Siger.Middlelayer.QmsRepository.Repositories
{
    internal class InspectStandardCategoryRepository : QMSRepositoryBase<siger_qms_inspection_standard_category>, IInspectStandardCategoryRepository
    {
        private readonly ApiQmsDbContext _context;
        public InspectStandardCategoryRepository(ApiQmsDbContext context) : base(context)
        {
            _context = context;
        }

        public IPagedCollectionResult<ReponseInspectStandardCategory> GetPagedList(int parentid, int projectid, int page, int pagesize, int toexcel)
        {
            var query0 = _context.siger_qms_inspection_standard_category.Where(q =>
                q.status == (int)RowState.Valid && q.projectid == projectid && q.parentid == 0);

            var querylist0 = from q in query0
                             select new ReponseInspectStandardCategory
                             {
                                 id = q.id,
                                 parentid = q.parentid,
                                 name = q.name,
                                 parentname = "TOP"
                             };

            var query1 = _context.siger_qms_inspection_standard_category.Where(q =>
                q.status == (int)RowState.Valid && q.projectid == projectid
                                                 && q.parentid != 0);
            var querylist1 = from q in query1
                             join p in _context.siger_qms_inspection_standard_category on q.parentid equals p.id
                                 into temp
                             from tt in temp.DefaultIfEmpty()
                             select new ReponseInspectStandardCategory
                             {
                                 id = q.id,
                                 parentid = q.parentid,
                                 name = q.name,
                                 parentname = tt.name ?? ""
                             };


            Expression<Func<ReponseInspectStandardCategory, bool>> parentidExpression = q => true;
            if (parentid > 0) // 取全部子级
            {
                var ids = GetSonCategorys(parentid, projectid).Select(t => t.id).ToList();
                ids.Add(parentid);
                parentidExpression = q => ids.Contains(q.id);
            }

            var predicate = parentidExpression;

            var entities = querylist0.Union(querylist1).Where(predicate).AsNoTracking().ToList();
            var totalCount = entities.Count;

            if(toexcel > 0)
            {
                var list = entities.OrderBy(q => q.parentid).ToList();
                return new PagedCollectionResult<ReponseInspectStandardCategory>(list, totalCount);
            }
            else
            {
                var list = entities.OrderBy(q => q.parentid).Skip((page - 1) * pagesize).Take(pagesize);
                return new PagedCollectionResult<ReponseInspectStandardCategory>(list, totalCount);
            }                        
        }

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

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

        public CommonImportResult ImportInspectStandardCategory(IEnumerable<InspectStandardCategoryTemplate> datas, int projectid)
        {
            var errors = new List<string>();
            var rowIndex = 1;
            //检查输入信息
            foreach (var data in datas)
            {
                rowIndex++;
                //获取相关实体
                if (string.IsNullOrEmpty(data.name))
                {
                    errors.Add($"{rowIndex},{(int)RequestEnum.ParameterMiss}");
                }
                var exsit1 = _context.siger_qms_inspection_standard_category.FirstOrDefault(t => t.projectid == projectid &&
                    t.status == (int)RowState.Valid && t.name == data.name) != null;
                var exist2 = datas.Count(t => t.name == data.name) > 1;
                if (exsit1 || exist2)
                {
                    errors.Add($"{rowIndex},{(int)CommonEnum.RecordExits}");
                }
                var category = _context.siger_qms_inspection_standard_category.FirstOrDefault(t => t.projectid == projectid &&
                    t.status == (int)RowState.Valid && t.name == data.parentname);
                if(category == null && !string.IsNullOrWhiteSpace(data.parentname))
                {
                    errors.Add($"{rowIndex},{(int)CommonEnum.RecordNotFound}");
                }
                if (errors.Any())
                {
                    return new CommonImportResult(0, string.Join(";", errors));
                }

                var entity = new siger_qms_inspection_standard_category
                {
                    name = data.name,
                    parentid = category?.id ?? 0,
                    projectid = projectid
                };
                try
                {
                    _context.siger_qms_inspection_standard_category.Add(entity);
                    if (_context.SaveChanges() <= 0)
                    {
                        throw new BadRequestException(CommonEnum.Fail);
                    }
                }
                catch
                {
                    throw;
                }
            }                
            return new CommonImportResult(1, "1");
        }
    }
}
