using Microsoft.Extensions.Logging;
using QYZH.InteractiveMagazine.Common.Extensions;
using QYZH.InteractiveMagazine.Models.Common;
using QYZH.InteractiveMagazine.Models.Dto;

namespace QYZH.InteractiveMagazine.Infrastructure.OSS;

/// <summary>
/// OSS 图片搬运辅助类
/// 负责将 temp 临时目录下的文件搬运到正式目录
/// </summary>
public class OssImageHelper
{
    private readonly OssService _ossService;
    private readonly ILogger _logger;

    public OssImageHelper(OssService ossService, ILogger logger)
    {
        _ossService = ossService;
        _logger = logger;
    }

    /// <summary>
    /// 判断图片是否在 temp 临时目录
    /// </summary>
    public static bool IsTempImage(string? imageUrl)
    {
        if (string.IsNullOrWhiteSpace(imageUrl)) return false;
        return imageUrl.Contains("/temp/", StringComparison.OrdinalIgnoreCase);
    }

    /// <summary>
    /// 将 temp 目录下的图片搬运到正式目录，返回正式路径
    /// 如果图片不在 temp 目录，原样返回
    /// </summary>
    /// <param name="imageUrl">原始图片 URL（可能是完整 URL 或相对路径）</param>
    /// <param name="formalFolder">正式目录前缀，如 "product/makeupcard/123" 或 "pet/skin/456"</param>
    /// <returns>正式路径（相对路径），搬运失败时抛出异常</returns>
    public async Task<string> MoveToFormalAsync(string imageUrl, string formalFolder)
    {
        if (!IsTempImage(imageUrl))
            return imageUrl;

        // 提取 OSS 相对路径（去掉域名前缀）
        var sourcePath = imageUrl.RemoveDomain();
        if (string.IsNullOrWhiteSpace(sourcePath))
        {
            _logger.LogWarning("图片路径解析失败，ImageUrl: {ImageUrl}", imageUrl);
            return imageUrl;
        }

        // URL 解码（处理中文文件名）
        sourcePath = Uri.UnescapeDataString(sourcePath);

        // 提取文件名
        var fileName = Path.GetFileName(sourcePath);
        if (string.IsNullOrWhiteSpace(fileName))
        {
            _logger.LogWarning("无法从路径中提取文件名，Path: {Path}", sourcePath);
            return imageUrl;
        }

        // 生成正式路径
        var targetPath = $"{formalFolder}/{fileName}";

        _logger.LogInformation("开始搬运图片，Source: {Source} -> Target: {Target}", sourcePath, targetPath);

        try
        {
            // 拷贝文件到正式目录
            var copyResult = _ossService.CopyObject(sourcePath, targetPath);
            if (!copyResult)
            {
                _logger.LogError("OSS 图片拷贝失败，Source: {Source}, Target: {Target}", sourcePath, targetPath);
                throw new Exception("OSS 图片拷贝失败");
            }

            // 删除临时文件（失败不影响主流程）
            var deleteResult = _ossService.DeleteObject(sourcePath);
            if (!deleteResult)
            {
                _logger.LogWarning("OSS 临时文件删除失败（不影响主流程），Source: {Source}", sourcePath);
            }

            _logger.LogInformation("图片搬运成功，Target: {Target}", targetPath);
            return targetPath;
        }
        catch (Exception ex) when (ex is not BusinessException)
        {
            _logger.LogError(ex, "OSS 图片搬运异常，Source: {Source}, Target: {Target}", sourcePath, targetPath);
            throw new BusinessException("图片搬运失败，请重试", ResultCode.GLOBAL_ERROR);
        }
    }

    /// <summary>
    /// 批量搬运 temp 图片到正式目录
    /// </summary>
    /// <param name="imageUrls">原始图片 URL 列表</param>
    /// <param name="formalFolder">正式目录前缀</param>
    /// <returns>正式路径列表（顺序与输入一致）</returns>
    public async Task<List<string>> MoveBatchToFormalAsync(IEnumerable<string> imageUrls, string formalFolder)
    {
        var results = new List<string>();
        foreach (var url in imageUrls)
        {
            var formal = await MoveToFormalAsync(url, formalFolder);
            results.Add(formal);
        }
        return results;
    }
}
