using Lada.Framework.Data.Enums;
using Lada.Framework.DTO.Models.Media;
using Lada.Framework.DTO.Results.Media;
using Microsoft.AspNetCore.Http;

namespace Lada.Framework.Infrastructures.Services
{
    /// <summary>
    /// Unified Media Service - Thay thế cho PictureService và MediaService
    /// Kết hợp tất cả ưu điểm của cả hai service cũ
    /// </summary>
    public interface IUnifiedMediaService
    {
        #region Image Processing

        /// <summary>
        /// Xử lý ảnh đơn giản (thay thế PictureService.UploadPicture)
        /// </summary>
        /// <param name="file">File ảnh</param>
        /// <param name="imageType">Loại ảnh</param>
        /// <returns>Kết quả với URL</returns>
        Task<ImageProcessResult> ProcessImageAsync(IFormFile file, ImageType imageType);

        /// <summary>
        /// Xử lý ảnh với lưu database (thay thế MediaService image functions)
        /// </summary>
        /// <param name="file">File ảnh</param>
        /// <param name="options">Tùy chọn lưu</param>
        /// <returns>Kết quả với metadata</returns>
        Task<ImageProcessResult> ProcessImageWithDatabaseAsync(IFormFile file, ImageSaveOptions options);

        /// <summary>
        /// Xử lý nhiều ảnh cùng lúc
        /// </summary>
        /// <param name="files">Danh sách file ảnh</param>
        /// <param name="imageType">Loại ảnh</param>
        /// <returns>Danh sách kết quả</returns>
        Task<List<ImageProcessResult>> ProcessMultipleImagesAsync(List<IFormFile> files, ImageType imageType);

        #endregion

        #region Video Processing

        /// <summary>
        /// Xử lý video đơn giản
        /// </summary>
        /// <param name="file">File video</param>
        /// <param name="videoType">Loại video</param>
        /// <returns>Kết quả với URL</returns>
        Task<VideoProcessResult> ProcessVideoAsync(IFormFile file, VideoType videoType);

        /// <summary>
        /// Xử lý video với lưu database
        /// </summary>
        /// <param name="file">File video</param>
        /// <param name="options">Tùy chọn lưu</param>
        /// <returns>Kết quả với metadata</returns>
        Task<VideoProcessResult> ProcessVideoWithDatabaseAsync(IFormFile file, VideoSaveOptions options);

        /// <summary>
        /// Xử lý nhiều video cùng lúc
        /// </summary>
        /// <param name="files">Danh sách file video</param>
        /// <param name="videoType">Loại video</param>
        /// <returns>Danh sách kết quả</returns>
        Task<List<VideoProcessResult>> ProcessMultipleVideosAsync(List<IFormFile> files, VideoType videoType);

        #endregion

        #region Validation

        /// <summary>
        /// Validate file có phải ảnh hợp lệ không
        /// </summary>
        /// <param name="file">File cần kiểm tra</param>
        /// <returns>True nếu hợp lệ</returns>
        Task<bool> ValidateImageAsync(IFormFile file);

        /// <summary>
        /// Validate file có phải video hợp lệ không
        /// </summary>
        /// <param name="file">File cần kiểm tra</param>
        /// <returns>True nếu hợp lệ</returns>
        Task<bool> ValidateVideoAsync(IFormFile file);

        /// <summary>
        /// Tự động detect loại file và validate
        /// </summary>
        /// <param name="file">File cần kiểm tra</param>
        /// <returns>MediaType nếu hợp lệ, null nếu không</returns>
        Task<MediaType?> DetectAndValidateMediaTypeAsync(IFormFile file);

        #endregion

        #region URL Management

        /// <summary>
        /// Chuyển đổi SystemPath thành URL hiển thị
        /// </summary>
        /// <param name="systemPath">Đường dẫn hệ thống</param>
        /// <returns>URL hiển thị</returns>
        Task<string> GetUrlBySystemPathAsync(string systemPath);

        /// <summary>
        /// Chuyển đổi nhiều SystemPath thành URL
        /// </summary>
        /// <param name="systemPaths">Danh sách đường dẫn</param>
        /// <returns>Danh sách URL</returns>
        Task<List<string>> GetUrlsBySystemPathsAsync(List<string> systemPaths);

        #endregion

        #region Legacy Support (Backward Compatibility)

        /// <summary>
        /// Upload ảnh (tương thích với PictureService.UploadPicture)
        /// </summary>
        /// <param name="file">File ảnh</param>
        /// <param name="picType">Loại ảnh (legacy)</param>
        /// <returns>Kết quả upload</returns>
        Task<UploadPictureResult> UploadPictureAsync(IFormFile file, string picType);

        /// <summary>
        /// Upload media (tương thích với MediaService)
        /// </summary>
        /// <param name="file">File media</param>
        /// <returns>Kết quả upload</returns>
        Task<UploadMediaResult> UploadMediaAsync(IFormFile file);

        /// <summary>
        /// Lưu media cho order tracking (pickup/delivery)
        /// </summary>
        /// <param name="files">Danh sách file media</param>
        /// <param name="orderTrackId">ID của order track</param>
        /// <param name="orderId">ID của order</param>
        /// <param name="orderCode">Mã đơn hàng</param>
        /// <param name="createdBy">ID người tạo</param>
        /// <param name="createdByUserName">Tên người tạo</param>
        /// <returns>Danh sách kết quả lưu media</returns>
        Task<List<ImageProcessResult>> SaveOrderTrackMediaAsync(List<IFormFile> files, Guid orderTrackId, int orderId, string orderCode, int createdBy, string createdByUserName);

        #endregion
    }

    public class UnifiedMediaService : IUnifiedMediaService
    {
        private readonly IImageService _imageService;
        private readonly IVideoService _videoService;

        public UnifiedMediaService(IImageService imageService, IVideoService videoService)
        {
            _imageService = imageService;
            _videoService = videoService;
        }

        #region Image Processing

        public async Task<ImageProcessResult> ProcessImageAsync(IFormFile file, ImageType imageType)
        {
            return await _imageService.ProcessImageAsync(file, imageType);
        }

        public async Task<ImageProcessResult> ProcessImageWithDatabaseAsync(IFormFile file, ImageSaveOptions options)
        {
            return await _imageService.ProcessAndSaveAsync(file, options);
        }

        public async Task<List<ImageProcessResult>> ProcessMultipleImagesAsync(List<IFormFile> files, ImageType imageType)
        {
            return await _imageService.ProcessMultipleAsync(files, imageType);
        }

        #endregion

        #region Video Processing

        public async Task<VideoProcessResult> ProcessVideoAsync(IFormFile file, VideoType videoType)
        {
            return await _videoService.ProcessVideoAsync(file, videoType);
        }

        public async Task<VideoProcessResult> ProcessVideoWithDatabaseAsync(IFormFile file, VideoSaveOptions options)
        {
            return await _videoService.ProcessAndSaveAsync(file, options);
        }

        public async Task<List<VideoProcessResult>> ProcessMultipleVideosAsync(List<IFormFile> files, VideoType videoType)
        {
            return await _videoService.ProcessMultipleAsync(files, videoType);
        }

        #endregion

        #region Validation

        public async Task<bool> ValidateImageAsync(IFormFile file)
        {
            return await _imageService.ValidateImageAsync(file);
        }

        public async Task<bool> ValidateVideoAsync(IFormFile file)
        {
            return await _videoService.ValidateVideoAsync(file);
        }

        public async Task<MediaType?> DetectAndValidateMediaTypeAsync(IFormFile file)
        {
            if (file == null || file.Length == 0)
                return null;

            // Kiểm tra ảnh trước
            if (await ValidateImageAsync(file))
                return MediaType.Image;

            // Kiểm tra video
            if (await ValidateVideoAsync(file))
                return MediaType.Video;

            return null;
        }

        #endregion

        #region URL Management

        public async Task<string> GetUrlBySystemPathAsync(string systemPath)
        {
            // Sử dụng ImageService để convert URL (logic giống nhau)
            return await _imageService.GetUrlBySystemPath(systemPath);
        }

        public async Task<List<string>> GetUrlsBySystemPathsAsync(List<string> systemPaths)
        {
            var urls = new List<string>();

            if (systemPaths != null && systemPaths.Any())
            {
                foreach (var path in systemPaths)
                {
                    var url = await GetUrlBySystemPathAsync(path);
                    urls.Add(url);
                }
            }

            return urls;
        }

        #endregion

        #region Legacy Support (Backward Compatibility)

        public async Task<UploadPictureResult> UploadPictureAsync(IFormFile file, string picType)
        {
            try
            {
                // Convert legacy picType to ImageType
                var imageType = ConvertLegacyPicTypeToImageType(picType);

                // Process using new ImageService
                var result = await _imageService.ProcessImageAsync(file, imageType);

                // Convert to legacy result format
                return new UploadPictureResult
                {
                    Result = result.Result,
                    Message = result.Message,
                    Url = result.Url
                };
            }
            catch (Exception ex)
            {
                return new UploadPictureResult
                {
                    Result = Lada.Framework.DTO.Result.SystemError,
                    Message = $"Lỗi upload ảnh: {ex.Message}",
                    Url = string.Empty
                };
            }
        }

        public async Task<UploadMediaResult> UploadMediaAsync(IFormFile file)
        {
            try
            {
                // Detect media type
                var mediaType = await DetectAndValidateMediaTypeAsync(file);

                if (mediaType == null)
                {
                    return new UploadMediaResult
                    {
                        Result = Lada.Framework.DTO.Result.Failed,
                        Message = "File không phải là media hợp lệ",
                        Url = string.Empty
                    };
                }

                string url;
                if (mediaType == MediaType.Image)
                {
                    var result = await _imageService.ProcessImageAsync(file, ImageType.General);
                    url = result.Url;
                }
                else
                {
                    var result = await _videoService.ProcessVideoAsync(file, VideoType.General);
                    url = result.Url;
                }

                return new UploadMediaResult
                {
                    Result = Lada.Framework.DTO.Result.Success,
                    Message = "Upload thành công",
                    Url = url
                };
            }
            catch (Exception ex)
            {
                return new UploadMediaResult
                {
                    Result = Lada.Framework.DTO.Result.SystemError,
                    Message = $"Lỗi upload media: {ex.Message}",
                    Url = string.Empty
                };
            }
        }

        #endregion

        #region Private Methods

        private ImageType ConvertLegacyPicTypeToImageType(string picType)
        {
            return picType?.ToLower() switch
            {
                "avatar" => ImageType.Avatar,
                "product" => ImageType.Product,
                "post" => ImageType.Post,
                "attendance" => ImageType.Attendance,
                "truck" or "truckactivity" => ImageType.TruckActivity,
                "order" => ImageType.Order,
                "ordertrack" => ImageType.OrderTrack,
                "package" => ImageType.Package,
                "maintenance" => ImageType.Maintenance,
                "document" => ImageType.Document,
                _ => ImageType.General
            };
        }

        public async Task<List<ImageProcessResult>> SaveOrderTrackMediaAsync(List<IFormFile> files, Guid orderTrackId, int orderId, string orderCode, int createdBy, string createdByUserName)
        {
            var results = new List<ImageProcessResult>();

            if (files != null && files.Any())
            {
                foreach (var file in files)
                {
                    try
                    {
                        // Xử lý ảnh với metadata cho order tracking
                        var options = new ImageSaveOptions
                        {
                            ImageType = ImageType.OrderTrack,
                            SaveToDatabase = true,
                            AltText = $"Ảnh đơn hàng {orderCode}",
                            Caption = $"Ảnh tracking đơn hàng {orderCode}",
                            CreatedBy = createdBy,
                            CreatedByUserName = createdByUserName,
                            UpdatedBy = createdBy,
                            UpdatedByUserName = createdByUserName,
                            OrderId = orderId,
                            OrderTrackId = orderTrackId,
                            DisplayOrder = results.Count + 1
                        };

                        var result = await _imageService.ProcessAndSaveAsync(file, options);
                        results.Add(result);
                    }
                    catch (Exception ex)
                    {
                        // Thêm kết quả lỗi cho file này
                        results.Add(new ImageProcessResult
                        {
                            Result = Lada.Framework.DTO.Result.SystemError,
                            Message = $"Lỗi xử lý file {file.FileName}: {ex.Message}",
                            Url = string.Empty,
                            SystemPath = string.Empty
                        });
                    }
                }
            }

            return results;
        }

        #endregion
    }

    /// <summary>
    /// Enum để phân biệt loại media
    /// </summary>
    public enum MediaType
    {
        Image = 1,
        Video = 2
    }
}
