using System.Data;
using Dapper;
using Lada.Framework.Data.Domains.Hr;
using Lada.Framework.Data.Domains.Trucks;
using Lada.Framework.Data.Repositories;
using Lada.Framework.Infrastructures.Helpers;
using Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp;
using Ladaer.BackEnd.Infrastructures.Services.Hr;
using Ladaer.BackEnd.Infrastructures.Services.Trucks;
using Microsoft.EntityFrameworkCore;

namespace Ladaer.BackEnd.Infrastructures.Services.DriverApp
{
    public interface IDriverAppService
    {
        Task<DashboardModel> GetDashboard(int userId);
    }

    public class DriverAppService : IDriverAppService
    {
        private readonly IDbConnection _dbConnection;
        private readonly IAttendanceService _attendanceService;
        private readonly ITruckActivityService _truckActivityService;
        private readonly IRepository<Attendance> _attendanceRepository;
        private readonly IRepository<TruckActivity> _truckActivityRepository;

        public DriverAppService(
            IDbConnection dbConnection,
            IAttendanceService attendanceService,
            ITruckActivityService truckActivityService,
            IRepository<Attendance> attendanceRepository,
            IRepository<TruckActivity> truckActivityRepository)
        {
            _dbConnection = dbConnection;
            _attendanceService = attendanceService;
            _truckActivityService = truckActivityService;
            _attendanceRepository = attendanceRepository;
            _truckActivityRepository = truckActivityRepository;
        }

        public async Task<DashboardModel> GetDashboard(int userId)
        {
            // Lấy thông tin cơ bản từ stored procedure
            const string storedProcedure = "MobileApp_Driver_GetDashboard";
            var parameters = new { UserId = userId };

            var result = await _dbConnection.QueryFirstOrDefaultAsync<DashboardModel>(
                storedProcedure,
                parameters,
                commandType: CommandType.StoredProcedure
            ) ?? new DashboardModel();

            // Lấy thông tin chấm công
            await LoadAttendanceInfo(result, userId);

            // Lấy thông tin xe đang phụ trách
            await LoadCurrentTruckInfo(result, userId);

            return result;
        }

        /// <summary>
        /// Lấy thông tin chấm công của người dùng
        /// </summary>
        private async Task LoadAttendanceInfo(DashboardModel dashboard, int userId)
        {
            try
            {
                var currentTime = DateTimeHelper.CurrentTime();
                var today = currentTime.Date;

                // Tìm attendance chưa check-out
                var currentAttendance = await _attendanceService.GetCurrentAttendance(userId);
                if (currentAttendance != null)
                {
                    dashboard.CurrentAttendance = currentAttendance;
                    dashboard.HasCheckedInToday = true;
                    dashboard.TodayCheckInTime = currentAttendance.CheckInTime;
                    dashboard.TodayCheckInOdo = currentAttendance.CheckInOdo;

                    if (!string.IsNullOrEmpty(currentAttendance.CheckOutTime))
                    {
                        dashboard.HasCheckedOutToday = true;
                        dashboard.TodayCheckOutTime = currentAttendance.CheckOutTime;
                        dashboard.TodayCheckOutOdo = currentAttendance.CheckOutOdo;
                    }
                }
            }
            catch (Exception ex)
            {
                // Log error but don't fail the entire dashboard
                // dashboard.AttendanceError = ex.Message;
            }
        }

        /// <summary>
        /// Lấy thông tin xe đang phụ trách
        /// </summary>
        private async Task LoadCurrentTruckInfo(DashboardModel dashboard, int userId)
        {
            try
            {
                var currentTruckResult = await _truckActivityService.GetCurrentUserTruck(userId);
                if (currentTruckResult?.Items?.Any() == true)
                {
                    var currentTruck = currentTruckResult.Items.First();
                    dashboard.CurrentTruck = currentTruck;
                    dashboard.HasAssignedTruck = true;
                    dashboard.CurrentTruckLicensePlate = currentTruck.LicensePlate;
                    dashboard.CurrentTruckAgencyName = currentTruck.AgencyName;

                    // Lấy ODO gần nhất của xe
                    dashboard.CurrentTruckLatestOdo = await GetLatestTruckOdo(currentTruck.Id, userId);
                }
            }
            catch (Exception ex)
            {
                // Log error but don't fail the entire dashboard
                // dashboard.TruckError = ex.Message;
            }
        }

        /// <summary>
        /// Lấy ODO gần nhất của xe từ các hoạt động (chấm công hoặc bàn giao xe)
        /// </summary>
        /// <param name="truckId">ID xe tải</param>
        /// <param name="userId">ID người dùng</param>
        /// <returns>ODO gần nhất</returns>
        private async Task<int?> GetLatestTruckOdo(int truckId, int userId)
        {
            try
            {
                // Lấy ODO từ attendance gần nhất của user
                var latestAttendance = await _attendanceRepository.Query()
                    .Where(a => a.UserId == userId)
                    .OrderByDescending(a => a.CheckOutTime ?? a.CheckInTime)
                    .FirstOrDefaultAsync();

                var latestAttendanceOdo = latestAttendance != null
                    ? (latestAttendance.CheckOutOdo ?? latestAttendance.CheckInOdo)
                    : (int?)null;

                // Lấy ODO từ truck activity gần nhất của xe này
                var latestTruckActivityOdo = await _truckActivityRepository.Query()
                    .Where(ta => ta.TruckId == truckId && ta.CurrentOdo != null)
                    .OrderByDescending(ta => ta.CreatedTime)
                    .Select(ta => ta.CurrentOdo)
                    .FirstOrDefaultAsync();

                // Trả về ODO mới nhất (ưu tiên attendance vì đó là hoạt động gần đây nhất)
                return latestAttendanceOdo ?? latestTruckActivityOdo;
            }
            catch (Exception ex)
            {
                // Log error nhưng không làm fail
                return null;
            }
        }
    }
}