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

namespace TakeoutSaaS.Application.App.Tenants;

/// <summary>
/// 租户 DTO 映射助手。
/// </summary>
internal static class TenantMapping
{
    /// <summary>
    /// 将租户实体与订阅、认证信息映射为租户 DTO。
    /// </summary>
    /// <param name="tenant">租户实体。</param>
    /// <param name="subscription">订阅信息。</param>
    /// <param name="verification">认证信息。</param>
    /// <returns>租户 DTO。</returns>
    public static TenantDto ToDto(Tenant tenant, TenantSubscription? subscription, TenantVerificationProfile? verification)
        => new()
        {
            Id = tenant.Id,
            Code = tenant.Code,
            Name = tenant.Name,
            ShortName = tenant.ShortName,
            ContactName = tenant.ContactName,
            ContactPhone = tenant.ContactPhone,
            ContactEmail = tenant.ContactEmail,
            Status = tenant.Status,
            VerificationStatus = verification?.Status ?? Domain.Tenants.Enums.TenantVerificationStatus.Draft,
            CurrentPackageId = subscription?.TenantPackageId,
            EffectiveFrom = subscription?.EffectiveFrom ?? tenant.EffectiveFrom,
            EffectiveTo = subscription?.EffectiveTo ?? tenant.EffectiveTo,
            AutoRenew = subscription?.AutoRenew ?? false
        };

    /// <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,
                BankAccountNumber = profile.BankAccountNumber,
                BankName = profile.BankName,
                ReviewRemarks = profile.ReviewRemarks,
                ReviewedByName = profile.ReviewedByName,
                ReviewedAt = profile.ReviewedAt
            };

    /// <summary>
    /// 将订阅实体映射为 DTO。
    /// </summary>
    /// <param name="subscription">订阅实体。</param>
    /// <returns>订阅 DTO 或 null。</returns>
    public static TenantSubscriptionDto? ToSubscriptionDto(this TenantSubscription? subscription)
        => subscription == null
            ? null
            : new TenantSubscriptionDto
            {
                Id = subscription.Id,
                TenantId = subscription.TenantId,
                TenantPackageId = subscription.TenantPackageId,
                Status = subscription.Status,
                EffectiveFrom = subscription.EffectiveFrom,
                EffectiveTo = subscription.EffectiveTo,
                NextBillingDate = subscription.NextBillingDate,
                AutoRenew = subscription.AutoRenew
            };

    /// <summary>
    /// 将审计日志实体映射为 DTO。
    /// </summary>
    /// <param name="log">审计日志实体。</param>
    /// <returns>审计日志 DTO。</returns>
    public static TenantAuditLogDto ToDto(this TenantAuditLog log)
        => new()
        {
            Id = log.Id,
            TenantId = log.TenantId,
            Action = log.Action,
            Title = log.Title,
            Description = log.Description,
            OperatorName = log.OperatorName,
            PreviousStatus = log.PreviousStatus,
            CurrentStatus = log.CurrentStatus,
            CreatedAt = log.CreatedAt
        };

    /// <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,
            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,
            IsActive = announcement.IsActive,
            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
        };
}
