using System.Data;
using Dapper;
using Lada.Framework.Data.Domains.Hr;
using Lada.Framework.Data.Domains.Medias;
using Lada.Framework.Data.Domains.Trucks;
using Lada.Framework.Data.Enums;
using Lada.Framework.Data.Repositories;
using Lada.Framework.DTO;
using Lada.Framework.DTO.Models.Media;
using Lada.Framework.DTO.SmartTable;
using Lada.Framework.Infrastructures.Helpers;
using Lada.Framework.Infrastructures.Services;
using Ladaer.BackEnd.Infrastructures.DTO;
using Ladaer.BackEnd.Infrastructures.DTO.Items.Hr;
using Ladaer.BackEnd.Infrastructures.DTO.Models.Hr;
using Ladaer.BackEnd.Infrastructures.DTO.Results.Export;
using Ladaer.BackEnd.Infrastructures.DTO.Results.Hr;
using Ladaer.BackEnd.Infrastructures.DTO.Results.Media;
using Microsoft.EntityFrameworkCore;
using OfficeOpenXml;
using OfficeOpenXml.Style;

namespace Ladaer.BackEnd.Infrastructures.Services.Hr
{
    /// <summary>
    /// Giao diện cho dịch vụ chấm công.
    /// </summary>
    public interface IAttendanceService
    {
        /// <summary>
        /// Xử lý chấm công (Check-in hoặc Check-out) dựa trên trạng thái hiện tại.
        /// </summary>
        /// <param name="model">Mô hình CheckInOutModel chứa thông tin chấm công.</param>
        /// <returns>Kết quả chấm công với thông tin chi tiết.</returns>
        Task<CheckInOutResult> PunchAsync(CheckInOutModel model);

        /// <summary>
        /// Lấy thông tin chấm công hiện tại của người dùng (chưa check-out hoặc hôm nay)
        /// </summary>
        /// <param name="userId">ID người dùng</param>
        /// <returns>Thông tin chấm công hiện tại</returns>
        Task<AttendanceItem?> GetCurrentAttendance(int userId);



        /// <summary>
        /// Tìm kiếm bản ghi chấm công theo điều kiện.
        /// </summary>
        /// <param name="param">Tham số SmartTableParam.</param>
        /// <returns>Kết quả tìm kiếm bản ghi chấm công.</returns>
        Task<SmartTableResult<AttendanceItem>> SearchAsync(SmartTableParam param);

        /// <summary>
        /// Tạo mới bản ghi chấm công.
        /// </summary>
        /// <param name="attendance">Đối tượng Attendance.</param>
        /// <returns>Bản ghi Attendance đã tạo.</returns>
        Task<Attendance> CreateAsync(Attendance attendance);

        /// <summary>
        /// Cập nhật bản ghi chấm công.
        /// </summary>
        /// <param name="attendance">Đối tượng Attendance cần cập nhật.</param>
        /// <returns>Bản ghi Attendance đã cập nhật.</returns>
        Task<Attendance> UpdateAsync(Attendance attendance);

        /// <summary>
        /// Xóa bản ghi chấm công theo Id.
        /// </summary>
        /// <param name="id">Id bản ghi chấm công.</param>
        /// <returns>True nếu xóa thành công, ngược lại false.</returns>
        Task<bool> DeleteAsync(Guid id);

        /// <summary>
        /// Lấy thông tin bản ghi chấm công theo Id.
        /// </summary>
        /// <param name="id">Id bản ghi chấm công.</param>
        /// <returns>Bản ghi Attendance nếu tìm thấy, ngược lại null.</returns>
        Task<Attendance> GetByIdAsync(Guid id);

        /// <summary>
        /// Xuất danh sách chấm công ra file Excel.
        /// </summary>
        /// <param name="param">Tham số SmartTableParam.</param>
        /// <param name="filePath">Đường dẫn file Excel.</param>
        /// <returns>Kết quả xuất file.</returns>
        Task<ExportResult> ExportToExcelAsync(SmartTableParam param, string filePath);

        /// <summary>
        /// Lấy tổng hợp số công của tất cả nhân viên theo tháng
        /// </summary>
        /// <param name="month">Tháng (1-12)</param>
        /// <param name="year">Năm (ví dụ: 2025)</param>
        /// <returns>Danh sách tổng hợp số công của nhân viên</returns>
        Task<List<AttendanceSummaryItem>> GetAttendanceSummaryByMonthAsync(int month, int year);

        /// <summary>
        /// Lấy chi tiết công từng ngày của một nhân viên theo tháng
        /// </summary>
        /// <param name="month">Tháng (1-12)</param>
        /// <param name="year">Năm (ví dụ: 2025)</param>
        /// <param name="userId">ID nhân viên</param>
        /// <returns>Danh sách chi tiết công từng ngày</returns>
        Task<List<AttendanceDetailItem>> GetAttendanceDetailByUserAsync(int month, int year, int userId);
    }

    /// <summary>
    /// Triển khai dịch vụ chấm công.
    /// </summary>
    public class AttendanceService : IAttendanceService
    {
        private readonly IRepository<Attendance> _attendanceRepository;
        private readonly IRepository<AttendanceMedia> _attendanceMediaRepository;
        private readonly IRepository<Media> _mediaRepository;
        private readonly IUnifiedMediaService _unifiedMediaService;
        private readonly IRepository<Truck> _truckRepository;
        private readonly IDbConnection _dbConnection;

        public AttendanceService(
            IRepository<Attendance> attendanceRepository,
            IRepository<AttendanceMedia> attendanceMediaRepository,
            IRepository<Media> mediaRepository,
            IUnifiedMediaService unifiedMediaService,
            IRepository<Truck> truckRepository,
            IDbConnection dbConnection)
        {
            _attendanceRepository = attendanceRepository;
            _attendanceMediaRepository = attendanceMediaRepository;
            _mediaRepository = mediaRepository;
            _unifiedMediaService = unifiedMediaService;
            _truckRepository = truckRepository;
            _dbConnection = dbConnection;
        }

        #region Staff Functions

        /// <summary>
        /// Xử lý chấm công (Check-in hoặc Check-out) dựa trên trạng thái hiện tại.
        /// </summary>
        public async Task<CheckInOutResult> PunchAsync(CheckInOutModel model)
        {
            var result = new BaseResult();
            var currentTime = DateTimeHelper.CurrentTime();

            // Tìm attendance chưa checkout
            var today = DateTimeHelper.CurrentTime().Date;
            var attendance = await _attendanceRepository.Query()
                //.Include(a => a.AttendanceMedias).ThenInclude(am => am.Media)
                .Where(a => a.UserId == model.UserId &&
                           a.CheckInTime.Date == today &&
                           a.CheckOutTime == null)
                .OrderByDescending(a => a.CheckInTime)
                .FirstOrDefaultAsync();

            var isCheckOut = true;

            if (attendance != null)
            {
                // Xác định ngày hiện tại (UTC hoặc timezone nghiệp vụ)
                var attendanceDate = attendance.CheckInTime.Date;
                isCheckOut = today == attendanceDate ? true : false;
                if (isCheckOut)
                {
                    model.AttendanceId = attendance.Id;
                }
            }
            else
            {
                isCheckOut = false;
            }

            return isCheckOut ? await CheckOut(model) : await CheckIn(model);

        }


        /// <summary>
        /// Chấm công vào (Check-in) với mô hình CheckInOutModel.
        /// </summary>
        public async Task<CheckInOutResult> CheckIn(CheckInOutModel model)
        {
            var result = new CheckInOutResult();
            var currentTime = DateTimeHelper.CurrentTime();
            var attendance = new Attendance
            {
                Id = Guid.NewGuid(),
                UserId = model.UserId,
                CheckInTime = currentTime,
                CheckInOdo = model.Odo,
                CreatedTime = currentTime,
                UpdatedTime = currentTime,
                CreatedBy = model.UpdatedBy,
                UpdatedBy = model.UpdatedBy,
                CreatedByUserName = model.UpdatedByUserName,
                UpdatedByUserName = model.UpdatedByUserName
            };
            await _attendanceRepository.InsertAsync(attendance);

            if (model.MediaFiles != null && model.MediaFiles.Any())
            {
                var attendanceMediaModel = new AttendanceMediaModel
                {
                    AttendanceId = attendance.Id,
                    Files = model.MediaFiles,
                    AttendanceMediaType = AttendanceMediaType.CheckIn,
                    UpdatedBy = model.UpdatedBy,
                    UpdatedByUserName = model.UpdatedByUserName
                };
                var saveResults = await SaveAttendanceMediaAsync(attendanceMediaModel);
                var failedResult = saveResults.FirstOrDefault(r => r.Result != Result.Success);
                if (failedResult != null)
                {
                    result.Result = failedResult.Result;
                    result.Message = failedResult.Message;
                    return result;
                }
            }

            // Cập nhật trạng thái xe của tài xế (nếu có) thành "Đang hoạt động"
            await UpdateUserTruckOperatingStatus(model.UserId, OperatingStatus.Running);

            // Lấy thông tin chi tiết của attendance vừa tạo để trả về
            var attendanceItem = await GetAttendanceItemById(attendance.Id);

            result.Result = Result.Success;
            result.Message = "Check-in thành công";
            result.Item = attendanceItem;
            result.ActionType = "CheckIn";
            result.ActionTime = currentTime;
            result.IsCheckIn = true;

            return result;
        }




        /// <summary>
        /// Chấm công ra (Check-out) với mô hình CheckInOutModel.
        /// </summary>
        public async Task<CheckInOutResult> CheckOut(CheckInOutModel model)
        {
            var result = new CheckInOutResult();
            var currentTime = DateTimeHelper.CurrentTime();


            if (!model.AttendanceId.HasValue)
            {
                result.Result = Result.Failed;
                result.Message = "Không tìm thấy ID bản ghi chấm công";
                return result;
            }

            var attendance = await _attendanceRepository.Query()
                .FirstOrDefaultAsync(a => a.Id == model.AttendanceId.Value);

            if (attendance == null)
            {
                result.Result = Result.Failed;
                result.Message = "Không tìm thấy bản ghi chấm công";
                return result;
            }

            if (attendance.CheckOutTime != null)
            {
                result.Result = Result.Failed;
                result.Message = "Đã check-out trước đó";
                return result;
            }

            attendance.CheckOutTime = currentTime;
            attendance.CheckOutOdo = model.Odo;
            await _attendanceRepository.UpdateAsync(attendance);

            if (model.MediaFiles != null && model.MediaFiles.Any())
            {
                var attendanceMediaModel = new AttendanceMediaModel
                {
                    AttendanceId = attendance.Id,
                    Files = model.MediaFiles,
                    AttendanceMediaType = AttendanceMediaType.CheckOut,
                    UpdatedBy = model.UpdatedBy,
                    UpdatedByUserName = model.UpdatedByUserName
                };
                var saveResults = await SaveAttendanceMediaAsync(attendanceMediaModel);
                var failedResult = saveResults.FirstOrDefault(r => r.Result != Result.Success);
                if (failedResult != null)
                {
                    result.Result = failedResult.Result;
                    result.Message = failedResult.Message;
                    return result;
                }
            }

            // Cập nhật trạng thái xe của tài xế (nếu có) thành "Dừng đỗ"
            await UpdateUserTruckOperatingStatus(model.UserId, OperatingStatus.Stop);

            // Lấy thông tin chi tiết của attendance sau khi check-out để trả về
            var attendanceItem = await GetAttendanceItemById(attendance.Id);

            result.Result = Result.Success;
            result.Message = "Check-out thành công";
            result.Item = attendanceItem;
            result.ActionType = "CheckOut";
            result.ActionTime = currentTime;
            result.IsCheckIn = false;

            return result;
        }

        #endregion


        #region Admin Functions


        /// <summary>
        /// Tìm kiếm bản ghi chấm công theo điều kiện.
        /// </summary>
        /// <param name="param">Tham số SmartTableParam.</param>
        /// <returns>Kết quả tìm kiếm bản ghi chấm công.</returns>
        public async Task<SmartTableResult<AttendanceItem>> SearchAsync(SmartTableParam param)
        {
            var query = _attendanceRepository.Query();

            if (param.Search.PredicateObject != null)
            {
                dynamic search = param.Search.PredicateObject;
                if (search.UserId != null)
                {
                    int userId = search.UserId;
                    query = query.Where(x => x.UserId == userId);
                }
                if (search.CheckInStart != null && search.CheckInEnd != null)
                {
                    DateTimeOffset start = search.CheckInStart;
                    DateTimeOffset end = search.CheckInEnd;
                    DateTimeOffset startParam = start.ToLocalTime().StartOfDay();
                    DateTimeOffset endParam = end.ToLocalTime().EndOfDay();
                    query = query.Where(x => x.CheckInTime >= startParam && x.CheckInTime <= endParam);
                }
                if (search.CheckOutStart != null && search.CheckOutEnd != null)
                {
                    DateTimeOffset start = search.CheckOutStart;
                    DateTimeOffset end = search.CheckOutEnd;
                    DateTimeOffset startParam = start.ToLocalTime().StartOfDay();
                    DateTimeOffset endParam = end.ToLocalTime().EndOfDay();
                    query = query.Where(x => x.CheckOutTime >= startParam && x.CheckOutTime <= endParam);
                }
            }

            // Thực hiện Include sau cùng - bao gồm cả AttendanceMedias và Media
            var queryWithIncludes = query
                .Include(x => x.User)
                .Include(x => x.AttendanceMedias)
                .ThenInclude(am => am.Media);

            param.Sort = new Sort() { Predicate = "CheckInTime", Reverse = true };

            // Lấy dữ liệu với pagination trước
            var pagedAttendances = await queryWithIncludes.ToSmartTableResultAsync(param, x => x);

            // Tạo AttendanceItem với media
            var attendanceItems = new List<AttendanceItem>();
            if (pagedAttendances.Items.Count() > 0)
            {
                foreach (var attendance in pagedAttendances.Items)
                {
                    var item = attendance.ToItem();

                    if (attendance.AttendanceMedias != null && attendance.AttendanceMedias.Count > 0)
                    {
                        foreach (var attendanceMedia in attendance.AttendanceMedias)
                        {
                            if (attendanceMedia.Media != null)
                            {
                                var mediaItem = new AttendanceMediaItem
                                {
                                    Id = attendanceMedia.Media.Id,
                                    AltText = attendanceMedia.Media.AltText ?? string.Empty,
                                    Caption = attendanceMedia.Media.Caption ?? string.Empty,
                                    DisplayOrder = attendanceMedia.Media.DisplayOrder,
                                    Url = await _unifiedMediaService.GetUrlBySystemPathAsync(attendanceMedia.Media.SystemPath)
                                };

                                if (attendanceMedia.Type == AttendanceMediaType.CheckIn)
                                {
                                    item.CheckInMedias.Add(mediaItem);
                                }
                                else if (attendanceMedia.Type == AttendanceMediaType.CheckOut)
                                {
                                    item.CheckOutMedias.Add(mediaItem);
                                }
                            }
                        }
                    }

                    attendanceItems.Add(item);

                }
            }


            // Tạo SmartTableResult thủ công
            var totalRecord = queryWithIncludes.Count();
            var gridData = new SmartTableResult<AttendanceItem>
            {
                Items = attendanceItems,
                TotalRecord = totalRecord,
                NumberOfPages = (int)Math.Ceiling((double)totalRecord / param.Pagination.PageSize)
            };

            return gridData;
        }

        /// <summary>
        /// Tạo mới bản ghi chấm công.
        /// </summary>
        /// <param name="attendance">Đối tượng Attendance.</param>
        /// <returns>Bản ghi Attendance đã tạo.</returns>
        public async Task<Attendance> CreateAsync(Attendance attendance)
        {
            attendance.Id = Guid.NewGuid();
            await _attendanceRepository.InsertAsync(attendance);
            return attendance;
        }

        /// <summary>
        /// Cập nhật bản ghi chấm công.
        /// </summary>
        /// <param name="attendance">Đối tượng Attendance cần cập nhật.</param>
        /// <returns>Bản ghi Attendance đã cập nhật.</returns>
        public async Task<Attendance> UpdateAsync(Attendance attendance)
        {
            await _attendanceRepository.UpdateAsync(attendance);
            return attendance;
        }

        /// <summary>
        /// Xóa bản ghi chấm công theo Id.
        /// </summary>
        /// <param name="id">Id bản ghi chấm công.</param>
        /// <returns>True nếu xóa thành công, ngược lại false.</returns>
        public async Task<bool> DeleteAsync(Guid id)
        {
            var attendance = await _attendanceRepository.GetByIdAsync(id);
            if (attendance == null)
                return false;
            await _attendanceRepository.DeleteAsync(attendance);
            return true;
        }

        /// <summary>
        /// Lấy thông tin bản ghi chấm công theo Id.
        /// </summary>
        /// <param name="id">Id bản ghi chấm công.</param>
        /// <returns>Bản ghi Attendance nếu tìm thấy, ngược lại null.</returns>
        public async Task<Attendance> GetByIdAsync(Guid id)
        {
            return await _attendanceRepository.GetByIdAsync(id);
        }

        /// <summary>
        /// Xuất danh sách chấm công ra file Excel.
        /// </summary>
        /// <param name="param">Tham số SmartTableParam.</param>
        /// <param name="filePath">Đường dẫn file Excel.</param>
        /// <returns>Kết quả xuất file.</returns>
        public async Task<ExportResult> ExportToExcelAsync(SmartTableParam param, string filePath)
        {
            var result = new ExportResult();

            try
            {
                // Lấy dữ liệu chấm công (không cần media cho Excel)
                var query = _attendanceRepository.Query();

                if (param.Search.PredicateObject != null)
                {
                    dynamic search = param.Search.PredicateObject;
                    if (search.UserId != null)
                    {
                        int userId = search.UserId;
                        query = query.Where(x => x.UserId == userId);
                    }
                    if (search.CheckInStart != null && search.CheckInEnd != null)
                    {
                        DateTimeOffset start = search.CheckInStart;
                        DateTimeOffset end = search.CheckInEnd;
                        DateTimeOffset startParam = start.StartOfDay();
                        DateTimeOffset endParam = end.EndOfDay();
                        query = query.Where(x => x.CheckInTime >= startParam && x.CheckInTime <= endParam);
                    }
                    if (search.CheckOutStart != null && search.CheckOutEnd != null)
                    {
                        DateTimeOffset start = search.CheckOutStart;
                        DateTimeOffset end = search.CheckOutEnd;
                        DateTimeOffset startParam = start.StartOfDay();
                        DateTimeOffset endParam = end.EndOfDay();
                        query = query.Where(x => x.CheckOutTime >= startParam && x.CheckOutTime <= endParam);
                    }
                }

                // Include User để lấy thông tin user
                var queryWithUser = query.Include(x => x.User)
                    .OrderByDescending(x => x.CheckInTime);

                var attendances = await queryWithUser.ToListAsync();

                // Tạo file Excel
                var excelFile = new FileInfo(filePath);
                using (var package = new ExcelPackage(excelFile))
                {
                    var worksheet = package.Workbook.Worksheets.Add("Danh sách chấm công");

                    // Thiết lập header
                    worksheet.Cells[1, 1].Value = "STT";
                    worksheet.Cells[1, 2].Value = "Tên đăng nhập";
                    worksheet.Cells[1, 3].Value = "Họ và tên";
                    worksheet.Cells[1, 4].Value = "Thời gian check-in";
                    worksheet.Cells[1, 5].Value = "Thời gian check-out";
                    worksheet.Cells[1, 6].Value = "Tổng thời gian (giờ)";

                    // Định dạng header
                    using (var range = worksheet.Cells[1, 1, 1, 6])
                    {
                        range.Style.Font.Bold = true;
                        range.Style.Font.Name = "Times New Roman";
                        range.Style.Font.Size = 11;
                        range.Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;
                        range.Style.VerticalAlignment = ExcelVerticalAlignment.Center;
                        range.Style.Fill.BackgroundColor.SetColor(System.Drawing.Color.LightGray);
                        range.Style.Border.BorderAround(ExcelBorderStyle.Thin);
                    }

                    // Điền dữ liệu
                    int row = 2;
                    int stt = 1;
                    foreach (var attendance in attendances)
                    {
                        worksheet.Cells[row, 1].Value = stt;
                        worksheet.Cells[row, 2].Value = attendance.User?.UserName ?? "";
                        worksheet.Cells[row, 3].Value = attendance.User?.FullName ?? "";
                        worksheet.Cells[row, 4].Value = attendance.CheckInTime.ToString("dd/MM/yyyy HH:mm");
                        worksheet.Cells[row, 5].Value = attendance.CheckOutTime?.ToString("dd/MM/yyyy HH:mm") ?? "";

                        // Tính tổng thời gian làm việc
                        if (attendance.CheckOutTime.HasValue)
                        {
                            var workingHours = (attendance.CheckOutTime.Value - attendance.CheckInTime).TotalHours;
                            worksheet.Cells[row, 6].Value = Math.Round(workingHours, 2);
                        }
                        else
                        {
                            worksheet.Cells[row, 6].Value = "";
                        }

                        // Định dạng dữ liệu
                        using (var range = worksheet.Cells[row, 1, row, 6])
                        {
                            range.Style.Font.Name = "Times New Roman";
                            range.Style.Font.Size = 11;
                            range.Style.VerticalAlignment = ExcelVerticalAlignment.Center;
                            range.Style.Border.BorderAround(ExcelBorderStyle.Thin);
                        }

                        row++;
                        stt++;
                    }

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

                    // Lưu file
                    await package.SaveAsync();
                }

                result.Result = Result.Success;
                result.Message = "Xuất file Excel thành công";
                result.Url = filePath;
            }
            catch (Exception ex)
            {
                result.Result = Result.SystemError;
                result.Message = $"Lỗi khi xuất file Excel: {ex.Message}";
            }

            return result;
        }

        /// <summary>
        /// Lấy thông tin chi tiết của một bản ghi chấm công theo ID
        /// </summary>
        /// <param name="attendanceId">ID của bản ghi chấm công</param>
        /// <returns>Thông tin chi tiết của bản ghi chấm công</returns>
        private async Task<AttendanceItem?> GetAttendanceItemById(Guid attendanceId)
        {
            var attendance = await _attendanceRepository.Query()
                .Include(a => a.User)
                .Include(a => a.AttendanceMedias).ThenInclude(am => am.Media)
                .Where(a => a.Id == attendanceId)
                .FirstOrDefaultAsync();

            if (attendance == null)
                return null;

            var attendanceItem = new AttendanceItem
            {
                Id = attendance.Id,
                UserId = attendance.UserId,
                UserName = attendance.User?.UserName ?? "",
                UserFullName = attendance.User?.FullName ?? "",
                CheckInTime = attendance.CheckInTime.ToString("dd/MM/yyyy HH:mm"),
                CheckOutTime = attendance.CheckOutTime?.ToString("dd/MM/yyyy HH:mm") ?? "",
                CheckInOdo = attendance.CheckInOdo,
                CheckOutOdo = attendance.CheckOutOdo
            };

            // Lấy ảnh check-in và chuyển đổi SystemPath thành URL
            var checkInMedias = attendance.AttendanceMedias
                .Where(am => am.Type == AttendanceMediaType.CheckIn)
                .OrderBy(am => am.Media?.DisplayOrder ?? 0)
                .ToList();

            attendanceItem.CheckInMedias = new List<AttendanceMediaItem>();
            foreach (var am in checkInMedias)
            {
                var mediaItem = new AttendanceMediaItem
                {
                    Id = am.MediaId,
                    Url = !string.IsNullOrEmpty(am.Media?.SystemPath)
                        ? await _unifiedMediaService.GetUrlBySystemPathAsync(am.Media.SystemPath)
                        : "",
                    AltText = am.Media?.AltText ?? "",
                    Caption = am.Media?.Caption ?? "",
                    DisplayOrder = am.Media?.DisplayOrder ?? 0
                };
                attendanceItem.CheckInMedias.Add(mediaItem);
            }

            // Lấy ảnh check-out và chuyển đổi SystemPath thành URL
            var checkOutMedias = attendance.AttendanceMedias
                .Where(am => am.Type == AttendanceMediaType.CheckOut)
                .OrderBy(am => am.Media?.DisplayOrder ?? 0)
                .ToList();

            attendanceItem.CheckOutMedias = new List<AttendanceMediaItem>();
            foreach (var am in checkOutMedias)
            {
                var mediaItem = new AttendanceMediaItem
                {
                    Id = am.MediaId,
                    Url = !string.IsNullOrEmpty(am.Media?.SystemPath)
                        ? await _unifiedMediaService.GetUrlBySystemPathAsync(am.Media.SystemPath)
                        : "",
                    AltText = am.Media?.AltText ?? "",
                    Caption = am.Media?.Caption ?? "",
                    DisplayOrder = am.Media?.DisplayOrder ?? 0
                };
                attendanceItem.CheckOutMedias.Add(mediaItem);
            }

            return attendanceItem;
        }

        /// <summary>
        /// Lấy thông tin chấm công hiện tại của người dùng (chưa check-out hoặc hôm nay)
        /// </summary>
        /// <param name="userId">ID người dùng</param>
        /// <returns>Thông tin chấm công hiện tại</returns>
        public async Task<AttendanceItem?> GetCurrentAttendance(int userId)
        {
            var currentTime = DateTimeHelper.CurrentTime();
            var today = currentTime.Date;

            // Tìm attendance hôm nay và chưa check-out
            var attendance = await _attendanceRepository.Query()
                .Include(a => a.User)
                .Include(a => a.AttendanceMedias).ThenInclude(am => am.Media)
                .Where(a => a.UserId == userId &&
                           a.CheckInTime.Date == today &&
                           a.CheckOutTime == null)
                .OrderByDescending(a => a.CheckInTime)
                .FirstOrDefaultAsync();

            if (attendance == null)
                return null;

            return await GetAttendanceItemById(attendance.Id);
        }

        /// <summary>
        /// Cập nhật trạng thái hoạt động của xe mà người dùng đang phụ trách
        /// </summary>
        /// <param name="userId">ID người dùng</param>
        /// <param name="operatingStatus">Trạng thái hoạt động mới</param>
        private async Task UpdateUserTruckOperatingStatus(int userId, OperatingStatus operatingStatus)
        {
            try
            {
                // Tìm xe mà người dùng đang phụ trách
                var userTruck = await _truckRepository.Query()
                    .FirstOrDefaultAsync(t => t.CurrentDriverId == userId);

                if (userTruck != null)
                {
                    userTruck.OperatingStatus = operatingStatus;
                    await _truckRepository.UpdateAsync(userTruck);
                }
            }
            catch (Exception ex)
            {
                // Log error nhưng không làm fail toàn bộ quá trình chấm công
                // Có thể log: $"Lỗi khi cập nhật trạng thái xe cho user {userId}: {ex.Message}"
            }
        }

        #endregion

        #region PRIVATE METHODS

        /// <summary>
        /// Lưu media cho attendance (check-in/check-out)
        /// </summary>
        /// <param name="model">Model chứa thông tin attendance media</param>
        /// <returns>Danh sách kết quả lưu media</returns>
        private async Task<List<SaveMediaResult>> SaveAttendanceMediaAsync(AttendanceMediaModel model)
        {
            var results = new List<SaveMediaResult>();

            if (model.Files == null || !model.Files.Any())
            {
                return results;
            }

            try
            {
                var currentTime = DateTimeHelper.CurrentTime();

                for (int i = 0; i < model.Files.Count; i++)
                {
                    var file = model.Files[i];
                    var saveResult = new SaveMediaResult
                    {
                        InputFilename = file.FileName,
                        Result = Result.Success
                    };

                    try
                    {
                        // Xử lý ảnh bằng UnifiedMediaService (không lưu database)
                        var processResult = await _unifiedMediaService.ProcessImageAsync(file, ImageType.Attendance);

                        if (processResult.Result == Result.Success)
                        {
                            // Tạo Media entity thủ công
                            var media = new Media
                            {
                                Id = Guid.NewGuid(),
                                SystemPath = processResult.SystemPath,
                                AltText = $"Ảnh chấm công {(model.AttendanceMediaType == AttendanceMediaType.CheckIn ? "vào" : "ra")}",
                                Caption = $"Ảnh chấm công {(model.AttendanceMediaType == AttendanceMediaType.CheckIn ? "vào" : "ra")}",
                                DisplayOrder = i,
                                CreatedTime = currentTime,
                                UpdatedTime = currentTime,
                                CreatedBy = model.UpdatedBy,
                                CreatedByUserName = model.UpdatedByUserName,
                                UpdatedBy = model.UpdatedBy,
                                UpdatedByUserName = model.UpdatedByUserName
                            };

                            // Lưu Media entity
                            await _mediaRepository.InsertAsync(media);

                            // Tạo relationship AttendanceMedia
                            var attendanceMedia = new AttendanceMedia
                            {
                                AttendanceId = model.AttendanceId,
                                MediaId = media.Id,
                                Type = model.AttendanceMediaType,
                                CreatedTime = currentTime,
                                UpdatedTime = currentTime,
                                CreatedBy = model.UpdatedBy,
                                CreatedByUserName = model.UpdatedByUserName,
                                UpdatedBy = model.UpdatedBy,
                                UpdatedByUserName = model.UpdatedByUserName
                            };

                            await _attendanceMediaRepository.InsertAsync(attendanceMedia);

                            saveResult.OutputFileName = processResult.SystemPath;
                            saveResult.Url = processResult.Url;
                            saveResult.Message = "Lưu ảnh chấm công thành công";
                        }
                        else
                        {
                            saveResult.Result = processResult.Result;
                            saveResult.Message = processResult.Message;
                        }
                    }
                    catch (Exception ex)
                    {
                        saveResult.Result = Result.SystemError;
                        saveResult.Message = $"Lỗi xử lý file {file.FileName}: {ex.Message}";
                    }

                    results.Add(saveResult);
                }
            }
            catch (Exception ex)
            {
                // Trả về lỗi chung nếu có exception
                results.Add(new SaveMediaResult
                {
                    Result = Result.SystemError,
                    Message = $"Lỗi hệ thống khi lưu media: {ex.Message}"
                });
            }

            return results;
        }

        #endregion

        #region Report Functions

        /// <summary>
        /// Lấy tổng hợp số công của tất cả nhân viên theo tháng
        /// </summary>
        /// <param name="month">Tháng (1-12)</param>
        /// <param name="year">Năm (ví dụ: 2025)</param>
        /// <returns>Danh sách tổng hợp số công của nhân viên</returns>
        public async Task<List<AttendanceSummaryItem>> GetAttendanceSummaryByMonthAsync(int month, int year)
        {
            const string storedProcedure = "sp_GetAttendanceSummaryByMonth";

            var parameters = new DynamicParameters();
            parameters.Add("Month", month);
            parameters.Add("Year", year);

            var result = await _dbConnection.QueryAsync<AttendanceSummaryItem>(
                storedProcedure,
                parameters,
                commandType: CommandType.StoredProcedure
            );

            return result.ToList();
        }

        /// <summary>
        /// Lấy chi tiết công từng ngày của một nhân viên theo tháng
        /// </summary>
        /// <param name="month">Tháng (1-12)</param>
        /// <param name="year">Năm (ví dụ: 2025)</param>
        /// <param name="userId">ID nhân viên</param>
        /// <returns>Danh sách chi tiết công từng ngày</returns>
        public async Task<List<AttendanceDetailItem>> GetAttendanceDetailByUserAsync(int month, int year, int userId)
        {
            const string storedProcedure = "sp_GetAttendanceDetailByUser";

            var parameters = new DynamicParameters();
            parameters.Add("Month", month);
            parameters.Add("Year", year);
            parameters.Add("UserId", userId);

            var result = await _dbConnection.QueryAsync<AttendanceDetailItem>(
                storedProcedure,
                parameters,
                commandType: CommandType.StoredProcedure
            );

            return result.ToList();
        }

        #endregion

    }
}