using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using Microsoft.EntityFrameworkCore;
using Siger.Middlelayer.AccRepository.Entities;
using Siger.Middlelayer.AccRepository.Repositories.Interface;
using Siger.Middlelayer.AccRepository.Response;
using Siger.Middlelayer.Common;
using Siger.Middlelayer.Common.Extensions;
using Siger.Middlelayer.Log;
using Siger.Middlelayer.Repository.Data.Acc;
using Siger.Middlelayer.Repository.Extensions;
using Siger.Middlelayer.Repository.Paged;
using Siger.Middlelayer.Utility.ImportEntities;

namespace Siger.Middlelayer.AccRepository.Repositories
{
    internal class AutomationFixtureToolsRepository : AccRepositoryBase<siger_automation_fixture_tools>, IAutomationFixtureToolsRepository
    {
        private ApiAccDbContext _context;
        public AutomationFixtureToolsRepository(ApiAccDbContext context) : base(context)
        {
            _context = context;
        }

        public IPagedCollectionResult<ResponseFixtureTools> GetPagedList(List<int> category, string code, string name, int state, 
                int projectid, int page, int pagesize, string toexcel = "")
        {
            var query = from q in _context.siger_automation_fixture_tools
                        join p in _context.siger_automation_fixture_tools_category on q.category equals p.guid
                        join u in _context.siger_project_user on q.updator equals u.mid into uu
                        from u in uu.DefaultIfEmpty()
                        where q.projectId == projectid
                        select new ResponseFixtureTools
                        {
                            id = q.id,
                            name = q.name,
                            guid = q.guid,
                            cate_guid = p.guid,
                            categoryid = p.id,
                            category = p.name,
                            managetype = q.managetype,
                            partnumber = q.partnumber,
                            specification = q.specification,
                            number = q.number,
                            remark = q.remark,
                            fileurl = q.attachment ?? "",
                            filename = q.filename ?? "",
                            code = q.code,
                            updator = u.name ?? "",
                            status = q.status,
                            updatetime = q.updatetime.HasValue && q.updatetime > DateTime.MinValue ? q.updatetime.Value.ToString(ParameterConstant.DateTimeFormat) : ""
                        };
            Expression<Func<ResponseFixtureTools, bool>> categoryExpression = f => true;
            if (category.Any())
            {
                categoryExpression = q => category.Contains(q.categoryid);
            }
            Expression<Func<ResponseFixtureTools, bool>> codeExpression = f => true;
            if (!string.IsNullOrEmpty(code))
            {
                categoryExpression = q => q.code.Contains(code);
            }
            Expression<Func<ResponseFixtureTools, bool>> nameExpression = f => true;
            if (!string.IsNullOrEmpty(name))
            {
                nameExpression = q => q.name.Contains(name);
            }
            Expression<Func<ResponseFixtureTools, bool>> stateExpression = f => true;
            if (state >= 0)
            {
                stateExpression = q => q.status == state;
            }
            var expression = categoryExpression.And(codeExpression).And(nameExpression).And(stateExpression);
            if(toexcel.ToInt() == 1)
            {
                var entities = query.Where(expression).OrderByDescending(q => q.id).AsNoTracking().ToList();
                return new PagedCollectionResult<ResponseFixtureTools>(entities, entities.Count);
            }
            else
            {
                var entities = query.Where(expression).OrderByDescending(q => q.id).Skip((page - 1) * pagesize).Take(pagesize).AsNoTracking().ToList();
                var totalCount = query.Where(expression).Count();
                return new PagedCollectionResult<ResponseFixtureTools>(entities, totalCount);
            }
        }


        public IEnumerable<ResponseFixtureTools> GetDataList(List<int> categoryid, int projectid)
        {
            var query = from q in _context.siger_automation_fixture_tools
                        join p in _context.siger_automation_fixture_tools_category on q.category equals p.guid
                        where q.projectId == projectid && q.status == (int)RowState.Valid
                        select new ResponseFixtureTools
                        {
                            id = q.id,
                            name = q.name,
                            guid = q.guid,
                            cate_guid = p.guid,
                            categoryid = p.id,
                            category = p.name,
                            managetype = q.managetype,
                            partnumber = q.partnumber,
                            specification = q.specification,
                            number = q.number,
                            remark = q.remark,
                            code = q.code,
                            status = q.status,
                            updatetime = q.updatetime.HasValue && q.updatetime > DateTime.MinValue ? q.updatetime.Value.ToString(ParameterConstant.DateTimeFormat) : ""
                        };
            if (categoryid.Any())
            {
                query = query.Where(q => categoryid.Contains(q.categoryid));
            }
            var entities = query.OrderByDescending(q => q.id).AsNoTracking().ToList();
            return entities;
        }

        public ResponseProductFixtureInfo GetProductFixtureLocation(int projectId, string guid)
        {
            var query = from q in _context.siger_automation_fixture_tools
                        join l in _context.siger_automation_location on q.guid equals l.fixturetools
                        select new ResponseProductFixtureInfo
                        {
                             FixtureGuid=q.guid,
                             FixtureName=q.name,
                 
                             Location=l.locationid
                        };
            return query.FirstOrDefault();
        }


        public CommonImportResult ImportData(IEnumerable<FixtureToolsTemplate> list, int projectid, int userid)
        {
            var entities = new List<siger_automation_fixture_tools>();

            var errors = new List<string>();
            var rowIndex = 1;
            foreach (var item in list)
            {
                rowIndex++;

                if (string.IsNullOrEmpty(item.Catgeory))
                {
                    errors.Add($"{rowIndex},{(int)RequestEnum.PleaseInputFixtureCategory}");
                }
                if (string.IsNullOrEmpty(item.Manage))
                {
                    errors.Add($"{rowIndex},{(int)RequestEnum.PleaseInputManageType}");
                }
                if (string.IsNullOrEmpty(item.Name))
                {
                    errors.Add($"{rowIndex},{(int)RequestEnum.PleaseInputFixtureName}");
                }
                if (string.IsNullOrEmpty(item.PartNumber))
                {
                    errors.Add($"{rowIndex},{(int)RequestEnum.PleaseInputPartNumber}");
                }
                if (string.IsNullOrEmpty(item.Code))
                {
                    errors.Add($"{rowIndex},{(int)RequestEnum.PleaseInputFixtureCode}");
                }
                if (string.IsNullOrEmpty(item.Specfication))
                {
                    errors.Add($"{rowIndex},{(int)RequestEnum.PleaseInputSpecfication}");
                }
                if (string.IsNullOrEmpty(item.Number))
                {
                    errors.Add($"{rowIndex},{(int)RequestEnum.PleaseInputNumber}");
                }
                if (string.IsNullOrEmpty(item.Status))
                {
                    errors.Add($"{rowIndex},{(int)RequestEnum.PleaseInputStatus}");
                }

                if(!int.TryParse(item.Number, out int number))
                {
                    errors.Add($"{rowIndex},{(int)RequestEnum.NumberPleaseInputInt}");
                }

                if (item.Manage.Trim() != "单件" && item.Manage.Trim() != "批次")
                {
                    errors.Add($"{rowIndex},{(int)RequestEnum.ManageTypeInputSingleOrBatch}");
                }

                if (item.Status.Trim() != "可用" && item.Status.Trim() != "停用")
                {
                    errors.Add($"{rowIndex},{(int)RequestEnum.StatusInputUsefulOrDisabled}");
                }

                var data = _context.siger_automation_fixture_tools.FirstOrDefault(q => q.projectId == projectid && q.code == item.Code);
                if (data != null)
                {
                    errors.Add($"{rowIndex},{(int)RequestEnum.DataExist}");
                }
                if (list.Count(q => q.Code == item.Code) > 1)
                {
                    errors.Add($"{rowIndex},{(int)RequestEnum.DataExist}");
                }

                var category = _context.siger_automation_fixture_tools_category.FirstOrDefault(q => q.name == item.Catgeory && q.projectId == projectid && q.status == (int)RowState.Valid);
                if (category == null)
                {
                    errors.Add($"{rowIndex},{(int)RequestEnum.FixtureToolCatgeoryNotFound}");
                }

                if (errors.Any())
                {
                    return new CommonImportResult(0, string.Join(";", errors));
                }

                var entity = new siger_automation_fixture_tools
                {
                    guid = Guid.NewGuid().ToString(),
                    category = category.guid,
                    managetype = item.Manage.Trim() == "单件" ? 1 : 2,
                    partnumber = item.PartNumber,
                    name = item.Name,
                    specification = item.Specfication,
                    number = item.Number.ToInt(),
                    remark = item.Remark,
                    attachment = "",
                    filename = "",
                    code = item.Code,
                    projectId = projectid,
                    status = item.Status.Trim() == "可用" ? (int)RowState.Valid : (int)RowState.Invalid,
                    createtime = DateTime.Now,
                    updatetime = DateTime.Now,
                    creator = userid,
                    updator = userid,
                };
                entities.Add(entity);
            }

            try
            {
                _context.siger_automation_fixture_tools.AddRange(entities);
                _context.SaveChanges();
                return new CommonImportResult(1, "1");
            }
            catch (Exception e)
            {
                Logger.WriteLineError(e.Message);
                throw;
            }
        }
    }
}
