using Dapper;
using Lada.Framework.DTO.SmartTable;
using Lada.Framework.Infrastructures.Helpers;
using Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards;
using Ladaer.BackEnd.Infrastructures.DTO.Reports.Results;
using System.Data;

namespace Ladaer.BackEnd.Infrastructures.Services.Report.FuelCards
{
    /// <summary>
    /// Interface cho dịch vụ báo cáo đổ dầu
    /// </summary>
    public interface IFuelRefillReportService
    {
        /// <summary>
        /// Lấy báo cáo đổ dầu theo lái xe từ stored procedure
        /// </summary>
        /// <param name="param">Tham số bảng thông minh</param>
        /// <returns>Danh sách báo cáo đổ dầu theo lái xe</returns>
        Task<FuelRefillReportByDriverResult> GetFuelRefillReportByDriverAsync(SmartTableParam param);
    }

    /// <summary>
    /// Dịch vụ báo cáo đổ dầu
    /// </summary>
    public class FuelRefillReportService : IFuelRefillReportService
    {
        private readonly IDbConnection _dbConnection;

        public FuelRefillReportService(IDbConnection dbConnection)
        {
            _dbConnection = dbConnection;
        }

        /// <summary>
        /// Lấy báo cáo đổ dầu theo lái xe từ stored procedure
        /// </summary>
        /// <param name="param">Tham số bảng thông minh</param>
        /// <returns>Danh sách báo cáo đổ dầu theo lái xe</returns>
        public async Task<FuelRefillReportByDriverResult> GetFuelRefillReportByDriverAsync(SmartTableParam param)
        {
            var result = new FuelRefillReportByDriverResult();
            const string storeNameByDriver = "sp_GetFuelRefillReportByDriver";
            const string storeNameByDriverAndTruck = "sp_GetFuelRefillReportByDriverAndTruck";

            try
            {
                // Xử lý tham số từ SmartTableParam
                DateTimeOffset fromDate = DateTimeOffset.Now.AddDays(-30).StartOfDay(); // Mặc định 30 ngày gần nhất
                DateTimeOffset toDate = DateTimeOffset.Now.EndOfDay();
                string? driverIds = null;
                string? truckIds = null;

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

                    // Xử lý khoảng thời gian
                    if (search.StartDate != null && search.EndDate != null)
                    {
                        DateTimeOffset start = search.StartDate;
                        DateTimeOffset end = search.EndDate;
                        fromDate = start.ToLocalTime().StartOfDay();
                        toDate = end.ToLocalTime().EndOfDay();
                    }

                    // Xử lý DriverIds (mảng ID lái xe)
                    if (search.DriverIds != null)
                    {
                        var driverIdList = new List<int>();

                        // Kiểm tra nếu DriverIds là mảng
                        if (search.DriverIds is Newtonsoft.Json.Linq.JArray jArray)
                        {
                            foreach (var item in jArray)
                            {
                                if (int.TryParse(item.ToString(), out int id))
                                {
                                    driverIdList.Add(id);
                                }
                            }
                        }
                        // Kiểm tra nếu DriverIds là List<int>
                        else if (search.DriverIds is System.Collections.IEnumerable enumerable)
                        {
                            foreach (var item in enumerable)
                            {
                                if (int.TryParse(item.ToString(), out int id))
                                {
                                    driverIdList.Add(id);
                                }
                            }
                        }

                        if (driverIdList.Count > 0)
                        {
                            driverIds = string.Join(",", driverIdList);
                        }
                    }

                    // Xử lý TruckIds (mảng ID xe)
                    if (search.TruckIds != null)
                    {
                        var truckIdList = new List<int>();

                        // Kiểm tra nếu TruckIds là mảng
                        if (search.TruckIds is Newtonsoft.Json.Linq.JArray jArray)
                        {
                            foreach (var item in jArray)
                            {
                                if (int.TryParse(item.ToString(), out int id))
                                {
                                    truckIdList.Add(id);
                                }
                            }
                        }
                        // Kiểm tra nếu TruckIds là List<int>
                        else if (search.TruckIds is System.Collections.IEnumerable enumerable)
                        {
                            foreach (var item in enumerable)
                            {
                                if (int.TryParse(item.ToString(), out int id))
                                {
                                    truckIdList.Add(id);
                                }
                            }
                        }

                        if (truckIdList.Count > 0)
                        {
                            truckIds = string.Join(",", truckIdList);
                        }
                    }
                }

                var parameters = new DynamicParameters();
                parameters.Add("StartDate", fromDate.Date);
                parameters.Add("EndDate", toDate.Date);
                parameters.Add("DriverIds", driverIds);
                parameters.Add("TruckIds", truckIds);

                // Gọi stored procedure để lấy dữ liệu tổng hợp theo lái xe
                var driverItems = (await _dbConnection.QueryAsync<FuelRefillReportByDriverItem>(
                    storeNameByDriver,
                    parameters,
                    commandType: CommandType.StoredProcedure)).ToList();

                // Gọi stored procedure để lấy chi tiết theo lái xe và xe
                var detailItems = (await _dbConnection.QueryAsync<DriverTruckDetailRow>(
                    storeNameByDriverAndTruck,
                    parameters,
                    commandType: CommandType.StoredProcedure)).ToList();

                // Gán chi tiết xe vào từng lái xe
                foreach (var driver in driverItems)
                {
                    driver.TruckDetails = detailItems
                        .Where(d => d.DriverId == driver.DriverId)
                        .Select(d => new FuelRefillReportByTruckItem
                        {
                            TruckId = d.TruckId,
                            TruckPlate = d.TruckPlate,
                            TruckName = d.TruckName,
                            TotalDistanceKm = d.TotalDistanceKm,
                            TotalActualLiters = d.TotalActualLiters,
                            TotalActualAmount = d.TotalActualAmount,
                            TotalQuotaLiters = d.TotalQuotaLiters,
                            TotalQuotaAmount = d.TotalQuotaAmount,
                            TotalFuelIncome = d.TotalFuelIncome
                        })
                        .ToList();
                }

                result.Items = driverItems;
                result.TotalRecord = result.Items.Count;
            }
            catch (Exception ex)
            {
                result.Result = Lada.Framework.DTO.Result.SystemError;
                result.Message = ex.Message;
            }

            return result;
        }

        /// <summary>
        /// DTO tạm để map kết quả từ stored procedure chi tiết
        /// </summary>
        private class DriverTruckDetailRow
        {
            public int DriverId { get; set; }
            public string DriverUserName { get; set; } = string.Empty;
            public string DriverFullName { get; set; } = string.Empty;
            public int TruckId { get; set; }
            public string TruckPlate { get; set; } = string.Empty;
            public string TruckName { get; set; } = string.Empty;
            public int TotalDistanceKm { get; set; }
            public decimal TotalActualLiters { get; set; }
            public decimal TotalActualAmount { get; set; }
            public decimal TotalQuotaLiters { get; set; }
            public decimal TotalQuotaAmount { get; set; }
            public decimal TotalFuelIncome { get; set; }
        }
    }
}
