using System.Drawing;
using Lada.Framework.Data.Domains.Finance;
using Lada.Framework.Data.Domains.Trucks;
using Lada.Framework.Data.Repositories;
using Lada.Framework.DTO;
using Lada.Framework.DTO.SmartTable;
using Lada.Framework.Infrastructures.Services;
using Ladaer.BackEnd.Infrastructures.DTO.Results.FuelCards;
using Microsoft.EntityFrameworkCore;
using OfficeOpenXml;
using OfficeOpenXml.Style;

namespace Ladaer.BackEnd.Infrastructures.Services.FuelCards
{
    /// <summary>
    /// Interface cho dịch vụ xuất Excel lịch sử đổ dầu
    /// </summary>
    public interface IFuelRefillExcelService
    {
        /// <summary>
        /// Xuất Excel lịch sử đổ dầu
        /// </summary>
        /// <param name="param">Tham số tìm kiếm và sắp xếp</param>
        /// <returns>Kết quả xuất file</returns>
        Task<FuelRefillExcelExportResult> ExportFuelRefillsAsync(SmartTableParam param);
    }

    /// <summary>
    /// Dịch vụ xuất Excel lịch sử đổ dầu
    /// </summary>
    public class FuelRefillExcelService : IFuelRefillExcelService
    {
        private readonly IRepository<FuelRefill> _fuelRefillRepository;
        private readonly IExcelFileService _excelFileService;

        public FuelRefillExcelService(
            IRepository<FuelRefill> fuelRefillRepository,
            IExcelFileService excelFileService)
        {
            _fuelRefillRepository = fuelRefillRepository;
            _excelFileService = excelFileService;
        }

        /// <summary>
        /// Xuất Excel lịch sử đổ dầu
        /// </summary>
        public async Task<FuelRefillExcelExportResult> ExportFuelRefillsAsync(SmartTableParam param)
        {
            var result = new FuelRefillExcelExportResult
            {
                ProcessStartTime = DateTimeOffset.Now
            };

            try
            {
                // Lấy dữ liệu (không phân trang)
                var refills = await GetRefillsDataAsync(param);

                // Tạo file Excel
                var excelPackage = CreateExcelPackage(refills);

                // Lưu file sử dụng ExcelFileService
                var saveResult = await _excelFileService.SaveExcelFileAsync(
                    excelPackage,
                    "LichSuDoDau",
                    "fuel-refills",
                    null);

                if (saveResult.Result == Result.Success)
                {
                    // Cập nhật kết quả
                    result.FilePath = saveResult.FilePath;
                    result.FileName = saveResult.SavedFileName;
                    result.DownloadUrl = saveResult.FileUrl;
                    result.FileSize = saveResult.FileSize;
                    result.TotalRecords = refills.Count;
                    result.Result = Result.Success;
                    result.Message = "Xuất file Excel thành công";
                }
                else
                {
                    result.Result = saveResult.Result;
                    result.Message = saveResult.Message;
                }
            }
            catch (Exception ex)
            {
                result.Result = Result.SystemError;
                result.Message = $"Lỗi khi xuất file Excel: {ex.Message}";
            }

            result.ProcessEndTime = DateTimeOffset.Now;
            return result;
        }

        #region Private Methods

        /// <summary>
        /// Lấy dữ liệu lịch sử đổ dầu (không phân trang)
        /// </summary>
        private async Task<List<FuelRefill>> GetRefillsDataAsync(SmartTableParam param)
        {
            param ??= new SmartTableParam();

            var query = _fuelRefillRepository.Query()
                .Include(x => x.Truck)
                .Include(x => x.Driver)
                .Include(x => x.FuelCard)
                .Where(x => !x.IsDeleted);

            // Search
            if (param.Search?.PredicateObject != null)
            {
                dynamic search = param.Search.PredicateObject;

                // Filter by TruckId
                if (search.TruckId != null)
                {
                    int truckId = search.TruckId;
                    if (truckId > 0)
                    {
                        query = query.Where(x => x.TruckId == truckId);
                    }
                }

                // Filter by Keyword
                if (search.Keyword != null)
                {
                    string keyword = search.Keyword.ToString().ToLower().Trim();
                    if (!string.IsNullOrEmpty(keyword))
                    {
                        query = query.Where(x =>
                            x.Truck.LicensePlate.ToLower().Contains(keyword) ||
                            x.Driver.UserName.ToLower().Contains(keyword) ||
                            x.StationName.ToLower().Contains(keyword));
                    }
                }
            }

            // Sorting
            if (!string.IsNullOrWhiteSpace(param.Sort?.Predicate))
            {
                query = param.Sort.Predicate.ToLower() switch
                {
                    "refilltime" => param.Sort.Reverse ? query.OrderByDescending(x => x.RefillTime) : query.OrderBy(x => x.RefillTime),
                    "differenceliters" => param.Sort.Reverse ? query.OrderByDescending(x => x.DifferenceLiters) : query.OrderBy(x => x.DifferenceLiters),
                    _ => query.OrderByDescending(x => x.RefillTime)
                };
            }
            else
            {
                query = query.OrderByDescending(x => x.RefillTime);
            }

            return await query.ToListAsync();
        }

        /// <summary>
        /// Tạo ExcelPackage
        /// </summary>
        private ExcelPackage CreateExcelPackage(List<FuelRefill> refills)
        {
            var package = new ExcelPackage();
            var worksheet = package.Workbook.Worksheets.Add("Lịch sử đổ dầu");

            // Thiết lập header
            SetupHeaders(worksheet);

            // Điền dữ liệu
            FillData(worksheet, refills);

            // Định dạng worksheet
            FormatWorksheet(worksheet, refills.Count);

            return package;
        }

        /// <summary>
        /// Thiết lập header
        /// </summary>
        private void SetupHeaders(ExcelWorksheet worksheet)
        {
            var headers = new[]
            {
                "STT",
                "Biển số xe",
                "Lái xe",
                "Thẻ xăng",
                "ODO trước",
                "ODO hiện tại",
                "Quãng đường (km)",
                "Số tiền",
                "Đơn giá",
                "Số lít thực tế",
                "Định mức (lít/100km)",
                "Số lít khoán",
                "Chênh lệch (lít)",
                "Phương thức thanh toán",
                "Cây xăng",
                "Thời gian đổ dầu",
                "Ghi chú"
            };

            for (int i = 0; i < headers.Length; i++)
            {
                worksheet.Cells[1, i + 1].Value = headers[i];
            }
        }

        /// <summary>
        /// Điền dữ liệu
        /// </summary>
        private void FillData(ExcelWorksheet worksheet, List<FuelRefill> refills)
        {
            int row = 2;

            foreach (var refill in refills)
            {
                worksheet.Cells[row, 1].Value = row - 1; // STT
                worksheet.Cells[row, 2].Value = refill.Truck?.LicensePlate ?? "";
                worksheet.Cells[row, 3].Value = refill.Driver?.UserName ?? "";
                worksheet.Cells[row, 4].Value = refill.FuelCard?.CardNumber ?? "";
                worksheet.Cells[row, 5].Value = refill.PreviousOdo;
                worksheet.Cells[row, 6].Value = refill.CurrentOdo;
                worksheet.Cells[row, 7].Value = refill.DistanceKm;
                worksheet.Cells[row, 8].Value = refill.Amount;
                worksheet.Cells[row, 8].Style.Numberformat.Format = "#,##0";
                worksheet.Cells[row, 9].Value = refill.UnitPrice;
                worksheet.Cells[row, 9].Style.Numberformat.Format = "#,##0";
                worksheet.Cells[row, 10].Value = (double)refill.ActualLiters;
                worksheet.Cells[row, 10].Style.Numberformat.Format = "0.00";
                worksheet.Cells[row, 11].Value = (double)refill.FuelQuotaPer100Km;
                worksheet.Cells[row, 11].Style.Numberformat.Format = "0.00";
                worksheet.Cells[row, 12].Value = (double)refill.QuotaLiters;
                worksheet.Cells[row, 12].Style.Numberformat.Format = "0.00";
                worksheet.Cells[row, 13].Value = (double)refill.DifferenceLiters;
                worksheet.Cells[row, 13].Style.Numberformat.Format = "0.00";
                worksheet.Cells[row, 14].Value = refill.PaymentMethod.ToString();
                worksheet.Cells[row, 15].Value = refill.StationName ?? "";
                worksheet.Cells[row, 16].Value = refill.RefillTime.ToString("dd/MM/yyyy HH:mm");
                worksheet.Cells[row, 17].Value = refill.Notes ?? "";

                row++;
            }
        }

        /// <summary>
        /// Định dạng worksheet
        /// </summary>
        private void FormatWorksheet(ExcelWorksheet worksheet, int dataRowCount)
        {
            // Header formatting
            var headerRange = worksheet.Cells[1, 1, 1, 17];
            headerRange.Style.Font.Bold = true;
            headerRange.Style.Fill.PatternType = ExcelFillStyle.Solid;
            headerRange.Style.Fill.BackgroundColor.SetColor(Color.LightBlue);
            headerRange.Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;
            headerRange.Style.VerticalAlignment = ExcelVerticalAlignment.Center;

            // Auto-fit columns
            worksheet.Cells.AutoFitColumns();

            // Border for all data
            if (dataRowCount > 0)
            {
                var dataRange = worksheet.Cells[1, 1, dataRowCount + 1, 17];
                dataRange.Style.Border.Top.Style = ExcelBorderStyle.Thin;
                dataRange.Style.Border.Left.Style = ExcelBorderStyle.Thin;
                dataRange.Style.Border.Right.Style = ExcelBorderStyle.Thin;
                dataRange.Style.Border.Bottom.Style = ExcelBorderStyle.Thin;
            }
        }

        #endregion
    }
}
