using Microsoft.Extensions.Logging;
using QYZH.InteractiveMagazine.Common.Helpers;
using QYZH.InteractiveMagazine.Infrastructure.OSS;
using QYZH.InteractiveMagazine.IService;
using QYZH.InteractiveMagazine.Models.Common;
using QYZH.InteractiveMagazine.Models.Dto;
using QYZH.InteractiveMagazine.Models.Entity;
using QYZH.InteractiveMagazine.Models.Enum;
using QYZH.InteractiveMagazine.Repository;
using SqlSugar;

namespace QYZH.InteractiveMagazine.Service;

/// <summary>
/// 商品服务实现
/// </summary>
public class ProductService(
    BaseRepository<Product> productRepository,
    OssService ossService,
    ILogger<ProductService> logger) : BaseRepository<Product>, IProductService
{

    /// <summary>
    /// 创建商品
    /// </summary>
    public async Task<ProductOutput> CreateAsync(ProductInput input)
    {
        logger.LogInformation("正在创建商品，商品名称: {Name}", input.Name);

        if (string.IsNullOrWhiteSpace(input.Name))
        {
            throw new BusinessException("商品名称不能为空", ResultCode.BAD_REQUEST);
        }

        if (string.IsNullOrWhiteSpace(input.Type))
        {
            throw new BusinessException("商品类型不能为空", ResultCode.BAD_REQUEST);
        }

        if (input.Price < 0)
        {
            throw new BusinessException("商品价格不能为负数", ResultCode.BAD_REQUEST);
        }

        var product = new Product
        {
            Name = input.Name.Trim(),
            Description = input.Description,
            ImageUrl = input.ImageUrl,
            Price = input.Price,
            Type = Enum.Parse<ProductTypeEnum>(input.Type, true),
            Status = (int)input.Status,
            MetaData = input.MetaData,
            IsActive = input.IsActive,
            Stock = input.Stock,
            IsVirtual = input.IsVirtual,
            TypeId = input.TypeId,
            CreatedBy = "System",
            UpdatedBy = "System",
            CreatedAt = DateTime.Now,
            UpdatedAt = DateTime.Now,
            IsDeleted = false
        };

        var result = await productRepository.InsertAsync(product);
        if (!result)
        {
            logger.LogError("商品创建失败，商品名称: {Name}", input.Name);
            throw new BusinessException("创建商品失败", ResultCode.GLOBAL_ERROR);
        }

        // 将 temp 目录下的图片搬运到正式目录
        if (OssImageHelper.IsTempImage(product.ImageUrl))
        {
            var helper = CreateImageHelper();
            var folder = GetProductFormalFolder(product.Type, product.Id);
            var formalPath = await helper.MoveToFormalAsync(product.ImageUrl, folder);
            product.ImageUrl = formalPath;
            await productRepository.UpdateAsync(product);
        }

        logger.LogInformation("商品创建成功，商品名称: {Name}, ID: {Id}", input.Name, product.Id);

        return new ProductOutput
        {
            Id = product.Id,
            Name = product.Name,
            Description = product.Description,
            ImageUrl = product.ImageUrl,
            Price = product.Price,
            Type = product.Type.ToString(),
            Status = product.Status.ToString(),
            MetaData = product.MetaData,
            IsActive = product.IsActive,
            Stock = product.Stock,
            IsVirtual = product.IsVirtual,
            TypeId = product.TypeId,
            CreatedBy = product.CreatedBy,
            CreatedAt = product.CreatedAt,
            UpdatedBy = product.UpdatedBy,
            UpdatedAt = product.UpdatedAt
        };
    }

    /// <summary>
    /// 更新商品
    /// </summary>
    public async Task<ProductOutput> UpdateAsync(long id, ProductInput input)
    {
        logger.LogInformation("正在更新商品，ID: {Id}", id);

        var product = await productRepository.GetByIdAsync(id);
        if (product == null)
        {
            logger.LogWarning("未找到要更新的商品，ID: {Id}", id);
            throw new BusinessException("商品不存在", ResultCode.NOT_FOUND);
        }

        if (string.IsNullOrWhiteSpace(input.Name))
        {
            throw new BusinessException("商品名称不能为空", ResultCode.BAD_REQUEST);
        }

        if (string.IsNullOrWhiteSpace(input.Type))
        {
            throw new BusinessException("商品类型不能为空", ResultCode.BAD_REQUEST);
        }

        if (input.Price < 0)
        {
            throw new BusinessException("商品价格不能为负数", ResultCode.BAD_REQUEST);
        }

        // 将 temp 目录下的新图片搬运到正式目录
        var newImageUrl = input.ImageUrl;
        if (OssImageHelper.IsTempImage(newImageUrl))
        {
            var helper = CreateImageHelper();
            var folder = GetProductFormalFolder(Enum.Parse<ProductTypeEnum>(input.Type, true), product.Id);
            newImageUrl = await helper.MoveToFormalAsync(newImageUrl, folder);
        }

        product.Name = input.Name.Trim();
        product.Description = input.Description;
        product.ImageUrl = newImageUrl;
        product.Price = input.Price;
        product.Type = Enum.Parse<ProductTypeEnum>(input.Type, true);
        product.Status = (int)input.Status;
        product.MetaData = input.MetaData;
        product.IsActive = input.IsActive;
        product.Stock = input.Stock;
        product.IsVirtual = input.IsVirtual;
        product.TypeId = input.TypeId;
        product.UpdatedBy = "System";
        product.UpdatedAt = DateTime.Now;

        var result = await productRepository.UpdateAsync(product);
        if (!result)
        {
            logger.LogError("商品更新失败，ID: {Id}", id);
            throw new BusinessException("更新商品失败", ResultCode.GLOBAL_ERROR);
        }

        logger.LogInformation("商品更新成功，ID: {Id}", id);

        return new ProductOutput
        {
            Id = product.Id,
            Name = product.Name,
            Description = product.Description,
            ImageUrl = product.ImageUrl,
            Price = product.Price,
            Type = product.Type.ToString(),
            Status = product.Status.ToString(),
            MetaData = product.MetaData,
            IsActive = product.IsActive,
            Stock = product.Stock,
            IsVirtual = product.IsVirtual,
            TypeId = product.TypeId,
            CreatedBy = product.CreatedBy,
            CreatedAt = product.CreatedAt,
            UpdatedBy = product.UpdatedBy,
            UpdatedAt = product.UpdatedAt
        };
    }

    /// <summary>
    /// 删除商品（软删除）
    /// </summary>
    public async Task DeleteAsync(long id)
    {
        logger.LogInformation("正在删除商品，ID: {Id}", id);

        var product = await productRepository.GetByIdAsync(id);
        if (product == null)
        {
            logger.LogWarning("未找到要删除的商品，ID: {Id}", id);
            throw new BusinessException("商品不存在", ResultCode.NOT_FOUND);
        }

        var result = await productRepository.DeleteByIdAsync(id);
        if (!result)
        {
            logger.LogError("商品删除失败，ID: {Id}", id);
            throw new BusinessException("删除商品失败", ResultCode.GLOBAL_ERROR);
        }

        logger.LogInformation("商品删除成功，ID: {Id}", id);
    }

    /// <summary>
    /// 根据ID获取商品
    /// </summary>
    public async Task<ProductOutput> GetByIdAsync(long id)
    {
        logger.LogInformation("正在获取商品信息，ID: {Id}", id);

        var product = await productRepository.GetByIdAsync(id);
        if (product == null)
        {
            logger.LogWarning("未找到商品，ID: {Id}", id);
            throw new BusinessException("商品不存在", ResultCode.NOT_FOUND);
        }

        return new ProductOutput
        {
            Id = product.Id,
            Name = product.Name,
            Description = product.Description,
            ImageUrl = DomainHelper.OssFullUrl(product.ImageUrl),
            Price = product.Price,
            Type = product.Type.ToString(),
            Status = product.Status.ToString(),
            MetaData = product.MetaData,
            IsActive = product.IsActive,
            Stock = product.Stock,
            IsVirtual = product.IsVirtual,
            TypeId = product.TypeId,
            CreatedBy = product.CreatedBy,
            CreatedAt = product.CreatedAt,
            UpdatedBy = product.UpdatedBy,
            UpdatedAt = product.UpdatedAt
        };
    }

    /// <summary>
    /// 分页查询商品列表
    /// </summary>
    public async Task<PageListModel<ProductOutput>> GetListAsync(ProductQueryInput input)
    {
        logger.LogInformation("正在查询商品列表，页码: {PageIndex}, 每页条数: {PageSize}", input.PageIndex, input.PageSize);

        if (input.PageIndex <= 0)
        {
            throw new BusinessException("页码必须大于0", ResultCode.BAD_REQUEST);
        }

        if (input.PageSize <= 0 || input.PageSize > 100)
        {
            throw new BusinessException("每页条数必须在1-100之间", ResultCode.BAD_REQUEST);
        }

        RefAsync<int> totalNumber = 0;
        var pageResult = await productRepository.Queryable()
                .WhereIF(!string.IsNullOrWhiteSpace(input.Name), p => p.Name.Contains(input.Name))
                .WhereIF(!string.IsNullOrWhiteSpace(input.Type), p => p.Type.ToString() == input.Type)
                .WhereIF(input.Status.HasValue, p => p.Status == (int)input.Status)
                .WhereIF(input.IsActive.HasValue, p => p.IsActive == input.IsActive.Value)
                .OrderByDescending(p => p.CreatedAt)
                .ToPageListAsync(input.PageIndex, input.PageSize, totalNumber);

        var result = pageResult.Select(p => new ProductOutput
        {
            Id = p.Id,
            Name = p.Name,
            Description = p.Description,
            ImageUrl = DomainHelper.OssFullUrl(p.ImageUrl),
            Price = p.Price,
            Type = p.Type.ToString(),
            Status = p.Status.ToString(),
            MetaData = p.MetaData,
            IsActive = p.IsActive,
            Stock = p.Stock,
            IsVirtual = p.IsVirtual,
            TypeId = p.TypeId,
            CreatedBy = p.CreatedBy,
            CreatedAt = p.CreatedAt,
            UpdatedBy = p.UpdatedBy,
            UpdatedAt = p.UpdatedAt
        }).ToList();

        return new PageListModel<ProductOutput>(result, input.PageIndex, input.PageSize, totalNumber);
    }

    /// <summary>
    /// 更新商品上架/下架状态（取反）
    /// </summary>
    public async Task UpdateSaleStatusAsync(long id)
    {
        logger.LogInformation("正在更新商品上下架状态，ID: {Id}", id);

        var product = await productRepository.GetByIdAsync(id);
        if (product == null)
        {
            logger.LogWarning("未找到要更新状态的商品，ID: {Id}", id);
            throw new BusinessException("商品不存在", ResultCode.NOT_FOUND);
        }

        product.Status = product.Status == (int)ProductStatusEnum.OnSale
            ? (int)ProductStatusEnum.OffSale
            : (int)ProductStatusEnum.OnSale;
        product.UpdatedBy = "System";
        product.UpdatedAt = DateTime.Now;

        var result = await productRepository.UpdateAsync(product);
        if (!result)
        {
            logger.LogError("商品状态更新失败，ID: {Id}", id);
            throw new BusinessException("更新商品状态失败", ResultCode.GLOBAL_ERROR);
        }

        logger.LogInformation("商品上下架状态更新成功，ID: {Id}, SaleStatus: {SaleStatus}", id, product.Status);
    }

    #region OSS 图片搬运

    private OssImageHelper CreateImageHelper() => new(ossService, logger);

    private static string GetProductFormalFolder(ProductTypeEnum type, long productId)
    {
        var typeFolder = type switch
        {
            ProductTypeEnum.MakeUpCard => "makeupcard",
            ProductTypeEnum.PetSkin => "petskin",
            _ => "other"
        };
        return $"product/{typeFolder}/{productId}";
    }

    #endregion
}
