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

namespace Ladaer.BackEnd.Infrastructures.Services.Report.OperationReports
{
    /// <summary>
    /// Interface cho dịch vụ báo cáo lái xe
    /// </summary>
    public interface IDriverReportService
    {
        /// <summary>
        /// Lấy báo cáo năng suất lái xe theo từng ngày
        /// </summary>
        /// <param name="param">Tham số bảng thông minh</param>
        /// <param name="userId">ID người dùng</param>
        /// <returns>Kết quả báo cáo năng suất lái xe theo ngày</returns>
        Task<DriverProductivityReportByDateResult> GetDriverProductivityReportByDateAsync(
            SmartTableParam param, int userId);
    }

    /// <summary>
    /// Dịch vụ báo cáo lái xe
    /// </summary>
    public class DriverReportService : IDriverReportService
    {
        private readonly IDbConnection _dbConnection;
        private readonly IUserService _userService;

        /// <summary>
        /// Khởi tạo một thể hiện của <see cref="DriverReportService"/>.
        /// </summary>
        /// <param name="dbConnection">Kết nối cơ sở dữ liệu.</param>
        /// <param name="userService">Service quản lý người dùng.</param>
        public DriverReportService(IDbConnection dbConnection, IUserService userService)
        {
            _dbConnection = dbConnection;
            _userService = userService;
        }

        /// <inheritdoc />
        public async Task<DriverProductivityReportByDateResult> GetDriverProductivityReportByDateAsync(
            SmartTableParam param, int userId)
        {
            var result = new DriverProductivityReportByDateResult();
            const string storeName = "sp_GetDriverProductivityReportByDate";

            try
            {
                var currentUser = await _userService.GetByIdAsync(userId);
                if (currentUser == null)
                {
                    result.Message = "Không tìm thấy thông tin người dùng";
                    return result;
                }

                var userRoles = await _userService.GetRolesAsync(userId);
                var isFounder = userRoles.Any(r => r.Equals("Founder", StringComparison.OrdinalIgnoreCase));

                DateTimeOffset? fromDate = null;
                DateTimeOffset? toDate = null;
                string? driverIds = null;

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

                    if (search.FromDate != null && search.ToDate != null)
                    {
                        DateTimeOffset start = search.FromDate;
                        DateTimeOffset end = search.ToDate;
                        // Chuyển từ UTC sang local time (GMT+7) và lấy đầu/cuối ngày
                        fromDate = start.ToLocalTime().DateTime.StartOfDay();
                        toDate = end.ToLocalTime().DateTime.EndOfDay();
                    }

                    if (search.DriverIds != null)
                    {
                        var driverIdList = new List<int>();

                        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);
                                }
                            }
                        }
                        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);
                        }
                    }
                }

                var parameters = new DynamicParameters();
                parameters.Add("FromDate", fromDate);
                parameters.Add("ToDate", toDate);
                parameters.Add("DriverIds", driverIds);

                var items = await _dbConnection.QueryAsync<DriverProductivityReportByDateItem>(
                    storeName,
                    parameters,
                    commandType: CommandType.StoredProcedure);

                var allItems = items.ToList();

                // Nhóm dữ liệu theo DriverId và tính tổng, giữ chi tiết từng ngày
                var groupedItems = allItems
                    .GroupBy(x => x.DriverId)
                    .Select(g => new DriverProductivityGroupItem
                    {
                        DriverId = g.Key,
                        DriverUserName = g.First().DriverUserName,
                        DriverFullName = g.First().DriverFullName,
                        PickupCount = g.Sum(x => x.PickupCount),
                        DeliveryCount = g.Sum(x => x.DeliveryCount),
                        TotalCount = g.Sum(x => x.TotalCount),
                        DailyDetails = g.OrderByDescending(x => x.ActivityDate).ToList()
                    })
                    .OrderByDescending(x => x.TotalCount)
                    .ThenBy(x => x.DriverFullName)
                    .ToList();

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

            return result;
        }
    }
}
