using Atomx.Admin.Client.Models;
using Atomx.Admin.Client.Validators;
using Atomx.Admin.Services;
using Atomx.Common.Entities;
using Atomx.Common.Enums;
using Atomx.Common.Models;
using Atomx.Data;
using Atomx.Data.Services;
using Atomx.Utils.Extension;
using Atomx.Utils.Json;
using Mapster;
using MapsterMapper;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;

namespace Atomx.Admin.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class ProductController : ControllerBase
    {
        readonly ILogger<ProductController> _logger;
        readonly IdentityService _identityService;
        readonly IIdCreatorService _idCreator;
        readonly IMapper _mapper;
        readonly DataContext _dbContext;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="logger"></param>
        /// <param name="identityService"></param>
        /// <param name="idCreator"></param>
        /// <param name="adminService"></param>
        /// <param name="mapper"></param>
        public ProductController(ILogger<ProductController> logger, IdentityService identityService, IIdCreatorService idCreator, IMapper mapper, DataContext dataContext)
        {
            _logger = logger;
            _identityService = identityService;
            _idCreator = idCreator;
            _mapper = mapper;
            _dbContext = dataContext;
        }

        /// <summary>
        /// 查询接口
        /// </summary>
        /// <param name="search"></param>
        /// <param name="page"></param>
        /// <param name="size"></param>
        /// <returns></returns>
        [HttpPost("search")]

        public IActionResult Search(ProductSearch search, int page, int size = 20)
        {
            var result = new ApiResult<PagingList<Product>>();
            try
            {
                var pager = new PagingList<Product>() { Size = size, Index = page < 1 ? 1 : page };

                var query = from p in _dbContext.Products
                            select p;

                pager.Count = query.Count();

                pager.Items = query.OrderByDescending(p => p.Id).Skip((pager.Index - 1) * size).Take(size).ToList();
                result = result.IsSuccess(pager);
            }
            catch (Exception ex)
            {
                result = result.IsFail(ex.Message);
                _logger.LogError(ex.Message);
            }
            return new JsonResult(result);
        }


        /// <summary>
        /// 查询接口
        /// </summary>
        /// <param name="search"></param>
        /// <param name="page"></param>
        /// <param name="size"></param>
        /// <returns></returns>
        [HttpPost("stock/search")]

        public IActionResult StockUnitSearch(ProductStockUnitSearch search, int page, int size = 20)
        {
            var result = new ApiResult<PagingList<ProductStockUnitModel>>();
            try
            {
                List<MiniProductModel> products = new();

                if (search.Type == 1)
                {
                    if (string.IsNullOrEmpty(search.Key))
                    {
                        var productQuery = from p in _dbContext.Products
                                           where p.Status == 1 && p.Title.Contains(search.Key)
                                           select new MiniProductModel
                                           {
                                               Id = p.Id,
                                               Title = p.Title,
                                               Image = p.Image
                                           };
                        products = productQuery.Take(100).ToList();
                    }
                }
                else
                {
                    if (search.Key.ToLong() > 0)
                    {
                        var productQuery = from p in _dbContext.Products
                                           where p.Status == 1 && p.Id == search.Key.ToLong()
                                           select new MiniProductModel
                                           {
                                               Id = p.Id,
                                               Title = p.Title,
                                               Image = p.Image
                                           };
                        products = productQuery.Take(100).ToList();
                    }
                }

                var productIds = products.Select(p => p.Id).ToList();
                var pager = new PagingList<ProductStockUnitModel>() { Size = size, Index = page < 1 ? 1 : page };

                var query = from p in _dbContext.ProductAttributeCombinations
                            select p;

                if (products.Any())
                {
                    query = from p in query
                            where productIds.Contains(p.ProductId)
                            select p;
                }

                if (search.Weight > 0)
                {
                    query = query.Where(p => p.Weight == search.Weight);
                }

                pager.Count = query.Count();

                var list = query.OrderByDescending(p => p.UpdateTime).Skip((pager.Index - 1) * size).Take(size).ToList();

                List<ProductStockUnitModel> stockUnits = new();
                foreach (var item in list)
                {
                    var data = _mapper.Map<ProductStockUnitModel>(item);
                    if (products.Any())
                    {
                        var product = products.SingleOrDefault(p => p.Id == item.ProductId);
                        if (product != null)
                        {
                            data.Title = product.Title;
                            data.Image = product.Image;
                        }

                    }
                    else
                    {
                        var product = _dbContext.Products.SingleOrDefault(p => p.Id == item.ProductId);
                        if (product != null)
                        {
                            data.Title = product.Title;
                            data.Image = product.Image;
                        }
                    }
                    if (!string.IsNullOrEmpty(data.AttributesJson))
                    {
                        data.Sku = data.AttributesJson.FromJson<List<ProductSkuModel>>();
                        foreach (var sku in data.Sku)
                        {
                            if (sku.Weight > 0)
                            {
                                data.WeightUnit = sku.WeightUnit;
                                break;
                            }
                        }
                    }
                    stockUnits.Add(data);
                }

                pager.Items = stockUnits;
                result = result.IsSuccess(pager);
            }
            catch (Exception ex)
            {
                result = result.IsFail(ex.Message);
                _logger.LogError(ex.Message);
            }
            return new JsonResult(result);
        }

        /// <summary>
        /// 根据id获取数据
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet("{id:long}")]
        public IActionResult Get(long id)
        {
            var result = new ApiResult<Product>();
            try
            {
                var data = _dbContext.Products.Where(p => p.Id == id).SingleOrDefault();
                result = result.IsSuccess(data);
            }
            catch (Exception ex)
            {
                result = result.IsFail(ex.Message);
                _logger.LogError(ex.Message);
            }
            return new JsonResult(result);
        }

        /// <summary>
        /// 获取商品详情
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet("detail/{id:long}")]
        public IActionResult Detail(long id)
        {
            var result = new ApiResult<ProductModel>();
            var product = _dbContext.Products.SingleOrDefault(p => p.Id == id);
            if (product == null)
            {
                return new JsonResult(result);
            }
            var attributeCombinations = _dbContext.ProductAttributeCombinations.Where(p => p.ProductId == id).ToList();
            var attributeRelations = _dbContext.ProductAttributeRelations.Where(p => p.ProductId == id).ToList();
            var attributeValues = _dbContext.ProductAttributeValues.Where(p => p.ProductId == id).ToList();


            var productAttributeCombinationList = new List<ProductAttributeCombinationModel>();
            foreach (var item in attributeCombinations)
            {
                var attribute = item.AttributesJson.FromJson<List<ProductSkuModel>>();
                var sku = new ProductAttributeCombinationModel()
                {
                    Enabled = item.Enabled,
                    Id = item.Id,
                    MarketPrice = item.MarketPrice,
                    Price = item.Price,
                    ProductId = item.ProductId,
                    SalesQuantity = item.SalesQuantity,
                    SkuNumber = item.SkuNumber,
                    SkuAttributes = attribute,
                    StockQuantity = item.StockQuantity,
                    Weight = item.Weight,
                    WeightUnit = item.WeightUnit,
                    ManufacturerId = item.ManufacturerId,
                    ProcessCharge = item.ProcessCharge,
                    ProcessCost = item.ProcessCost,
                    Surcharge = item.Surcharge,
                    SurchargeCost = item.SurchargeCost
                };
                productAttributeCombinationList.Add(sku);
            }

            var productSaleAttributes = new List<ProductSaleAttributeModel>();
            int index = 0;
            long skuPhotoAttributeId = 0;
            foreach (var item in attributeRelations)
            {
                var values = (from p in attributeValues
                              where p.ProductAttributeRelationId == item.Id
                              select new ProductAttributeValueModel()
                              {
                                  Id = p.Id,
                                  Image = p.Image,
                                  Name = p.Name,
                                  OptionId = p.OptionId,
                                  DisplayOrder = p.DisplayOrder,
                                  IsAddWeight = p.IsAddWeight,
                                  IsEdit = false,
                                  ProductAttributeRelationId = p.ProductAttributeRelationId,
                                  ProductId = p.ProductId,
                                  Weight = p.Weight.RemoveTrailingZeros().ToDecimal(),
                                  WeightUnit = p.WeightUnit
                              }).ToList();
                if (item.Image)
                {
                    skuPhotoAttributeId = item.AttributeId;
                }
                var attributeTree = _dbContext.ProductAttributes.SingleOrDefault(p => p.Id == item.AttributeId);

                var saleAttribute = new ProductSaleAttributeModel()
                {
                    Id = item.Id,
                    AttributeId = item.AttributeId,
                    Name = attributeTree?.Name ?? "",
                    Image = item.Image,
                    AddAttribute = false,
                    DisplayOrder = index,
                    InputText = string.Empty,
                    SelectOption = string.Empty,
                    ProductAttributeValues = values,
                    ControlType = attributeTree?.ControlType ?? 0,
                    IsRequired = attributeTree?.IsRequired ?? false,
                    WeightIsRequired = attributeTree?.WeightIsRequired ?? false,
                };
                productSaleAttributes.Add(saleAttribute);
                index++;
            }

            var data = _mapper.Map<ProductModel>(product);


            data.ProductAttributeCombinations = productAttributeCombinationList;
            data.ProductSaleAttributes = productSaleAttributes;


            //if (!string.IsNullOrEmpty(product.Photos))
            //{
            //    var photos = product.Photos.FromJson<ProductPhotosModel>();
            //    if (photos != null)
            //    {
            //        data.ProductPhotos = photos;
            //    }
            //}
            //data.SkuPhotoAttributeId = skuPhotoAttributeId;

            result = result.IsSuccess(data);

            return new JsonResult(result);
        }

        /// <summary>
        /// 新增数据
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        [HttpPost("add")]
        public IActionResult Add(ProductModel model)
        {

            var result = new ApiResult<string>();
            var validator = new ProductModelValidator();
            var validation = validator.Validate(model);
            if (!validation.IsValid)
            {
                var message = validation.Errors.FirstOrDefault()?.ErrorMessage ?? string.Empty;
                result = result.IsFail(message, null);
                return new JsonResult(result);
            }

            try
            {
                model.Id = _idCreator.NewId();
                var product = _mapper.Map<Product>(model);
                product.CreateTime = DateTime.UtcNow;

                var productAttributeRelations = new List<ProductAttributeRelation>();
                var productSalesAttributeValues = new List<ProductAttributeValue>();
                var productAttributeCombinations = new List<ProductAttributeCombination>();
                var productInventories = new List<ProductInventory>();
                var productInventroryLogs = new List<ProductInventoryLog>();

                foreach (var item in model.ProductSaleAttributes)
                {
                    var attributeRelated = new ProductAttributeRelation()
                    {
                        AttributeId = item.AttributeId,
                        DisplayOrder = 0,
                        ProductId = product.Id,
                        Image = item.Image,
                        Id = _idCreator.NewId()
                    };

                    foreach (var value in item.ProductAttributeValues)
                    {
                        //处理销售属性值
                        var data = productSalesAttributeValues.SingleOrDefault(p => p.OptionId == value.OptionId && p.Name == value.Name && p.Weight == value.Weight);
                        if (data == null)
                        {
                            var attributeValue = new ProductAttributeValue()
                            {
                                ProductAttributeRelationId = attributeRelated.Id,
                                DisplayOrder = value.DisplayOrder,
                                Id = _idCreator.NewId(),
                                Name = value.Name,
                                OptionId = value.OptionId,
                                ProductId = product.Id,
                                Image = value.Image,
                                WeightUnit = value.WeightUnit,
                                Weight = value.Weight.RemoveTrailingZeros().ToDecimal(),
                                IsAddWeight = value.IsAddWeight
                            };
                            if (!string.IsNullOrEmpty(value.Image))
                            {
                                attributeRelated.Image = true;
                            }

                            foreach (var sku in model.ProductAttributeCombinations)
                            {
                                var skuAttribute = sku.SkuAttributes.SingleOrDefault(p => p.ValueName == attributeValue.Name && p.Weight == attributeValue.Weight);
                                if (skuAttribute != null)
                                {
                                    skuAttribute.ValueId = attributeValue.Id;
                                }
                            }

                            productSalesAttributeValues.Add(attributeValue);
                        }
                    }
                    productAttributeRelations.Add(attributeRelated);
                }

                foreach (var item in model.ProductAttributeCombinations)
                {
                    var data = _mapper.Map<ProductAttributeCombination>(item);
                    data.AttributesJson = item.SkuAttributes.ToJson();
                    data.Id = _idCreator.NewId();
                    data.ProductId = product.Id;
                    data.UpdateTime = DateTime.UtcNow;

                    productAttributeCombinations.Add(data);
                }

                if (productAttributeCombinations.Count > 0)
                {
                    var skuPrices = new List<ProductSKUPricesModel>();
                    foreach (var item in productAttributeCombinations)
                    {
                        var prices = new ProductSKUPricesModel()
                        {
                            Id = item.Id,
                            MarketPrice = item.MarketPrice,
                            Price = item.Price,
                        };
                        skuPrices.Add(prices);

                        if (item.StockQuantity > 0)
                        {
                            var inventory = new ProductInventory()
                            {
                                CorporationId = item.CorporationId,
                                StockQuantity = item.StockQuantity,
                                CreateTime = DateTime.UtcNow,
                                Id = _idCreator.NewId(),
                                ProductAttributeCombinationId = item.Id,
                                ProductId = item.ProductId,
                                WarehouseId = 0
                            };
                            productInventories.Add(inventory);
                            var inventorylog = new ProductInventoryLog()
                            {
                                WarehouseId = 0,
                                ProductId = item.ProductId,
                                ProductAttributeCombinationId = item.Id,
                                Id = _idCreator.NewId(),
                                AfterStock = item.StockQuantity,
                                BeforeStock = 0,
                                ChangeAmount = item.StockQuantity,
                                CorporationId = item.CorporationId,
                                CreateTime = DateTime.UtcNow,
                                ManufacturerId = item.ManufacturerId,
                                Note = string.Empty,
                                Operator = _identityService.GetUserId(),
                                OrderId = 0,
                                StoreId = 0,
                                Type = (int)ProductInventoryChangeType.Initial,
                                Weight = item.Weight.RemoveTrailingZeros().ToDecimal()
                            };
                            productInventroryLogs.Add(inventorylog);
                        }
                    }
                    var stockQuantity = productAttributeCombinations.Where(p => !p.Enabled).Sum(p => p.StockQuantity);

                    product.SkuPrices = skuPrices.ToJson();
                    product.StockQuantity = stockQuantity;
                }




                using (var transaction = _dbContext.Database.BeginTransaction())
                {
                    try
                    {
                        _dbContext.Products.Add(product);
                        if (productAttributeRelations.Count() > 0)
                        {
                            _dbContext.ProductAttributeRelations.AddRange(productAttributeRelations);
                        }
                        if (productSalesAttributeValues.Count() > 0)
                        {
                            _dbContext.ProductAttributeValues.AddRange(productSalesAttributeValues);
                        }
                        if (productAttributeCombinations.Count() > 0)
                        {
                            _dbContext.ProductAttributeCombinations.AddRange(productAttributeCombinations);
                        }
                        if (productInventories.Count() > 0)
                        {
                            _dbContext.ProductInventories.AddRange(productInventories);
                        }
                        if (productInventroryLogs.Count() > 0)
                        {
                            _dbContext.ProductInventoryLogs.AddRange(productInventroryLogs);
                        }

                        int count = _dbContext.SaveChanges();
                        transaction.Commit();
                        result = result.IsSuccess(count.ToString());
                    }
                    catch (Exception ex)
                    {
                        transaction.Rollback();
                        result.Success = false;
                        result.Message = ex.Message;
                        return new JsonResult(result);
                    }
                }
            }
            catch (Exception ex)
            {
                result = result.IsFail(ex.Message);
                _logger.LogError(ex.Message);
            }
            return new JsonResult(result);
        }



        /// <summary>
        /// 编辑数据
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        [HttpPost("edit")]
        public IActionResult Edit(ProductModel model)
        {
            Console.WriteLine("编辑");
            Console.WriteLine(model.ToJson());

            var result = new ApiResult<string>();
            var validator = new ProductModelValidator();
            var validation = validator.Validate(model);
            if (!validation.IsValid)
            {
                var message = validation.Errors.FirstOrDefault()?.ErrorMessage ?? string.Empty;
                result = result.IsFail(message, null);
                return new JsonResult(result);
            }

            var product = _dbContext.Products.SingleOrDefault(p => p.Id == model.Id);

            if (product == null)
            {
                result.Message = "参数错误，产品数据不存在";
                return new JsonResult(result);
            }

            model.Adapt(product);

            var productAttributeRelations = new List<ProductAttributeRelation>();
            var productProductAttributeValues = new List<ProductAttributeValue>();
            var productAttributeCombination = new List<ProductAttributeCombination>();
            var originalProductAttributeRelasions = _dbContext.ProductAttributeRelations.Where(p => p.ProductId == model.Id).ToList();

            foreach (var item in model.ProductSaleAttributes)
            {
                var attributeRelation = originalProductAttributeRelasions.SingleOrDefault(p => p.AttributeId == item.AttributeId);
                if (attributeRelation == null)
                {
                    attributeRelation = new ProductAttributeRelation()
                    {
                        AttributeId = item.AttributeId,
                        DisplayOrder = 0,
                        ProductId = product.Id,
                        Image = item.Image,
                        Id = _idCreator.NewId()
                    };
                }

                foreach (var value in item.ProductAttributeValues)
                {
                    //更新属性值信息

                    var data = productProductAttributeValues.FirstOrDefault(p => p.OptionId == value.OptionId && p.Name == value.Name && p.Weight == value.Weight);
                    if (data == null)
                    {
                        var attributeValue = new ProductAttributeValue()
                        {
                            ProductAttributeRelationId = attributeRelation.Id,
                            DisplayOrder = value.DisplayOrder,
                            Id = value.Id,
                            Name = value.Name,
                            OptionId = value.OptionId,
                            ProductId = product.Id,
                            Image = value.Image,
                            Weight = value.Weight.RemoveTrailingZeros().ToDecimal(),
                            IsAddWeight = value.IsAddWeight,
                            WeightUnit = value.WeightUnit
                        };
                        if (attributeValue.Id == 0)
                        {
                            attributeValue.Id = _idCreator.NewId();
                        }
                        if (!string.IsNullOrEmpty(value.Image))
                        {
                            attributeRelation.Image = true;
                        }
                        else
                        {
                            attributeRelation.Image = false;
                        }
                        productProductAttributeValues.Add(attributeValue);

                        foreach (var sku in model.ProductAttributeCombinations)
                        {
                            var skuAttribute = sku.SkuAttributes.SingleOrDefault(p => p.ValueName == attributeValue.Name && p.Weight == attributeValue.Weight);
                            if (skuAttribute != null)
                            {
                                skuAttribute.ValueId = attributeValue.Id;
                            }
                        }
                    }
                }
                productAttributeRelations.Add(attributeRelation);
            }

            foreach (var item in model.ProductAttributeCombinations)
            {
                //处理产品SKU组合信息
                var data = _mapper.Map<ProductAttributeCombination>(item);
                data.AttributesJson = item.SkuAttributes.ToJson();
                if (data.Id == 0)
                {
                    data.Id = _idCreator.NewId();
                    data.ProductId = product.Id;
                }
                productAttributeCombination.Add(data);
            }


            var originalProductAttributeValues = _dbContext.ProductAttributeValues.Where(p => p.ProductId == model.Id).ToList();
            var originalProductAttributeCombinations = _dbContext.ProductAttributeCombinations.Where(p => p.ProductId == model.Id).ToList();


            var removeProductAttributeRelations = new List<ProductAttributeRelation>();
            var removeProductAttributeValues = new List<ProductAttributeValue>();
            var removeProductAttributeCombinations = new List<ProductAttributeCombination>();


            //处理产品属性
            foreach (var item in originalProductAttributeRelasions)
            {
                var data = productAttributeRelations.SingleOrDefault(p => p.Id == item.Id);
                if (data == null)
                {
                    removeProductAttributeRelations.Add(item);
                }
            }

            //处理产品属性值
            foreach (var item in originalProductAttributeValues)
            {
                var data = productProductAttributeValues.SingleOrDefault(p => p.Id == item.Id);
                if (data == null)
                {
                    removeProductAttributeValues.Add(item);
                }
            }

            //处理SKU组合信息
            foreach (var item in originalProductAttributeCombinations)
            {
                var data = productAttributeCombination.SingleOrDefault(p => p.Id == item.Id);
                if (data == null)
                {
                    removeProductAttributeCombinations.Add(item);
                }
            }


            if (productAttributeCombination.Count > 0)
            {
                var skuPrices = new List<ProductSKUPricesModel>();
                foreach (var item in productAttributeCombination)
                {
                    var prices = new ProductSKUPricesModel()
                    {
                        Id = item.Id,
                        MarketPrice = item.MarketPrice,
                        Price = item.Price
                    };
                    skuPrices.Add(prices);
                }
                var stockQuantity = productAttributeCombination.Where(p => !p.Enabled).Sum(p => p.StockQuantity);
                product.SkuPrices = skuPrices.ToJson();
                product.StockQuantity = stockQuantity;
            }



            using (var transaction = _dbContext.Database.BeginTransaction())
            {
                try
                {
                    _dbContext.Products.Update(product);

                    foreach (var item in productAttributeRelations)
                    {
                        var data = originalProductAttributeRelasions.SingleOrDefault(p => p.Id == item.Id);
                        if (data == null)
                        {
                            _dbContext.ProductAttributeRelations.Add(item);
                        }
                        else
                        {
                            data.Image = item.Image;
                            data.DisplayOrder = item.DisplayOrder;
                            _dbContext.ProductAttributeRelations.Update(data);
                        }
                    }

                    if (removeProductAttributeRelations.Count > 0)
                    {
                        _dbContext.ProductAttributeRelations.RemoveRange(removeProductAttributeRelations);
                    }

                    foreach (var item in productProductAttributeValues)
                    {
                        var data = originalProductAttributeValues.SingleOrDefault(p => p.Id == item.Id);
                        if (data == null)
                        {
                            _dbContext.ProductAttributeValues.Add(item);
                        }
                        else
                        {
                            data.Image = item.Image;
                            data.Name = item.Name;
                            data.Weight = item.Weight;
                            data.DisplayOrder = item.DisplayOrder;
                            _dbContext.ProductAttributeValues.Update(data);
                        }
                    }

                    if (removeProductAttributeValues.Count > 0)
                    {
                        _dbContext.RemoveRange(removeProductAttributeValues);
                    }

                    foreach (var item in productAttributeCombination)
                    {
                        var data = originalProductAttributeCombinations.SingleOrDefault(p => p.Id == item.Id);
                        if (data == null)
                        {
                            _dbContext.ProductAttributeCombinations.Add(item);
                        }
                        else
                        {
                            data.Enabled = item.Enabled;
                            data.MarketPrice = item.MarketPrice;
                            data.Price = item.Price;
                            data.AttributesJson = item.AttributesJson;
                            data.SalesQuantity = item.SalesQuantity;
                            data.SkuNumber = item.SkuNumber;
                            data.StockQuantity = item.StockQuantity;
                            data.UpdateTime = DateTime.UtcNow;
                            data.Weight = item.Weight;


                            _dbContext.ProductAttributeCombinations.Update(data);
                        }
                    }

                    if (removeProductAttributeCombinations.Count > 0)
                    {
                        _dbContext.RemoveRange(removeProductAttributeCombinations);
                    }

                    _dbContext.SaveChanges();
                    transaction.Commit();

                }
                catch (Exception ex)
                {
                    transaction.Rollback();
                    result.Success = false;
                    result.Message = ex.Message;
                    return new JsonResult(result);
                }

            }
            //await _cacheService.GetProductDetails(model.Id, true);

            return new JsonResult(result);
        }

        /// <summary>
        /// 删除指定ID的数据
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpPost("delete/{id:long}")]
        public IActionResult Delete(long id)
        {
            var result = new ApiResult<string>();

            Console.WriteLine($"{id} deleted");
            #region
            var skuCombinations = _dbContext.ProductAttributeCombinations.Where(p => p.ProductId == id).ToList();
            var saleAttribute = _dbContext.ProductAttributeRelations.Where(p => p.ProductId == id).ToList();
            var saleAttributeValues = _dbContext.ProductAttributeValues.Where(p => p.ProductId == id).ToList();
            var product = _dbContext.Products.SingleOrDefault(p => p.Id == id);
            var localiztion = _dbContext.LocalizedProperties.Where(p => p.EntityId == id).ToList();

            var attributeRelate = _dbContext.ProductAttributeRelations.Where(p => p.ProductId == id).ToList();

            List<long> attributeIds = new List<long>();
            List<long> attributeValueIds = new List<long>();
            if (attributeRelate != null && attributeRelate.Count > 0)
            {
                attributeIds = attributeRelate.Select(p => p.AttributeId).ToList();
            }
            if (saleAttributeValues != null && saleAttributeValues.Count > 0)
            {
                attributeValueIds = saleAttributeValues.Select(p => p.OptionId).ToList();
            }

            var skuAttributes = _dbContext.ProductAttributes.Where(p => attributeIds.Contains(p.Id)).ToList();
            var skuAttributeValues = _dbContext.ProductAttributeOptions.Where(p => attributeValueIds.Contains(p.Id)).ToList();

            using (var transaction = _dbContext.Database.BeginTransaction())
            {
                try
                {
                    foreach (var item in skuAttributes)
                    {
                        item.Count = item.Count - 1;
                    }
                    foreach (var item in skuAttributeValues)
                    {
                        item.Count = item.Count - 1;
                    }
                    if (skuCombinations != null)
                    {
                        _dbContext.RemoveRange(skuCombinations);
                    }
                    if (saleAttributeValues != null)
                    {
                        _dbContext.RemoveRange(saleAttributeValues);
                    }
                    if (saleAttribute != null)
                    {
                        _dbContext.RemoveRange(saleAttribute);
                    }
                    if (product != null)
                    {
                        _dbContext.Remove(product);
                    }
                    if (skuAttributes != null)
                    {
                        _dbContext.UpdateRange(skuAttributes);
                    }
                    if (skuAttributeValues != null)
                    {
                        _dbContext.UpdateRange(skuAttributeValues);
                    }
                    if (localiztion.Any())
                    {
                        _dbContext.RemoveRange(localiztion);
                    }

                    var count = _dbContext.SaveChanges();

                    transaction.Commit();

                    //_cacheService.RemoveProduct(id);
                    result = result.IsSuccess(count.ToString());
                    return new JsonResult(result);
                }
                catch (Exception ex)
                {
                    transaction.Rollback();
                    result = result.IsFail(ex.Message);
                    return new JsonResult(result);
                }
            }
            #endregion
        }

        /// <summary>
        /// 获取商品的规格信息
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpPost("attributes/{id:long}")]
        public IActionResult GetAttributes(long id)
        {
            var result = new ApiResult<List<ProductStockAttributeModel>>();

            var data = new List<ProductStockAttributeModel>();

            var relations = _dbContext.ProductAttributeRelations.Where(p => p.ProductId == id).ToList();
            List<long> attributeIds = relations.Select(p => p.AttributeId).ToList();
            var attributes = _dbContext.ProductAttributes.Where(p => attributeIds.Contains(p.Id)).ToList();
            var attributeValues = _dbContext.ProductAttributeValues.Where(p => p.ProductId == id).ToList();

            foreach (var attribute in attributes)
            {
                var saleAttribute = _mapper.Map<ProductStockAttributeModel>(attribute);
                saleAttribute.AttributeId = attribute.Id;
                var relationIds = relations.Where(p => p.AttributeId == attribute.Id).Select(p => p.Id).ToList();
                var values = attributeValues.Where(p => relationIds.Contains(p.ProductAttributeRelationId)).ToList();

                saleAttribute.ProductAttributeValues = _mapper.Map<List<ProductAttributeValueModel>>(values);
                data.Add(saleAttribute);
            }

            result = result.IsSuccess(data);

            return new JsonResult(result);
        }

        /// <summary>
        /// 添加库存
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        [HttpPost("stock/add")]
        public IActionResult AddStock(ProductAddStockModel model)
        {
            var result = new ApiResult<string>();
            var product = _dbContext.Products.SingleOrDefault(p => p.Id == model.ProductId);
            if (product == null)
            {
                result = result.IsFail("参数错误，产品数据不存在");
                return new JsonResult(result);
            }
            _logger.LogInformation(model.ToJson());
            Console.WriteLine(model.ToJson());
            ProductAttributeCombination productAttributeCombination = null;
            List<ProductAttributeValue> productAttributeValueList = new List<ProductAttributeValue>();
            List<ProductSkuModel> productSkus = new List<ProductSkuModel>();
            List<ProductAttributeRelation> productAttributeRelations = _dbContext.ProductAttributeRelations.Where(p => p.ProductId == product.Id).ToList();
            ProductSkuModel? weightModel = null;
            if (model.AddAttribute)
            {
                foreach (var item in model.ProductStockAttributes)
                {
                    var relation = productAttributeRelations.SingleOrDefault(p => p.AttributeId == item.AttributeId);
                    var attributeValue = new ProductAttributeValue()
                    {
                        Id = _idCreator.NewId(),
                        Name = item.AttributeValue.Name,
                        OptionId = item.AttributeValue.OptionId,
                        ProductAttributeRelationId = relation.Id,
                        ProductId = model.ProductId,
                        Image = item.AttributeValue.Image,
                        Weight = item.AttributeValue.Weight,
                        WeightUnit = item.AttributeValue.WeightUnit,
                        IsAddWeight = item.AttributeValue.IsAddWeight
                    };

                    productAttributeValueList.Add(attributeValue);
                    var sku = new ProductSkuModel() { AttributeId = item.AttributeId, AttributeName = item.Name, ValueId = attributeValue.Id, ValueName = attributeValue.Name, Weight = attributeValue.Weight.RemoveTrailingZeros().ToDecimal(), WeightUnit = attributeValue.WeightUnit };
                    if (sku.Weight > 0)
                    {
                        weightModel = sku;
                    }
                    productSkus.Add(sku);

                }

                productAttributeCombination = new ProductAttributeCombination()
                {
                    Id = _idCreator.NewId(),
                    ProductId = model.ProductId,
                    AttributesJson = productSkus.ToJson(),
                    Enabled = true,
                    MarketPrice = model.ProductAttributeCombination.MarketPrice,
                    Price = model.ProductAttributeCombination.Price,
                    SalesQuantity = 0,
                    SkuNumber = model.ProductAttributeCombination.SkuNumber,
                    StockQuantity = model.AddStockQuantity,
                    Weight = weightModel?.Weight.RemoveTrailingZeros().ToDecimal() ?? 0,
                    WeightUnit = weightModel?.WeightUnit ?? 0,
                    ManufacturerId = model.ProductAttributeCombination.ManufacturerId,
                    ProcessCharge = model.ProductAttributeCombination.ProcessCharge,
                    ProcessCost = model.ProductAttributeCombination.ProcessCost,
                    Surcharge = model.ProductAttributeCombination.Surcharge,
                    SurchargeCost = model.ProductAttributeCombination.SurchargeCost,
                    CorporationId = model.CorporationId,
                    UpdateTime = DateTime.UtcNow
                };


                var productWarehouseInventory = new ProductInventory()
                {
                    Id = _idCreator.NewId(),
                    ProductId = model.ProductId,
                    ProductAttributeCombinationId = productAttributeCombination.Id,
                    WarehouseId = model.WarehouseId.ToLong(),
                    StockQuantity = model.AddStockQuantity,
                    CorporationId = model.CorporationId,
                    CreateTime = DateTime.UtcNow,
                    UpdateTime = DateTime.UtcNow
                };

                product.StockQuantity += model.AddStockQuantity;

                using (var transaction = _dbContext.Database.BeginTransaction())
                {
                    try
                    {
                        _dbContext.ProductAttributeValues.AddRange(productAttributeValueList);
                        _dbContext.ProductInventories.Add(productWarehouseInventory);
                        _dbContext.ProductAttributeCombinations.Add(productAttributeCombination);
                        _dbContext.Products.Update(product);
                        _dbContext.SaveChanges();
                        transaction.Commit();
                        result.Success = true;

                    }
                    catch (Exception ex)
                    {
                        transaction.Rollback();
                        result.Success = false;
                        result.Message = ex.Message;
                        return new JsonResult(result);
                    }

                }
            }
            else
            {
                foreach (var item in model.ProductStockAttributes)
                {
                    var value = item.ProductAttributeValues.Where(p => p.Id == item.AttributeValue.OptionId).SingleOrDefault();
                    var attributeValue = new ProductAttributeValue()
                    {
                        Id = _idCreator.NewId(),
                        Name = value.Name,
                        OptionId = item.AttributeValue.OptionId,
                        ProductAttributeRelationId = item.AttributeValue.ProductAttributeRelationId,
                        ProductId = model.ProductId,
                        Image = item.AttributeValue.Image,
                        Weight = value.Weight,
                        WeightUnit = item.WeightUnit,
                        IsAddWeight = item.AttributeValue.IsAddWeight
                    };
                    productSkus.Add(new() { AttributeId = item.AttributeId, AttributeName = item.Name, ValueId = item.AttributeValue.OptionId, ValueName = value.Name, Weight = value.Weight.RemoveTrailingZeros().ToDecimal(), WeightUnit = item.WeightUnit });
                }
                var json = productSkus.ToJson();
                Console.WriteLine($"json: {json}");
                productAttributeCombination = _dbContext.ProductAttributeCombinations.SingleOrDefault(p => p.ProductId == model.ProductId && p.AttributesJson == json);
                bool addNewSku = false;
                if (productAttributeCombination == null)
                {
                    result = result.IsFail("参数错误，产品SKU数据不存在");
                    return new JsonResult(result);
                }
                else
                {
                    productAttributeCombination.StockQuantity += model.AddStockQuantity;
                    productAttributeCombination.UpdateTime = DateTime.UtcNow;
                }

                var productWarehouseInventory = _dbContext.ProductInventories.SingleOrDefault(p => p.ProductId == model.ProductId && p.ProductAttributeCombinationId == model.Id && p.WarehouseId == model.WarehouseId.ToLong());
                bool newWarehouseInventory = false;
                if (productWarehouseInventory == null)
                {
                    productWarehouseInventory = new ProductInventory()
                    {
                        Id = _idCreator.NewId(),
                        ProductId = model.ProductId,
                        ProductAttributeCombinationId = model.Id,
                        WarehouseId = model.WarehouseId.ToLong(),
                        StockQuantity = model.AddStockQuantity,
                        CorporationId = model.CorporationId,
                        CreateTime = DateTime.UtcNow,
                        UpdateTime = DateTime.UtcNow
                    };
                    newWarehouseInventory = true;
                }
                else
                {
                    productWarehouseInventory.StockQuantity += model.AddStockQuantity;
                }
                product.StockQuantity += model.AddStockQuantity;

                using (var transaction = _dbContext.Database.BeginTransaction())
                {
                    try
                    {
                        if (newWarehouseInventory)
                        {
                            _dbContext.ProductInventories.Add(productWarehouseInventory);
                        }
                        else
                        {
                            _dbContext.ProductInventories.Update(productWarehouseInventory);
                        }

                        if (addNewSku)
                        {
                            _dbContext.ProductAttributeCombinations.Add(productAttributeCombination);
                        }
                        else
                        {
                            _dbContext.ProductAttributeCombinations.Update(productAttributeCombination);
                        }

                        _dbContext.Products.Update(product);
                        _dbContext.SaveChanges();
                        transaction.Commit();
                        result.Success = true;

                    }
                    catch (Exception ex)
                    {
                        transaction.Rollback();
                        result.Success = false;
                        result.Message = ex.Message;
                        return new JsonResult(result);
                    }

                }
            }




            return new JsonResult(result);

        }

        /// <summary>
        /// 添加库存
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        [HttpPost("skustock/add")]
        public IActionResult AddSkuStock(ProductStockModel model)
        {
            var result = new ApiResult<string>();

            var productSku = _dbContext.ProductAttributeCombinations.SingleOrDefault(p => p.Id == model.Id && p.ProductId == model.ProductId);
            if (productSku == null)
            {
                result = result.IsFail("参数错误，产品SKU数据不存在");
                return new JsonResult(result);
            }
            var product = _dbContext.Products.SingleOrDefault(p => p.Id == model.ProductId);
            if (product == null)
            {
                result = result.IsFail("参数错误，产品数据不存在");
                return new JsonResult(result);
            }
            var productWarehouseInventory = _dbContext.ProductInventories.SingleOrDefault(p => p.ProductId == model.ProductId && p.ProductAttributeCombinationId == model.Id && p.WarehouseId == model.WarehouseId);
            bool newWarehouseInventory = false;
            if (productWarehouseInventory == null)
            {
                productWarehouseInventory = new ProductInventory()
                {
                    Id = _idCreator.NewId(),
                    ProductId = model.ProductId,
                    ProductAttributeCombinationId = model.Id,
                    WarehouseId = model.WarehouseId,
                    StockQuantity = model.AddStockQuantity,
                    CorporationId = model.CorporationId,
                    CreateTime = DateTime.UtcNow,
                    UpdateTime = DateTime.UtcNow
                };
                newWarehouseInventory = true;

               
            }
            else
            {
                productWarehouseInventory.StockQuantity += model.AddStockQuantity;
            }
            productSku.StockQuantity += model.AddStockQuantity;
            productSku.UpdateTime = DateTime.UtcNow;
            product.StockQuantity += model.AddStockQuantity;
            product.UpdateTime = DateTime.UtcNow;

            using (var transaction = _dbContext.Database.BeginTransaction())
            {
                try
                {
                    if (newWarehouseInventory)
                    {
                        _dbContext.ProductInventories.Add(productWarehouseInventory);
                    }
                    else
                    {
                        _dbContext.ProductInventories.Update(productWarehouseInventory);
                    }
                    _dbContext.Products.Update(product);
                    _dbContext.ProductAttributeCombinations.Update(productSku);
                    _dbContext.SaveChanges();
                    transaction.Commit();
                    result.Success = true;

                }
                catch (Exception ex)
                {
                    transaction.Rollback();
                    result.Success = false;
                    result.Message = ex.Message;
                    return new JsonResult(result);
                }

            }

            return new JsonResult(result);

        }
    }
}


public class MiniProductModel
{
    /// <summary>
    /// 产品ID
    /// </summary>
    public long Id { get; set; }

    /// <summary>
    /// 产品名称
    /// </summary>
    public string Title { get; set; } = string.Empty;

    /// <summary>
    /// 封面图片
    /// </summary>
    public string? Image { get; set; } = string.Empty;
}