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 AutomationFixtureToolsProductRepository : AccRepositoryBase<siger_automation_fixture_tools_product>, IAutomationFixtureToolsProductRepository
    {
        private ApiAccDbContext _context;
        public AutomationFixtureToolsProductRepository(ApiAccDbContext context) : base(context)
        {
            _context = context;
        }

        public ResponseProductFixtureInfo GetFixtureInfoByProductCode(int projectId, string productCode)
        {
            var query = from q in _context.siger_automation_fixture_tools_product
                        join t in _context.siger_automation_fixture_tools on q.fixturetools equals t.guid
                        join l in _context.siger_automation_location on t.guid equals l.fixturetools
                        where q.projectId == projectId && q.productcode==productCode && q.status == (int)RowState.Valid && t.status == (int)RowState.Valid
                        select new ResponseProductFixtureInfo
                        {
                            FixtureName=t.name,
                            FixtureGuid=t.guid,
                            ProductCode=q.productcode,
                            Location=l.locationid,
                        };
            return query.FirstOrDefault();
        }

        public IPagedCollectionResult<ResponseAumationFixtureToolsProduct> GetPagedList(int category, int tool, int product, int projectid, int page, int pagesize, string toexcel)
        {
            var query = from q in _context.siger_automation_fixture_tools_product
                        join t in _context.siger_automation_fixture_tools on q.fixturetools equals t.guid
                        join c in _context.siger_automation_fixture_tools_category on t.category equals c.guid
                        join p in _context.siger_project_product on q.productid equals p.id
                        join u in _context.siger_project_user on q.updator equals u.mid into uu
                        from u in uu.DefaultIfEmpty()
                        where q.projectId == projectid && q.status == (int)RowState.Valid
                        select new ResponseAumationFixtureToolsProduct
                        {
                            id = q.id,
                            categoryid = c.id,
                            categoryname = c.name,
                            fixturetoolid = t.id,
                            fixturetool = t.name,
                            productid = q.productid,
                            productname = p.name,
                            remark = q.remark,
                            updator = u.name ?? "",
                            updatetime = q.updatetime.HasValue && q.updatetime > DateTime.MinValue ? q.updatetime.Value.ToString(ParameterConstant.DateTimeFormat) : "",
                            fileurl = q.attachment,
                            filename = q.filename,
                            partnumber = t.partnumber,
                            specfication = t.specification,
                            productcode = p.code,
                            cate_guid = c.guid ?? ""
                        };
            Expression<Func<ResponseAumationFixtureToolsProduct, bool>> categoryExpression = f => true;
            if (category > 0)
            {
                categoryExpression = q => q.categoryid == category;
            }
            Expression<Func<ResponseAumationFixtureToolsProduct, bool>> toolExpression = f => true;
            if (tool > 0)
            {
                toolExpression = q => q.fixturetoolid == tool;
            }
            Expression<Func<ResponseAumationFixtureToolsProduct, bool>> productExpression = f => true;
            if (product > 0)
            {
                productExpression = q => q.productid == product;
            }
            var expression = categoryExpression.And(toolExpression).And(productExpression);
            if (toexcel.ToInt() == 1)
            {
                var entities = query.Where(expression).OrderByDescending(q => q.id).AsNoTracking().ToList();
                return new PagedCollectionResult<ResponseAumationFixtureToolsProduct>(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<ResponseAumationFixtureToolsProduct>(entities, totalCount);
            }
        }

        public ResponsePlanlFixtureInfo GetPlanFixtureInfo(int projectId, string ordernumber)
        {

            var query = from d in _context.siger_project_product_plan_detail
                        join p in _context.siger_project_product_plan on d.PlanId equals p.id
                        join q in _context.siger_automation_fixture_tools_product on p.product_code equals q.productcode 
                        join t in _context.siger_automation_fixture_tools on q.fixturetools equals t.guid 
                        join l in _context.siger_automation_location on t.guid equals l.fixturetools 
                        where q.projectId == projectId && d.OrderNumber == ordernumber
                        && q.status == (int)RowState.Valid && t.status == (int)RowState.Valid && l.status==(int)RowState.Valid
                        select new ResponsePlanlFixtureInfo
                        {
                            OrderNumber = ordernumber,
                            ProductName = p.product_name,
                            FixtureName=t.name,
                            FixtureGuid=t.guid,
                            ProductCode =q!=null? q.productcode:"",
                            Location =l!=null? l.locationid:0,
                        };
            return query.FirstOrDefault();
        }


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

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

                if (string.IsNullOrEmpty(item.FixtureTool) || string.IsNullOrEmpty(item.Product) || string.IsNullOrEmpty(item.Product))
                {
                    errors.Add($"{rowIndex},{(int)RequestEnum.ParameterMiss}");
                }
                var fixtureTool = _context.siger_automation_fixture_tools.FirstOrDefault(q => q.projectId == projectid && q.name == item.FixtureTool);
                if (fixtureTool == null)
                {
                    errors.Add($"{rowIndex},{(int)RequestEnum.FixtureToolNotFound}");
                }
                var product = _context.siger_project_product.FirstOrDefault(q => q.projectid == projectid && q.status == (int)RowState.Valid && q.code == item.Product);
                if (product == null)
                {
                    errors.Add($"{rowIndex},{(int)RequestEnum.ProductNotFound}");
                }
                if(fixtureTool != null && product != null)
                {
                    var data = _context.siger_automation_fixture_tools_product.FirstOrDefault(q => q.projectId == projectid && q.status == (int)RowState.Valid && (q.fixturetools == fixtureTool.guid ||
                        q.productid == product.id));
                    if (data != null)
                    {
                        errors.Add($"{rowIndex},{(int)RequestEnum.DataExist}");
                    }
                }

                if(list.Count(q => q.FixtureTool == item.FixtureTool || q.Product == item.Product) > 1)
                {
                    errors.Add($"{rowIndex},{(int)RequestEnum.DataExist}");
                }

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

                var entity = new siger_automation_fixture_tools_product
                {
                    guid = Guid.NewGuid().ToString(),
                    fixturetools = fixtureTool.guid,
                    remark = item.Remark,
                    productid = product.id,
                    productcode = product.code,
                    projectId = projectid,
                    createtime = DateTime.Now,
                    updatetime = DateTime.Now,
                    creator = userid,
                    updator = userid,
                    attachment = "",
                    filename = ""
                };
                entities.Add(entity);
            }

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