using TakeoutSaaS.Application.App.Merchants.Dto;
using TakeoutSaaS.Domain.Merchants.Entities;
using TakeoutSaaS.Domain.Stores.Entities;

namespace TakeoutSaaS.Application.App.Merchants;

/// <summary>
/// 商户 DTO 映射工具。
/// </summary>
internal static class MerchantMapping
{
    /// <summary>
    /// 将商户实体映射为 DTO。
    /// </summary>
    /// <param name="merchant">商户实体。</param>
    /// <returns>商户 DTO。</returns>
    public static MerchantDto ToDto(Merchant merchant) => new()
    {
        Id = merchant.Id,
        TenantId = merchant.TenantId,
        BrandName = merchant.BrandName,
        BrandAlias = merchant.BrandAlias,
        LogoUrl = merchant.LogoUrl,
        Category = merchant.Category,
        ContactPhone = merchant.ContactPhone,
        ContactEmail = merchant.ContactEmail,
        Status = merchant.Status,
        JoinedAt = merchant.JoinedAt,
        CreatedAt = merchant.CreatedAt
    };

    /// <summary>
    /// 将商户实体映射为列表项 DTO。
    /// </summary>
    public static MerchantListItemDto ToListItemDto(Merchant merchant, string? tenantName, int storeCount) => new()
    {
        Id = merchant.Id,
        TenantId = merchant.TenantId,
        TenantName = tenantName,
        Name = merchant.BrandName,
        OperatingMode = merchant.OperatingMode,
        LicenseNumber = merchant.BusinessLicenseNumber,
        Status = merchant.Status,
        IsFrozen = merchant.IsFrozen,
        StoreCount = storeCount,
        CreatedAt = merchant.CreatedAt,
        UpdatedAt = merchant.UpdatedAt
    };

    /// <summary>
    /// 将商户实体映射为详情 DTO。
    /// </summary>
    public static MerchantDetailDto ToDetailDto(Merchant merchant, string? tenantName, IReadOnlyList<MerchantStoreDto> stores) => new()
    {
        Id = merchant.Id,
        TenantId = merchant.TenantId,
        TenantName = tenantName,
        Name = merchant.BrandName,
        OperatingMode = merchant.OperatingMode,
        LicenseNumber = merchant.BusinessLicenseNumber,
        LegalRepresentative = merchant.LegalPerson,
        RegisteredAddress = merchant.Address,
        Province = merchant.Province,
        City = merchant.City,
        District = merchant.District,
        Longitude = merchant.Longitude,
        Latitude = merchant.Latitude,
        GeoStatus = merchant.GeoStatus,
        GeoFailReason = merchant.GeoFailReason,
        GeoUpdatedAt = merchant.GeoUpdatedAt,
        ContactPhone = merchant.ContactPhone,
        ContactEmail = merchant.ContactEmail,
        Status = merchant.Status,
        IsFrozen = merchant.IsFrozen,
        FrozenReason = merchant.FrozenReason,
        FrozenAt = merchant.FrozenAt,
        ApprovedBy = merchant.ApprovedBy,
        ApprovedAt = merchant.ApprovedAt,
        Stores = stores,
        RowVersion = merchant.RowVersion,
        CreatedAt = merchant.CreatedAt,
        CreatedBy = merchant.CreatedBy,
        UpdatedAt = merchant.UpdatedAt,
        UpdatedBy = merchant.UpdatedBy
    };

    /// <summary>
    /// 将商户证照实体映射为 DTO。
    /// </summary>
    /// <param name="document">证照实体。</param>
    /// <returns>证照 DTO。</returns>
    public static MerchantDocumentDto ToDto(MerchantDocument document) => new()
    {
        Id = document.Id,
        MerchantId = document.MerchantId,
        DocumentType = document.DocumentType,
        Status = document.Status,
        FileUrl = document.FileUrl,
        DocumentNumber = document.DocumentNumber,
        IssuedAt = document.IssuedAt,
        ExpiresAt = document.ExpiresAt,
        Remarks = document.Remarks,
        CreatedAt = document.CreatedAt
    };

    /// <summary>
    /// 将商户合同实体映射为 DTO。
    /// </summary>
    /// <param name="contract">合同实体。</param>
    /// <returns>合同 DTO。</returns>
    public static MerchantContractDto ToDto(MerchantContract contract) => new()
    {
        Id = contract.Id,
        MerchantId = contract.MerchantId,
        ContractNumber = contract.ContractNumber,
        Status = contract.Status,
        StartDate = contract.StartDate,
        EndDate = contract.EndDate,
        FileUrl = contract.FileUrl,
        SignedAt = contract.SignedAt,
        TerminatedAt = contract.TerminatedAt,
        TerminationReason = contract.TerminationReason
    };

    /// <summary>
    /// 将商户审核日志实体映射为 DTO。
    /// </summary>
    /// <param name="log">审核日志实体。</param>
    /// <returns>审核日志 DTO。</returns>
    public static MerchantAuditLogDto ToDto(MerchantAuditLog log) => new()
    {
        Id = log.Id,
        MerchantId = log.MerchantId,
        Action = log.Action,
        OperatorId = log.OperatorId,
        Title = log.Title,
        Description = log.Description,
        OperatorName = log.OperatorName,
        IpAddress = log.IpAddress,
        CreatedAt = log.CreatedAt
    };

    /// <summary>
    /// 将商户变更日志实体映射为 DTO。
    /// </summary>
    public static MerchantChangeLogDto ToDto(MerchantChangeLog log) => new()
    {
        Id = log.Id,
        FieldName = log.FieldName,
        OldValue = log.OldValue,
        NewValue = log.NewValue,
        ChangedBy = log.ChangedBy,
        ChangedByName = log.ChangedByName,
        ChangedAt = log.CreatedAt,
        ChangeReason = log.ChangeReason
    };

    /// <summary>
    /// 将门店实体映射为 DTO。
    /// </summary>
    public static MerchantStoreDto ToStoreDto(Store store) => new()
    {
        Id = store.Id,
        Name = store.Name,
        LicenseNumber = store.BusinessLicenseNumber,
        ContactPhone = store.Phone,
        Address = store.Address,
        Status = store.Status
    };

    /// <summary>
    /// 将商户分类实体映射为 DTO。
    /// </summary>
    /// <param name="category">分类实体。</param>
    /// <returns>分类 DTO。</returns>
    public static MerchantCategoryDto ToDto(MerchantCategory category) => new()
    {
        Id = category.Id,
        Name = category.Name,
        DisplayOrder = category.DisplayOrder,
        IsActive = category.IsActive,
        CreatedAt = category.CreatedAt
    };

    /// <summary>
    /// 将证照集合映射为 DTO 集合。
    /// </summary>
    /// <param name="documents">证照集合。</param>
    /// <returns>证照 DTO 列表。</returns>
    public static IReadOnlyList<MerchantDocumentDto> ToDocumentDtos(IEnumerable<MerchantDocument> documents)
        => documents.Select(ToDto).ToList();

    /// <summary>
    /// 将合同集合映射为 DTO 集合。
    /// </summary>
    /// <param name="contracts">合同集合。</param>
    /// <returns>合同 DTO 列表。</returns>
    public static IReadOnlyList<MerchantContractDto> ToContractDtos(IEnumerable<MerchantContract> contracts)
        => contracts.Select(ToDto).ToList();

    /// <summary>
    /// 将分类集合映射为 DTO 集合。
    /// </summary>
    /// <param name="categories">分类集合。</param>
    /// <returns>分类 DTO 列表。</returns>
    public static IReadOnlyList<MerchantCategoryDto> ToCategoryDtos(IEnumerable<MerchantCategory> categories)
        => categories.Select(ToDto).ToList();

    /// <summary>
    /// 将门店集合映射为 DTO 集合。
    /// </summary>
    public static IReadOnlyList<MerchantStoreDto> ToStoreDtos(IEnumerable<Store> stores)
        => stores.Select(ToStoreDto).ToList();
}
