using DramaLing.Api.Models.Configuration;
using Microsoft.Extensions.Options;

namespace DramaLing.Api.Services.Storage;

public class LocalImageStorageService : IImageStorageService
{
    private readonly string _basePath;
    private readonly string _baseUrl;
    private readonly ILogger<LocalImageStorageService> _logger;

    public LocalImageStorageService(
        IConfiguration configuration,
        ILogger<LocalImageStorageService> logger)
    {
        _logger = logger ?? throw new ArgumentNullException(nameof(logger));

        _basePath = configuration["ImageStorage:Local:BasePath"] ?? "wwwroot/images/examples";
        _baseUrl = configuration["ImageStorage:Local:BaseUrl"] ?? "https://localhost:5008/images/examples";

        // 確保目錄存在
        var fullPath = Path.GetFullPath(_basePath);
        if (!Directory.Exists(fullPath))
        {
            Directory.CreateDirectory(fullPath);
            _logger.LogInformation("Created image storage directory: {Path}", fullPath);
        }
    }

    public async Task<string> SaveImageAsync(Stream imageStream, string fileName)
    {
        try
        {
            var fullPath = Path.Combine(_basePath, fileName);
            var directory = Path.GetDirectoryName(fullPath);

            if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory))
            {
                Directory.CreateDirectory(directory);
            }

            using var fileStream = new FileStream(fullPath, FileMode.Create);
            await imageStream.CopyToAsync(fileStream);

            _logger.LogInformation("Image saved to {Path}", fullPath);

            return fileName; // 回傳相對路徑
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to save image {FileName}", fileName);
            throw;
        }
    }

    public Task<string> GetImageUrlAsync(string imagePath)
    {
        var imageUrl = $"{_baseUrl.TrimEnd('/')}/{imagePath.TrimStart('/')}";
        return Task.FromResult(imageUrl);
    }

    public Task<bool> DeleteImageAsync(string imagePath)
    {
        try
        {
            var fullPath = Path.Combine(_basePath, imagePath);
            if (File.Exists(fullPath))
            {
                File.Delete(fullPath);
                _logger.LogInformation("Image deleted: {Path}", fullPath);
                return Task.FromResult(true);
            }

            return Task.FromResult(false);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to delete image {ImagePath}", imagePath);
            return Task.FromResult(false);
        }
    }

    public Task<bool> ImageExistsAsync(string imagePath)
    {
        var fullPath = Path.Combine(_basePath, imagePath);
        return Task.FromResult(File.Exists(fullPath));
    }

    public Task<StorageInfo> GetStorageInfoAsync()
    {
        try
        {
            var fullPath = Path.GetFullPath(_basePath);
            var directory = new DirectoryInfo(fullPath);

            if (!directory.Exists)
            {
                return Task.FromResult(new StorageInfo
                {
                    Provider = "Local",
                    Status = "Directory not found"
                });
            }

            var files = directory.GetFiles("*", SearchOption.AllDirectories);
            var totalSize = files.Sum(f => f.Length);

            return Task.FromResult(new StorageInfo
            {
                Provider = "Local",
                TotalSizeBytes = totalSize,
                FileCount = files.Length,
                Status = "Available"
            });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to get storage info");
            return Task.FromResult(new StorageInfo
            {
                Provider = "Local",
                Status = $"Error: {ex.Message}"
            });
        }
    }
}