using AutoMapper;
using PowderCoating.Core.Entities;
using PowderCoating.Application.DTOs.Appointment;

namespace PowderCoating.Application.Mappings;

public class AppointmentProfile : Profile
{
    public AppointmentProfile()
    {
        // Appointment to AppointmentDto - Map all lookup properties from navigation
        CreateMap<Appointment, AppointmentDto>()
            // Customer mappings (nullable for internal appointments)
            .ForMember(dest => dest.CustomerName,
                      opt => opt.MapFrom(src => src.Customer != null
                          ? (!string.IsNullOrWhiteSpace(src.Customer.CompanyName)
                              ? src.Customer.CompanyName
                              : $"{src.Customer.ContactFirstName} {src.Customer.ContactLastName}".Trim())
                          : null))
            .ForMember(dest => dest.CustomerPhone,
                      opt => opt.MapFrom(src => src.Customer != null ? src.Customer.Phone : null))
            .ForMember(dest => dest.CustomerEmail,
                      opt => opt.MapFrom(src => src.Customer != null ? src.Customer.Email : null))
            // Job mappings (optional)
            .ForMember(dest => dest.JobNumber,
                      opt => opt.MapFrom(src => src.Job != null ? src.Job.JobNumber : null))
            // Worker assignment
            .ForMember(dest => dest.AssignedWorkerName,
                      opt => opt.MapFrom(src => src.AssignedUser != null ? src.AssignedUser.FullName : null))
            // Appointment Type lookup mappings
            .ForMember(dest => dest.AppointmentTypeId, opt => opt.MapFrom(src => src.AppointmentTypeId))
            .ForMember(dest => dest.TypeCode, opt => opt.MapFrom(src => src.AppointmentType.TypeCode))
            .ForMember(dest => dest.TypeDisplayName, opt => opt.MapFrom(src => src.AppointmentType.DisplayName))
            .ForMember(dest => dest.TypeColorClass, opt => opt.MapFrom(src => src.AppointmentType.ColorClass))
            .ForMember(dest => dest.TypeIconClass, opt => opt.MapFrom(src => src.AppointmentType.IconClass))
            .ForMember(dest => dest.TypeRequiresJobLink, opt => opt.MapFrom(src => src.AppointmentType.RequiresJobLink))
            // Appointment Status lookup mappings
            .ForMember(dest => dest.AppointmentStatusId, opt => opt.MapFrom(src => src.AppointmentStatusId))
            .ForMember(dest => dest.StatusCode, opt => opt.MapFrom(src => src.AppointmentStatus.StatusCode))
            .ForMember(dest => dest.StatusDisplayName, opt => opt.MapFrom(src => src.AppointmentStatus.DisplayName))
            .ForMember(dest => dest.StatusColorClass, opt => opt.MapFrom(src => src.AppointmentStatus.ColorClass))
            .ForMember(dest => dest.StatusIconClass, opt => opt.MapFrom(src => src.AppointmentStatus.IconClass))
            .ForMember(dest => dest.StatusIsTerminal, opt => opt.MapFrom(src => src.AppointmentStatus.IsTerminalStatus));

        // Appointment to AppointmentListDto - Lightweight for grid views
        CreateMap<Appointment, AppointmentListDto>()
            .ForMember(dest => dest.CustomerName,
                      opt => opt.MapFrom(src => src.Customer != null
                          ? (!string.IsNullOrWhiteSpace(src.Customer.CompanyName)
                              ? src.Customer.CompanyName
                              : $"{src.Customer.ContactFirstName} {src.Customer.ContactLastName}".Trim())
                          : null))
            .ForMember(dest => dest.AssignedWorkerName,
                      opt => opt.MapFrom(src => src.AssignedUser != null ? src.AssignedUser.FullName : null))
            // Type lookup mappings
            .ForMember(dest => dest.TypeDisplayName, opt => opt.MapFrom(src => src.AppointmentType.DisplayName))
            .ForMember(dest => dest.TypeColorClass, opt => opt.MapFrom(src => src.AppointmentType.ColorClass))
            // Status lookup mappings
            .ForMember(dest => dest.StatusDisplayName, opt => opt.MapFrom(src => src.AppointmentStatus.DisplayName))
            .ForMember(dest => dest.StatusColorClass, opt => opt.MapFrom(src => src.AppointmentStatus.ColorClass));

        // Appointment to CalendarEventDto - For calendar JSON API
        CreateMap<Appointment, CalendarEventDto>()
            .ForMember(dest => dest.Start,
                      opt => opt.MapFrom(src => src.ScheduledStartTime.ToString("yyyy-MM-ddTHH:mm:ss")))
            .ForMember(dest => dest.End,
                      opt => opt.MapFrom(src => src.ScheduledEndTime.ToString("yyyy-MM-ddTHH:mm:ss")))
            .ForMember(dest => dest.AllDay, opt => opt.MapFrom(src => src.IsAllDay))
            .ForMember(dest => dest.CustomerName,
                      opt => opt.MapFrom(src => src.Customer != null
                          ? (!string.IsNullOrWhiteSpace(src.Customer.CompanyName)
                              ? src.Customer.CompanyName
                              : $"{src.Customer.ContactFirstName} {src.Customer.ContactLastName}".Trim())
                          : "Internal"))
            .ForMember(dest => dest.TypeDisplayName, opt => opt.MapFrom(src => src.AppointmentType.DisplayName))
            .ForMember(dest => dest.StatusCode, opt => opt.MapFrom(src => src.AppointmentStatus.StatusCode))
            // Calendar colors based on appointment type color class
            .ForMember(dest => dest.BackgroundColor,
                      opt => opt.MapFrom(src => GetBootstrapColor(src.AppointmentType.ColorClass)))
            .ForMember(dest => dest.BorderColor,
                      opt => opt.MapFrom(src => GetBootstrapColor(src.AppointmentType.ColorClass)))
            .ForMember(dest => dest.TextColor, opt => opt.MapFrom(src => "#ffffff"));

        // CreateAppointmentDto to Appointment
        CreateMap<CreateAppointmentDto, Appointment>()
            .ForMember(dest => dest.AppointmentNumber, opt => opt.Ignore()) // Generated by system
            .ForMember(dest => dest.AppointmentStatusId, opt => opt.Ignore()) // Set to default "SCHEDULED" by controller
            .ForMember(dest => dest.AppointmentStatus, opt => opt.Ignore()) // Will be set by FK
            .ForMember(dest => dest.AppointmentType, opt => opt.Ignore()); // Will be set by FK

        // QuickCreateAppointmentDto to Appointment (for calendar quick create)
        CreateMap<QuickCreateAppointmentDto, Appointment>()
            .ForMember(dest => dest.AppointmentNumber, opt => opt.Ignore())
            .ForMember(dest => dest.AppointmentStatusId, opt => opt.Ignore())
            .ForMember(dest => dest.AppointmentStatus, opt => opt.Ignore())
            .ForMember(dest => dest.AppointmentType, opt => opt.Ignore())
            .ForMember(dest => dest.Description, opt => opt.MapFrom(src => (string?)null))
            .ForMember(dest => dest.Location, opt => opt.MapFrom(src => (string?)null))
            .ForMember(dest => dest.Notes, opt => opt.MapFrom(src => (string?)null))
            .ForMember(dest => dest.IsReminderEnabled, opt => opt.MapFrom(src => true))
            .ForMember(dest => dest.ReminderMinutesBefore, opt => opt.MapFrom(src => 30));

        // UpdateAppointmentDto to Appointment
        CreateMap<UpdateAppointmentDto, Appointment>()
            .ForMember(dest => dest.AppointmentNumber, opt => opt.Ignore()) // Cannot be changed
            .ForMember(dest => dest.AppointmentStatus, opt => opt.Ignore()) // Will be set by FK
            .ForMember(dest => dest.AppointmentType, opt => opt.Ignore()); // Will be set by FK

        // Appointment to UpdateAppointmentDto (needed for Edit GET action)
        CreateMap<Appointment, UpdateAppointmentDto>()
            .ForMember(dest => dest.AppointmentStatusId, opt => opt.MapFrom(src => src.AppointmentStatusId))
            .ForMember(dest => dest.AppointmentTypeId, opt => opt.MapFrom(src => src.AppointmentTypeId));
    }

    /// <summary>
    /// Maps Bootstrap color class names to hex color codes for calendar events
    /// </summary>
    private static string GetBootstrapColor(string colorClass)
    {
        return colorClass.ToLower() switch
        {
            "primary" => "#0d6efd",
            "secondary" => "#6c757d",
            "success" => "#198754",
            "danger" => "#dc3545",
            "warning" => "#ffc107",
            "info" => "#0dcaf0",
            "light" => "#f8f9fa",
            "dark" => "#212529",
            // Custom color names for appointment types
            "purple" => "#6f42c1",
            "green" => "#198754",
            "blue" => "#0d6efd",
            "orange" => "#fd7e14",
            "red" => "#dc3545",
            "yellow" => "#ffc107",
            "cyan" => "#0dcaf0",
            "pink" => "#d63384",
            "gray" => "#6c757d",
            _ => "#0d6efd" // Default to primary blue
        };
    }
}
