using Dapper;
using Lada.Framework.DTO.SmartTable;
using Lada.Framework.Infrastructures.Helpers;
using Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders;
using Ladaer.BackEnd.Infrastructures.DTO.Reports.Results;
using Ladaer.BackEnd.Infrastructures.Services.Identity;
using System.Data;
using System.Linq;
using static Microsoft.EntityFrameworkCore.DbLoggerCategory;

namespace Ladaer.BackEnd.Infrastructures.Services.Report.Orders
{
    public interface IOrderReportService
    {
        /// <summary>
        /// Lấy thống kê đơn hàng theo ngày từ stored procedure
        /// </summary>
        /// <param name="param">Tham số bảng thông minh</param>
        /// <param name="userId">ID người dùng</param>
        /// <returns>Danh sách thống kê đơn hàng theo ngày</returns>
        Task<OrderProductionResult> GetOrderProductionAsync(SmartTableParam param, int userId);


        // Đã chuyển sang ISaleReportService

        /// <summary>
        /// Lấy báo cáo công nợ theo sale từ stored procedure
        /// </summary>
        /// <param name="param">Tham số bảng thông minh</param>
        /// <param name="userId">ID người dùng</param>
        /// <returns>Danh sách báo cáo công nợ theo sale</returns>
        Task<SaleDebtResult> GetSaleDebtReportAsync(SmartTableParam param, int userId);

        /// <summary>
        /// Lấy báo cáo số lượng đơn và doanh số theo tuyến
        /// </summary>
        /// <param name="param">Tham số bảng thông minh</param>
        /// <param name="userId">ID người dùng</param>
        /// <returns>Danh sách báo cáo theo tuyến và trạng thái</returns>
        Task<OrderReportByRouteResult> GetOrderReportByRouteAsync(SmartTableParam param, int userId);
    }


    /// <summary>
    /// Dịch vụ báo cáo đơn hàng
    /// </summary>
    public class OrderReportService : IOrderReportService
    {
        private readonly IDbConnection _dbConnection;

        private readonly IUserService _userService;

        public OrderReportService(IDbConnection dbConnection, IUserService userService)
        {
            _dbConnection = dbConnection;
            _userService = userService;
        }

        /// <summary>
        /// Lấy thống kê đơn hàng theo ngày từ stored procedure
        /// </summary>
        /// <param name="param">Tham số bảng thông minh</param>
        /// <param name="userId">ID người dùng</param>
        /// <returns>Danh sách thống kê đơn hàng theo ngày</returns>
        public async Task<OrderProductionResult> GetOrderProductionAsync(SmartTableParam param, int userId)
        {
            var result = new OrderProductionResult();
            string storeName = "sp_GetOrderStatisticsByDate";

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

                var saleId = (int?)null;

                if (userId <= 0)
                {
                    result.Result = Lada.Framework.DTO.Result.Failed;
                    result.Message = "Không xác định được người dùng";
                    return result;
                }

                var roles = await _userService.GetRolesAsync(userId);

                if (!roles.Any(r => r == "Founder"))
                {
                    saleId = userId;
                }

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

                    if (search.StartDate != null && search.EndDate != null)
                    {
                        DateTimeOffset start = search.StartDate;
                        DateTimeOffset end = search.EndDate;
                        fromDate = start.ToLocalTime().StartOfDay();
                        toDate = end.ToLocalTime().DateTime.EndOfDay();
                    }
                }

                var parameters = new DynamicParameters();
                parameters.Add("StartDate", fromDate);
                parameters.Add("EndDate", toDate);
                parameters.Add("SaleId", saleId);

                // Gọi stored procedure và map trực tiếp sang OrderProductionItem
                result.Items = (await _dbConnection.QueryAsync<OrderProductionItem>(
                    storeName,
                    parameters,
                    commandType: CommandType.StoredProcedure)).ToList();


                result.TotalRecord = result.Items.Count;
            }
            catch (Exception ex)
            {
                result.Result = Lada.Framework.DTO.Result.SystemError;
                result.Message = ex.Message;
                // Log error here if needed
                //throw new Exception($"Lỗi khi gọi stored procedure {storeName}: {ex.Message}", ex);
            }

            return result;
        }

        //Method này đã chuyển sang ISaleReportService.GetOrderRevenueStatisticsByDateAsync
        // Đã chuyển sang SaleReportService

        /// <summary>
        /// Lấy báo cáo công nợ theo sale từ stored procedure
        /// </summary>
        /// <param name="param">Tham số bảng thông minh</param>
        /// <param name="userId">ID người dùng</param>
        /// <returns>Danh sách báo cáo công nợ theo sale</returns>
        public async Task<SaleDebtResult> GetSaleDebtReportAsync(SmartTableParam param, int userId)
        {
            var result = new SaleDebtResult();
            string storeName = "sp_GetSaleDebtReport";

            try
            {
                // Lấy thông tin user hiện tại
                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;
                }

                // Kiểm tra quyền của user hiện tại
                var userRoles = await _userService.GetRolesAsync(userId);
                var isFounder = userRoles.Any(r => r.Equals("Founder", StringComparison.OrdinalIgnoreCase));

                // Xử lý tham số tìm kiếm
                DateTime? fromDate = null;
                DateTime? toDate = null;
                int? saleId = null;
                string? saleIds = null;

                // Nếu không phải Founder, chỉ được xem dữ liệu của chính mình
                if (!isFounder)
                {
                    saleId = userId;
                }

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

                    if (search.StartDate != null && search.EndDate != null)
                    {
                        DateTimeOffset start = search.StartDate;
                        DateTimeOffset end = search.EndDate;
                        fromDate = start.Date;
                        toDate = end.Date;
                    }

                    // Chỉ Founder mới có thể lọc theo SaleId hoặc SaleIds
                    if (isFounder)
                    {
                        // Xử lý SaleId đơn lẻ
                        if (search.SaleId != null)
                        {
                            saleId = (int)search.SaleId;
                        }
                        // Xử lý SaleIds dạng mảng
                        else if (search.SaleIds != null)
                        {
                            var saleIdList = new List<int>();

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

                            if (saleIdList.Count > 0)
                            {
                                saleIds = string.Join(",", saleIdList);
                            }
                        }
                    }
                }

                var parameters = new DynamicParameters();
                parameters.Add("StartDate", fromDate);
                parameters.Add("EndDate", toDate);
                parameters.Add("SaleId", saleId);
                parameters.Add("SaleIds", saleIds);

                // Gọi stored procedure và map trực tiếp sang SaleDebtItem
                result.Items = [.. await _dbConnection.QueryAsync<SaleDebtItem>(
                    storeName,
                    parameters,
                    commandType: CommandType.StoredProcedure)];

                result.TotalRecord = result.Items.Count;
            }
            catch (Exception ex)
            {
                result.Result = Lada.Framework.DTO.Result.SystemError;
                result.Message = ex.Message;
                // Log error here if needed
                //throw new Exception($"Lỗi khi gọi stored procedure {storeName}: {ex.Message}", ex);
            }

            return result;
        }

        /// <summary>
        /// Lấy báo cáo số lượng đơn và doanh số theo tuyến
        /// </summary>
        /// <param name="param">Tham số bảng thông minh</param>
        /// <param name="userId">ID người dùng</param>
        /// <returns>Danh sách báo cáo theo tuyến và trạng thái</returns>
        public async Task<OrderReportByRouteResult> GetOrderReportByRouteAsync(SmartTableParam param, int userId)
        {
            var result = new OrderReportByRouteResult();
            string storeName = "sp_GetOrderReportByRoute";

            try
            {
                // Kiểm tra userId
                if (userId <= 0)
                {
                    result.Result = Lada.Framework.DTO.Result.Failed;
                    result.Message = "Không xác định được người dùng";
                    return result;
                }

                // Lấy roles của user
                var roles = await _userService.GetRolesAsync(userId);
                var isFounder = roles.Any(r => r.Equals("Founder", StringComparison.OrdinalIgnoreCase));

                // Xử lý tham số tìm kiếm
                DateTimeOffset? fromDate = null;
                DateTimeOffset? toDate = null;
                int? saleId = null;
                string? sourceCityIds = null;
                string? destCityIds = null;

                // Nếu không phải Founder, chỉ được xem dữ liệu của chính mình
                //if (!isFounder)
                //{
                //    saleId = userId;
                //}

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

                    // Chỉ Founder mới có thể lọc theo SaleId
                    if (isFounder && search.SaleId != null)
                    {
                        saleId = (int)search.SaleId;
                    }

                    // Lọc theo tỉnh/thành phố gửi (hỗ trợ nhiều giá trị)
                    if (search.SourceCityIds != null)
                    {
                        var sourceCityIdList = new List<int>();

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

                        if (sourceCityIdList.Count > 0)
                        {
                            sourceCityIds = string.Join(",", sourceCityIdList);
                        }
                    }

                    // Lọc theo tỉnh/thành phố nhận (hỗ trợ nhiều giá trị)
                    if (search.DestCityIds != null)
                    {
                        var destCityIdList = new List<int>();

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

                        if (destCityIdList.Count > 0)
                        {
                            destCityIds = string.Join(",", destCityIdList);
                        }
                    }
                }

                var parameters = new DynamicParameters();
                parameters.Add("FromDate", fromDate);
                parameters.Add("ToDate", toDate);
                parameters.Add("SaleId", saleId);
                parameters.Add("SourceCityIds", sourceCityIds);
                parameters.Add("DestCityIds", destCityIds);

                // Gọi stored procedure và map trực tiếp sang OrderReportByRouteItem
                result.Items = (await _dbConnection.QueryAsync<OrderReportByRouteItem>(
                    storeName,
                    parameters,
                    commandType: CommandType.StoredProcedure)).ToList();

                result.TotalRecord = result.Items.Count;
            }
            catch (Exception ex)
            {
                result.Result = Lada.Framework.DTO.Result.SystemError;
                result.Message = ex.Message;
                // Log error here if needed
            }

            return result;
        }

    }
}