using TakeoutSaaS.Application.App.Tenants.Dto;
using TakeoutSaaS.Domain.Tenants.Entities;
using TakeoutSaaS.Domain.Tenants.Enums;

namespace TakeoutSaaS.Application.App.Tenants;

/// <summary>
/// 租户 DTO 映射助手。
/// </summary>
internal static class TenantMapping
{
    /// <summary>
    /// 将租户认证实体映射为 DTO。
    /// </summary>
    /// <param name="profile">认证实体。</param>
    /// <returns>认证 DTO 或 null。</returns>
    public static TenantVerificationDto? ToVerificationDto(this TenantVerificationProfile? profile)
        => profile == null
            ? null
            : new TenantVerificationDto
            {
                Id = profile.Id,
                TenantId = profile.TenantId,
                Status = profile.Status,
                BusinessLicenseNumber = profile.BusinessLicenseNumber,
                BusinessLicenseUrl = profile.BusinessLicenseUrl,
                LegalPersonName = profile.LegalPersonName,
                LegalPersonIdNumber = profile.LegalPersonIdNumber,
                LegalPersonIdFrontUrl = profile.LegalPersonIdFrontUrl,
                LegalPersonIdBackUrl = profile.LegalPersonIdBackUrl,
                BankAccountName = profile.BankAccountName,
                BankAccountNumber = profile.BankAccountNumber,
                BankName = profile.BankName,
                WeChatMerchantNo = profile.WeChatMerchantNo,
                AlipayPid = profile.AlipayPid,
                AdditionalDataJson = profile.AdditionalDataJson,
                SubmittedAt = profile.SubmittedAt,
                ReviewRemarks = profile.ReviewRemarks,
                ReviewedBy = profile.ReviewedBy,
                ReviewedByName = profile.ReviewedByName,
                ReviewedAt = profile.ReviewedAt
            };

    /// <summary>
    /// 将套餐实体映射为 DTO。
    /// </summary>
    /// <param name="package">套餐实体。</param>
    /// <returns>套餐 DTO。</returns>
    public static TenantPackageDto ToDto(this TenantPackage package)
        => new()
        {
            Id = package.Id,
            Name = package.Name,
            Description = package.Description,
            PackageType = package.PackageType,
            MonthlyPrice = package.MonthlyPrice,
            YearlyPrice = package.YearlyPrice,
            MaxStoreCount = package.MaxStoreCount,
            MaxAccountCount = package.MaxAccountCount,
            MaxStorageGb = package.MaxStorageGb,
            MaxSmsCredits = package.MaxSmsCredits,
            MaxDeliveryOrders = package.MaxDeliveryOrders,
            FeaturePoliciesJson = package.FeaturePoliciesJson,
            IsActive = package.IsActive,
            IsPublicVisible = package.IsPublicVisible,
            IsAllowNewTenantPurchase = package.IsAllowNewTenantPurchase,
            PublishStatus = package.PublishStatus,
            IsRecommended = package.IsRecommended,
            Tags = package.Tags ?? [],
            SortOrder = package.SortOrder
        };

    /// <summary>
    /// 将账单实体映射为 DTO。
    /// </summary>
    /// <param name="bill">账单实体。</param>
    /// <returns>账单 DTO。</returns>
    public static TenantBillingDto ToDto(this TenantBillingStatement bill)
        => new()
        {
            Id = bill.Id,
            TenantId = bill.TenantId,
            StatementNo = bill.StatementNo,
            PeriodStart = bill.PeriodStart,
            PeriodEnd = bill.PeriodEnd,
            AmountDue = bill.AmountDue,
            AmountPaid = bill.AmountPaid,
            Status = bill.Status,
            DueDate = bill.DueDate,
            LineItemsJson = bill.LineItemsJson
        };

    /// <summary>
    /// 将公告实体映射为 DTO。
    /// </summary>
    /// <param name="announcement">公告实体。</param>
    /// <param name="isRead">是否已读。</param>
    /// <param name="readAt">阅读时间。</param>
    /// <returns>公告 DTO。</returns>
    public static TenantAnnouncementDto ToDto(this TenantAnnouncement announcement, bool isRead, DateTime? readAt)
        => new()
        {
            Id = announcement.Id,
            TenantId = announcement.TenantId,
            Title = announcement.Title,
            Content = announcement.Content,
            AnnouncementType = announcement.AnnouncementType,
            Priority = announcement.Priority,
            EffectiveFrom = announcement.EffectiveFrom,
            EffectiveTo = announcement.EffectiveTo,
            PublisherScope = announcement.PublisherScope,
            PublisherUserId = announcement.PublisherUserId,
            Status = announcement.Status,
            PublishedAt = announcement.PublishedAt,
            RevokedAt = announcement.RevokedAt,
            ScheduledPublishAt = announcement.ScheduledPublishAt,
            TargetType = announcement.TargetType,
            TargetParameters = announcement.TargetParameters,
            RowVersion = announcement.RowVersion,
            IsActive = announcement.Status == AnnouncementStatus.Published,
            IsRead = isRead,
            ReadAt = readAt
        };

    /// <summary>
    /// 将通知实体映射为 DTO。
    /// </summary>
    /// <param name="notification">通知实体。</param>
    /// <returns>通知 DTO。</returns>
    public static TenantNotificationDto ToDto(this TenantNotification notification)
        => new()
        {
            Id = notification.Id,
            TenantId = notification.TenantId,
            Title = notification.Title,
            Message = notification.Message,
            Channel = notification.Channel,
            Severity = notification.Severity,
            SentAt = notification.SentAt,
            ReadAt = notification.ReadAt,
            MetadataJson = notification.MetadataJson
        };
}
