using Lada.Framework.Data.Enums;
using Lada.Framework.DTO.Results.Media;
using Lada.Framework.Infrastructures.AppSettings;
using Lada.Framework.Infrastructures.Services;
using Lada.Framework.Data.Repositories;

using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;

namespace Ladaer.BackEnd.Infrastructures.Extensions
{
    /// <summary>
    /// Extension methods để cấu hình Media Services
    /// </summary>
    public static class MediaServiceExtensions
    {
        /// <summary>
        /// Đăng ký tất cả Media Services mới (ImageService, VideoService, UnifiedMediaService)
        /// </summary>
        /// <param name="services">Service collection</param>
        /// <param name="configuration">Configuration</param>
        /// <returns>Service collection</returns>
        public static IServiceCollection AddNewMediaServices(this IServiceCollection services, IConfiguration configuration)
        {
            // 1. Cấu hình MediaProcessingSettings từ appsettings.json
            services.Configure<MediaProcessingSettings>(configuration.GetSection("MediaProcessingSettings"));

            // 2. Đăng ký core services với dependency injection
            services.AddScoped<IImageService>(provider =>
            {
                var settings = provider.GetRequiredService<IOptions<MediaProcessingSettings>>();
                var appConfigService = provider.GetService<IAppConfigService>();
                var mediaRepository = provider.GetService<IRepository<Lada.Framework.Data.Domains.Medias.Media>>();
                return new ImageService(settings, appConfigService, mediaRepository);
            });

            services.AddScoped<IVideoService>(provider =>
            {
                var settings = provider.GetRequiredService<IOptions<MediaProcessingSettings>>();
                var appConfigService = provider.GetService<IAppConfigService>();
                var mediaRepository = provider.GetService<IRepository<Lada.Framework.Data.Domains.Medias.Media>>();
                return new VideoService(settings, appConfigService, mediaRepository);
            });

            services.AddScoped<IUnifiedMediaService, UnifiedMediaService>();

            return services;
        }

        /// <summary>
        /// Đăng ký Media Services với backward compatibility
        /// Giữ lại interface cũ nhưng sử dụng implementation mới
        /// </summary>
        /// <param name="services">Service collection</param>
        /// <param name="configuration">Configuration</param>
        /// <returns>Service collection</returns>
        public static IServiceCollection AddMediaServicesWithBackwardCompatibility(this IServiceCollection services, IConfiguration configuration)
        {
            // Đăng ký services mới
            services.AddNewMediaServices(configuration);

            // Đăng ký wrapper cho backward compatibility
            services.AddScoped<IBackwardCompatibleMediaService, BackwardCompatibleMediaService>();

            return services;
        }

        /// <summary>
        /// Migration helper - Thay thế dần dần các service cũ
        /// </summary>
        /// <param name="services">Service collection</param>
        /// <param name="configuration">Configuration</param>
        /// <param name="enableLegacyServices">Có enable legacy services không</param>
        /// <returns>Service collection</returns>
        public static IServiceCollection AddMediaServicesMigration(this IServiceCollection services, IConfiguration configuration, bool enableLegacyServices = true)
        {
            // Luôn đăng ký services mới
            services.AddNewMediaServices(configuration);

            if (enableLegacyServices)
            {
                // Giữ lại legacy services để migration dần dần
                // services.AddScoped<IPictureService, PictureService>(); // Comment out khi ready
                // services.AddScoped<IMediaService, MediaService>(); // Comment out khi ready

                // Thay vào đó, sử dụng wrapper
                services.AddScoped<IBackwardCompatibleMediaService, BackwardCompatibleMediaService>();
            }

            return services;
        }
    }

    /// <summary>
    /// Backward Compatible Media Service - Wrapper cho legacy interfaces
    /// </summary>
    public interface IBackwardCompatibleMediaService
    {
        // Legacy PictureService methods
        Task<UploadPictureResult> UploadPictureAsync(IFormFile file, string picType);

        // Legacy MediaService methods
        Task<UploadMediaResult> UploadMediaAsync(IFormFile file);
        Task<string> GetUrlBySystemPath(string systemPath);
    }

    public class BackwardCompatibleMediaService : IBackwardCompatibleMediaService
    {
        private readonly IUnifiedMediaService _unifiedMediaService;

        public BackwardCompatibleMediaService(IUnifiedMediaService unifiedMediaService)
        {
            _unifiedMediaService = unifiedMediaService;
        }

        public async Task<UploadPictureResult> UploadPictureAsync(IFormFile file, string picType)
        {
            return await _unifiedMediaService.UploadPictureAsync(file, picType);
        }

        public async Task<UploadMediaResult> UploadMediaAsync(IFormFile file)
        {
            return await _unifiedMediaService.UploadMediaAsync(file);
        }

        public async Task<string> GetUrlBySystemPath(string systemPath)
        {
            return await _unifiedMediaService.GetUrlBySystemPathAsync(systemPath);
        }
    }
}

/// <summary>
/// Example appsettings.json configuration
/// </summary>
public class MediaServiceConfigurationExample
{
    /*
    {
      "Media": {
        "RootPath": "C:\\uploads\\",
        "Domain": "https://yourdomain.com/",
        "MaxImageWidth": 1200,
        "ImageQuality": 80,
        "DefaultImageFormat": "WebP",
        "OutputFolder": "optimized",
        "TempPath": "C:\\temp\\",
        "MaxVideoDuration": 300,
        "DefaultVideoResolution": "HD1080",
        "FFmpegPath": "C:\\ffmpeg\\bin\\ffmpeg.exe",
        "AutoSaveToDatabase": false
      },
      "ConnectionStrings": {
        "DefaultConnection": "Server=.;Database=LadaDB;Trusted_Connection=true;"
      }
    }
    */
}
