using AutoMapper;
using Marco.Pms.Model.AppMenu;
using Marco.Pms.Model.Collection;
using Marco.Pms.Model.Directory;
using Marco.Pms.Model.DocumentManager;
using Marco.Pms.Model.Dtos.Activities;
using Marco.Pms.Model.Dtos.AppMenu;
using Marco.Pms.Model.Dtos.Collection;
using Marco.Pms.Model.Dtos.Directory;
using Marco.Pms.Model.Dtos.DocumentManager;
using Marco.Pms.Model.Dtos.Employees;
using Marco.Pms.Model.Dtos.Expenses;
using Marco.Pms.Model.Dtos.Expenses.Masters;
using Marco.Pms.Model.Dtos.Master;
using Marco.Pms.Model.Dtos.Organization;
using Marco.Pms.Model.Dtos.Project;
using Marco.Pms.Model.Dtos.ServiceProject;
using Marco.Pms.Model.Dtos.Tenant;
using Marco.Pms.Model.Employees;
using Marco.Pms.Model.Entitlements;
using Marco.Pms.Model.Expenses;
using Marco.Pms.Model.Expenses.Masters;
using Marco.Pms.Model.Master;
using Marco.Pms.Model.MongoDBModels;
using Marco.Pms.Model.MongoDBModels.Employees;
using Marco.Pms.Model.MongoDBModels.Expenses;
using Marco.Pms.Model.MongoDBModels.Masters;
using Marco.Pms.Model.MongoDBModels.Project;
using Marco.Pms.Model.OrganizationModel;
using Marco.Pms.Model.Projects;
using Marco.Pms.Model.ServiceProject;
using Marco.Pms.Model.TenantModels;
using Marco.Pms.Model.TenantModels.MongoDBModel;
using Marco.Pms.Model.ViewModels.Activities;
using Marco.Pms.Model.ViewModels.Collection;
using Marco.Pms.Model.ViewModels.Directory;
using Marco.Pms.Model.ViewModels.DocumentManager;
using Marco.Pms.Model.ViewModels.Employee;
using Marco.Pms.Model.ViewModels.Expanses;
using Marco.Pms.Model.ViewModels.Expenses;
using Marco.Pms.Model.ViewModels.Expenses.Masters;
using Marco.Pms.Model.ViewModels.Master;
using Marco.Pms.Model.ViewModels.Organization;
using Marco.Pms.Model.ViewModels.Projects;
using Marco.Pms.Model.ViewModels.ServiceProject;
using Marco.Pms.Model.ViewModels.Tenant;

namespace Marco.Pms.Services.MappingProfiles
{
    public class MappingProfile : Profile
    {
        public MappingProfile()
        {
            #region ======================================================= Organization =======================================================

            CreateMap<CreateOrganizationDto, Organization>();
            CreateMap<Organization, OrganizationVM>();
            CreateMap<Organization, BasicOrganizationVm>();
            CreateMap<Organization, OrganizationDetailsVM>();
            CreateMap<OrganizationMongoDB, BasicOrganizationVm>()
                .ForMember(
               dest => dest.Id,
               // Explicitly and safely convert string Id to Guid Id
               opt => opt.MapFrom(src => new Guid(src.Id))
           );

            #endregion

            #region ======================================================= Tenant =======================================================
            CreateMap<TenantEnquireDto, TenantEnquire>();
            CreateMap<Tenant, TenantVM>();
            CreateMap<Tenant, TenantListVM>();
            CreateMap<Tenant, TenantDetailsVM>();

            CreateMap<CreateTenantDto, Tenant>()
                .ForMember(
                    dest => dest.ContactName,
                    opt => opt.MapFrom(src => $"{src.FirstName} {src.LastName}")
                )
                .ForMember(
                    dest => dest.Name,
                    opt => opt.MapFrom(src => src.OrganizationName)
                );
            CreateMap<UpdateTenantDto, Tenant>()
                .ForMember(
                    dest => dest.ContactName,
                    opt => opt.MapFrom(src => $"{src.FirstName} {src.LastName}")
                );

            CreateMap<SubscriptionPlanDetails, SubscriptionPlanVM>()
                .ForMember(
                    dest => dest.PlanName,
                    opt => opt.MapFrom(src => src.Plan != null ? src.Plan.PlanName : "")
                )
                .ForMember(
                    dest => dest.Description,
                    opt => opt.MapFrom(src => src.Plan != null ? src.Plan.Description : "")
                );
            CreateMap<TenantSubscriptions, SubscriptionPlanDetailsVM>()
                .ForMember(
                    dest => dest.PlanName,
                    opt => opt.MapFrom(src => src.Plan!.Plan != null ? src.Plan.Plan.PlanName : "")
                )
                .ForMember(
                    dest => dest.Description,
                    opt => opt.MapFrom(src => src.Plan!.Plan != null ? src.Plan.Plan.Description : "")
                )
                .ForMember(
                    dest => dest.Price,
                    opt => opt.MapFrom(src => src.Plan != null ? src.Plan.Price : 0)
                )
                .ForMember(
                    dest => dest.Frequency,
                    opt => opt.MapFrom(src => src.Plan != null ? src.Plan.Frequency : PLAN_FREQUENCY.MONTHLY)
                );
            CreateMap<SubscriptionPlanDetailsDto, SubscriptionPlanDetails>();
            CreateMap<SubscriptionPlanDto, SubscriptionPlan>();

            CreateMap<FeatureDetailsDto, FeatureDetails>();
            CreateMap<SubscriptionCheckListDto, SubscriptionCheckList>();
            CreateMap<SupportDetailsDto, SupportDetails>();
            CreateMap<ReportDetailsDto, ReportDetails>();
            CreateMap<ModulesDetailsDto, ModulesDetails>();
            CreateMap<ProjectManagementDetailsDto, ProjectManagementDetails>();
            CreateMap<AttendanceDetailsDto, AttendanceDetails>();
            CreateMap<DirectoryDetailsDto, DirectoryDetails>();
            CreateMap<ExpenseModuleDetailsDto, ExpenseModuleDetails>();

            #endregion

            #region ======================================================= Projects =======================================================
            // Your mappings
            CreateMap<Project, ProjectVM>();
            CreateMap<Project, ProjectInfoVM>();
            CreateMap<Project, BasicProjectVM>();
            CreateMap<ProjectMongoDB, ProjectInfoVM>();
            CreateMap<UpdateProjectDto, Project>();
            CreateMap<Project, ProjectListVM>();
            CreateMap<Project, ProjectDto>();
            CreateMap<ProjectMongoDB, ProjectListVM>();
            CreateMap<ProjectServiceMapping, ProjectServiceMappingVM>();
            CreateMap<ProjectMongoDB, ProjectVM>()
           .ForMember(
               dest => dest.Id,
               // Explicitly and safely convert string Id to Guid Id
               opt => opt.MapFrom(src => new Guid(src.Id))
           );

            CreateMap<Project, ProjectBasicMongoDB>()
           .ForMember(
               dest => dest.Id,
               // Explicitly and safely convert Guid Id to string Id
               opt => opt.MapFrom(src => src.Id.ToString()))
           .ForMember(
                dest => dest.TenantId,
                opt => opt.MapFrom(src => src.TenantId.ToString()));
            CreateMap<ProjectBasicMongoDB, ProjectInfoVM>()
           .ForMember(
               dest => dest.Id,
               opt => opt.MapFrom(src => new Guid(src.Id)))
           .ForMember(
               dest => dest.ProjectStatusId,
               opt => opt.MapFrom(src => Guid.Empty)
           );

            CreateMap<ProjectMongoDB, Project>()
           .ForMember(
               dest => dest.Id,
               // Explicitly and safely convert string Id to Guid Id
               opt => opt.MapFrom(src => new Guid(src.Id))
           ).ForMember(
               dest => dest.ProjectStatusId,
               // Explicitly and safely convert string ProjectStatusId to Guid ProjectStatusId
               opt => opt.MapFrom(src => src.ProjectStatus == null ? Guid.Empty : new Guid(src.ProjectStatus.Id))
           );

            CreateMap<StatusMasterMongoDB, StatusMaster>();
            CreateMap<ProjectVM, Project>();
            CreateMap<CreateProjectDto, Project>();
            CreateMap<ProjectAllocationDot, ProjectAllocation>()
                .ForMember(
               dest => dest.EmployeeId,
               opt => opt.MapFrom(src => src.EmployeeId));
            CreateMap<ProjectsAllocationDto, ProjectAllocation>();
            CreateMap<ProjectAllocation, ProjectAllocationVM>();

            CreateMap<BuildingDto, Building>();
            CreateMap<FloorDto, Floor>();
            CreateMap<WorkAreaDto, WorkArea>();
            CreateMap<WorkItemDto, WorkItem>()
                .ForMember(
                    dest => dest.Description,
                    opt => opt.MapFrom(src => src.Comment));


            CreateMap<ServiceProjectDto, ServiceProject>();
            CreateMap<ServiceProject, ServiceProjectVM>();
            CreateMap<ServiceProject, ServiceProjectDetailsVM>();
            #endregion

            #region ======================================================= Employee =======================================================

            CreateMap<Employee, EmployeeVM>()
                .ForMember(
                dest => dest.JobRole,
                opt => opt.MapFrom(src => src.JobRole != null ? src.JobRole.Name : ""));
            CreateMap<CreateUserDto, Employee>();
            CreateMap<MobileUserManageDto, Employee>();

            CreateMap<Employee, BasicEmployeeVM>()
                .ForMember(
                dest => dest.JobRoleName,
                opt => opt.MapFrom(src => src.JobRole != null ? src.JobRole.Name : ""));

            CreateMap<Employee, BasicEmployeeMongoDB>()
                .ForMember(
                dest => dest.Id,
                opt => opt.MapFrom(src => src.Id.ToString()))
                .ForMember(
                dest => dest.JobRoleName,
                opt => opt.MapFrom(src => src.JobRole != null ? src.JobRole.Name : ""))
                .ForMember(
                dest => dest.JobRoleId,
                opt => opt.MapFrom(src => src.JobRoleId.ToString()))
                .ForMember(
                dest => dest.TenantId,
                opt => opt.MapFrom(src => src.TenantId.ToString()));
            CreateMap<BasicEmployeeMongoDB, BasicEmployeeVM>()
                .ForMember(
                    dest => dest.Id,
                    opt => opt.MapFrom(src => string.IsNullOrWhiteSpace(src.Id) ? Guid.Empty : Guid.Parse(src.Id)))
                .ForMember(
                    dest => dest.JobRoleId,
                    opt => opt.MapFrom(src => Guid.Parse(src.JobRoleId ?? "")));
            #endregion

            #region ======================================================= Finance =======================================================

            #region ======================================================= Expenses =======================================================

            CreateMap<Expenses, ExpenseList>();
            CreateMap<CreateExpensesDto, Expenses>();
            CreateMap<UpdateExpensesDto, Expenses>();
            CreateMap<ExpenseLog, ExpenseLogVM>();

            CreateMap<ExpensesReimburse, ExpensesReimburseVM>();
            CreateMap<Expenses, ExpenseDetailsMongoDB>()
                .ForMember(
                dest => dest.Id,
                opt => opt.MapFrom(src => src.Id.ToString()))
                .ForMember(
                dest => dest.TenantId,
                opt => opt.MapFrom(src => src.TenantId.ToString()));

            CreateMap<ExpenseDetailsMongoDB, Expenses>()
                .ForMember(
                dest => dest.Id,
                opt => opt.MapFrom(src => Guid.Parse(src.Id)))
                .ForMember(
                dest => dest.TenantId,
                opt => opt.MapFrom(src => Guid.Parse(src.TenantId)));

            CreateMap<ExpenseDetailsMongoDB, ExpenseList>()
                .ForMember(
                dest => dest.Id,
                opt => opt.MapFrom(src => Guid.Parse(src.Id)));

            CreateMap<Expenses, ExpenseDetailsVM>();
            CreateMap<ExpenseDetailsMongoDB, ExpenseDetailsVM>()
                .ForMember(
                dest => dest.Id,
                opt => opt.MapFrom(src => Guid.Parse(src.Id)));

            #endregion

            #region ======================================================= Payment Request =======================================================
            CreateMap<PaymentRequestDto, PaymentRequest>();
            CreateMap<PaymentRequest, PaymentRequestVM>()
                .ForMember(
                dest => dest.PaymentRequestUID,
                opt => opt.MapFrom(src => $"{src.UIDPrefix}/{src.UIDPostfix:D5}"));
            CreateMap<PaymentRequest, PaymentRequestDetailsVM>()
                .ForMember(
                dest => dest.PaymentRequestUID,
                opt => opt.MapFrom(src => $"{src.UIDPrefix}/{src.UIDPostfix:D5}"));
            CreateMap<PaymentRequest, BasicPaymentRequestVM>()
                .ForMember(
                dest => dest.PaymentRequestUID,
                opt => opt.MapFrom(src => $"{src.UIDPrefix}/{src.UIDPostfix:D5}"));
            CreateMap<Document, PaymentRequestAttachmentVM>();
            #endregion

            #region ======================================================= Recurring Request =======================================================
            CreateMap<CreateRecurringTemplateDto, RecurringPayment>()
                .ForMember(
                dest => dest.NextStrikeDate,
                opt => opt.MapFrom(src => src.StrikeDate.Date));
            CreateMap<UpdateRecurringTemplateDto, RecurringPayment>();
            CreateMap<RecurringPayment, RecurringPaymentVM>()
                .ForMember(
                dest => dest.RecurringPaymentUId,
                opt => opt.MapFrom(src => $"{src.UIDPrefix}/{src.UIDPostfix:D5}"));
            CreateMap<RecurringPayment, RecurringPaymentDetailsVM>()
                .ForMember(
                dest => dest.RecurringPaymentUID,
                opt => opt.MapFrom(src => $"{src.UIDPrefix}/{src.UIDPostfix:D5}"))
                .ForMember(
                dest => dest.NotifyTo,
                opt => opt.MapFrom(src => new List<BasicEmployeeVM>()));
            CreateMap<RecurringPayment, BasicRecurringPaymentVM>()
                .ForMember(
                dest => dest.RecurringPaymentUID,
                opt => opt.MapFrom(src => $"{src.UIDPrefix}/{src.UIDPostfix:D5}"));
            #endregion

            #region ======================================================= Collection =======================================================
            CreateMap<InvoiceDto, Invoice>();
            CreateMap<Invoice, InvoiceListVM>();
            CreateMap<Invoice, InvoiceDetailsVM>();

            CreateMap<ReceivedInvoicePaymentDto, ReceivedInvoicePayment>();
            CreateMap<ReceivedInvoicePayment, ReceivedInvoicePaymentVM>();

            CreateMap<InvoiceComment, InvoiceCommentVM>();

            CreateMap<InvoiceAttachment, InvoiceAttachmentVM>();
            #endregion

            CreateMap<AdvancePaymentTransaction, AdvancePaymentTransactionVM>();

            #endregion

            #region ======================================================= Master =======================================================

            CreateMap<FeaturePermission, FeaturePermissionVM>();

            #region ======================================================= Global Service Master =======================================================

            CreateMap<ServiceMasterDto, GlobalServiceMaster>()
                .ForMember(
                    dest => dest.Id,
                    // Explicitly and safely convert nullable Guid to non-nullable Guid
                    opt => opt.MapFrom(src => src.Id ?? Guid.Empty)
                );

            #endregion

            #region ======================================================= Service Master =======================================================

            CreateMap<ServiceMasterDto, ServiceMaster>()
                .ForMember(
                    dest => dest.Id,
                    // Explicitly and safely convert nullable Guid to non-nullable Guid
                    opt => opt.MapFrom(src => src.Id ?? Guid.Empty)
                );
            CreateMap<ServiceMaster, ServiceMasterVM>();

            #endregion

            #region ======================================================= Activity Group Master =======================================================

            CreateMap<ActivityGroupDto, ActivityGroupMaster>()
                .ForMember(
                    dest => dest.Id,
                    // Explicitly and safely convert nullable Guid to non-nullable Guid
                    opt => opt.MapFrom(src => src.Id ?? Guid.Empty)
                );
            CreateMap<ActivityGroupMaster, ActivityGroupMasterVM>();

            #endregion

            #region ======================================================= Activity Master =======================================================

            CreateMap<CreateActivityMasterDto, ActivityMaster>();
            CreateMap<CreateCheckListDto, ActivityCheckList>()
                .ForMember(
                    dest => dest.Id,
                    // Explicitly and safely convert nullable Guid to non-nullable Guid
                    opt => opt.MapFrom(src => src.Id ?? Guid.Empty)
                );
            CreateMap<ActivityCheckList, CheckListVM>();
            CreateMap<ActivityMaster, ActivityVM>();

            #endregion

            #region ======================================================= Expenses Category Master =======================================================

            CreateMap<ExpenseCategoryMasterDto, ExpenseCategoryMaster>()
                .ForMember(
                    dest => dest.Id,
                    // Explicitly and safely convert nullable Guid to non-nullable Guid
                    opt => opt.MapFrom(src => src.Id ?? Guid.Empty)
                );
            CreateMap<ExpenseCategoryMaster, ExpenseCategoryMasterVM>();

            CreateMap<ExpenseCategoryMaster, ExpenseCategoryMasterMongoDB>()
                .ForMember(
                dest => dest.Id,
                opt => opt.MapFrom(src => src.Id.ToString()))
                .ForMember(
                dest => dest.TenantId,
                opt => opt.MapFrom(src => src.TenantId.ToString()));

            CreateMap<ExpenseCategoryMasterMongoDB, ExpenseCategoryMasterVM>()
                .ForMember(
                dest => dest.Id,
                opt => opt.MapFrom(src => Guid.Parse(src.Id)));
            #endregion

            #region ======================================================= Expenses Status Master =======================================================

            CreateMap<ExpensesStatusMasterDto, ExpensesStatusMaster>()
                .ForMember(
                    dest => dest.Id,
                    opt => opt.MapFrom(src => src.Id ?? Guid.Empty))
                .ForMember(
                    dest => dest.DisplayName,
                    opt => opt.MapFrom(src => string.IsNullOrWhiteSpace(src.DisplayName) ? src.Name : src.DisplayName));
            CreateMap<ExpensesStatusMaster, ExpensesStatusMasterVM>();

            CreateMap<ExpensesStatusMaster, ExpensesStatusMasterMongoDB>()
                .ForMember(
                dest => dest.Id,
                opt => opt.MapFrom(src => src.Id.ToString()));

            CreateMap<ExpensesStatusMasterMongoDB, ExpensesStatusMasterVM>()
                .ForMember(
                dest => dest.Id,
                opt => opt.MapFrom(src => Guid.Parse(src.Id)));
            #endregion

            #region ======================================================= Payment Mode Matser =======================================================

            CreateMap<PaymentModeMatserDto, PaymentModeMatser>()
              .ForMember(
                  dest => dest.Id,
                  // Explicitly and safely convert nullable Guid to non-nullable Guid
                  opt => opt.MapFrom(src => src.Id ?? Guid.Empty)
              );
            CreateMap<PaymentModeMatser, PaymentModeMatserVM>();

            CreateMap<PaymentModeMatser, PaymentModeMatserMongoDB>()
                .ForMember(
                dest => dest.Id,
                opt => opt.MapFrom(src => src.Id.ToString()));

            CreateMap<PaymentModeMatserMongoDB, PaymentModeMatserVM>()
                .ForMember(
                dest => dest.Id,
                opt => opt.MapFrom(src => Guid.Parse(src.Id)));

            #endregion

            #region ======================================================= Contact Category Master =======================================================
            CreateMap<CreateContactCategoryDto, ContactCategoryMaster>();
            CreateMap<UpdateContactCategoryDto, ContactCategoryMaster>();
            CreateMap<ContactCategoryMaster, ContactCategoryVM>();
            #endregion

            #region ======================================================= Contact Tag Master =======================================================
            CreateMap<CreateContactTagDto, ContactTagMaster>();
            CreateMap<UpdateContactTagDto, ContactTagMaster>();
            CreateMap<ContactTagMaster, ContactTagVM>();
            #endregion

            #region ======================================================= Payment Adjustment Head Master =======================================================
            CreateMap<PaymentAdjustmentHeadDto, PaymentAdjustmentHead>();
            CreateMap<PaymentAdjustmentHead, PaymentAdjustmentHeadVM>();
            #endregion

            #region ======================================================= Expenses Status Master =======================================================
            #endregion

            #region ======================================================= Expenses Status Master =======================================================
            #endregion

            #region ======================================================= Expenses Status Master =======================================================
            #endregion

            #region ======================================================= Expenses Status Master =======================================================
            #endregion

            #endregion

            #region ======================================================= Document =======================================================

            CreateMap<DocumentMongoDB, BasicDocumentVM>()
                .ForMember(
                dest => dest.DocumentId,
                opt => opt.MapFrom(src => Guid.Parse(src.DocumentId)));

            CreateMap<DocumentAttachmentDto, DocumentAttachment>();
            CreateMap<DocumentAttachment, DocumentListVM>();
            CreateMap<DocumentAttachment, AttachmentVersionVM>();
            CreateMap<DocumentAttachment, DocumentAttachmentDetailsVM>();

            CreateMap<DocumentCategoryMaster, DocumentCategoryVM>();
            CreateMap<CreateDocumentCategoryDto, DocumentCategoryMaster>();

            CreateMap<DocumentTypeMaster, DocumentTypeVM>();
            CreateMap<CreateDocumentTypeDto, DocumentTypeMaster>();

            #endregion

            #region ======================================================= AppMenu =======================================================
            CreateMap<CreateMenuSectionDto, MenuSection>();
            CreateMap<UpdateMenuSectionDto, MenuSection>();
            CreateMap<MenuSection, MenuSectionVM>()
                .ForMember(
                dest => dest.Name,
               opt => opt.MapFrom(src => src.Title));

            CreateMap<CreateMenuItemDto, MenuItem>();
            CreateMap<UpdateMenuItemDto, MenuItem>();
            CreateMap<MenuItem, MenuItemVM>()
                .ForMember(
                dest => dest.Name,
               opt => opt.MapFrom(src => src.Text));

            CreateMap<CreateSubMenuItemDto, SubMenuItem>();
            CreateMap<UpdateSubMenuItemDto, SubMenuItem>();
            CreateMap<SubMenuItem, SubMenuItemVM>()
                .ForMember(
                dest => dest.Name,
               opt => opt.MapFrom(src => src.Text));
            #endregion

            #region ======================================================= Directory =======================================================

            CreateMap<Contact, ContactVM>();
            CreateMap<CreateContactDto, Contact>();
            CreateMap<UpdateContactDto, Contact>();
            CreateMap<Contact, ContactProfileVM>();


            CreateMap<ContactPhone, ContactPhoneVM>();
            CreateMap<CreateContactPhoneDto, ContactPhone>();
            CreateMap<UpdateContactPhoneDto, ContactPhone>();

            CreateMap<ContactEmail, ContactEmailVM>();
            CreateMap<CreateContactEmailDto, ContactEmail>();
            CreateMap<UpdateContactEmailDto, ContactEmail>();

            CreateMap<ContactCategoryMaster, ContactCategoryVM>();

            CreateMap<ContactTagMaster, ContactTagVM>();

            CreateMap<Bucket, BucketVM>();
            CreateMap<Bucket, AssignBucketVM>();

            CreateMap<ContactNote, ContactNoteVM>()
                .ForMember(
                    dest => dest.ContactName,
                    opt => opt.MapFrom(src => src.Contact != null ? src.Contact.Name : string.Empty)
                )
                .ForMember(
                    dest => dest.OrganizationName,
                    opt => opt.MapFrom(src => src.Contact != null ? src.Contact.Organization : string.Empty)
                );
            CreateMap<CreateContactNoteDto, ContactNote>();
            CreateMap<UpdateContactNoteDto, ContactNote>();

            #endregion
        }
    }
}