using System.ComponentModel.DataAnnotations;
using System.Text.Json;
using Tiku.Application.PlatformAdmin;
using Tiku.Domain.Common;
using Tiku.Domain.Commerce;
using Tiku.Domain.Identity;
using Tiku.Domain.Platform;
using Tiku.Domain.Tenancy;

namespace Tiku.Api.Contracts;

/// <summary>
/// 平台管理端查询参数。
/// </summary>
public sealed class PlatformAdminQueryDto
{
    /// <summary>
    /// 状态。
    /// </summary>
    [StringLength(32)]
    public string? Status { get; set; }

    /// <summary>
    /// 搜索关键字。
    /// </summary>
    [StringLength(200)]
    public string? Search { get; set; }

    /// <summary>
    /// 返回数量上限。
    /// </summary>
    [Range(1, 200)]
    public int? Limit { get; set; }

    public PlatformAdminQuery ToQuery() => new(Status, Search, Limit);
}

/// <summary>
/// 创建平台租户请求 DTO。
/// </summary>
public sealed class CreatePlatformTenantDto
{
    /// <summary>
    /// 短编码。
    /// </summary>
    [Required]
    [StringLength(100)]
    public string Slug { get; set; } = string.Empty;

    /// <summary>
    /// 名称。
    /// </summary>
    [Required]
    [StringLength(200)]
    public string Name { get; set; } = string.Empty;

    /// <summary>
    /// 法定名称。
    /// </summary>
    [StringLength(300)]
    public string? LegalName { get; set; }

    /// <summary>
    /// 状态。
    /// </summary>
    public TenantStatus Status { get; set; } = TenantStatus.Active;
    /// <summary>
    /// 账务状态。
    /// </summary>
    public BillingStatus BillingStatus { get; set; } = BillingStatus.Trial;
    /// <summary>
    /// 扩展元数据。
    /// </summary>
    public JsonElement Metadata { get; set; } = JsonDefaults.Object();

    /// <summary>
    /// 租户负责人邮箱。
    /// </summary>
    [EmailAddress, StringLength(320)]
    public string? OwnerEmail { get; set; }

    /// <summary>
    /// 租户负责人手机号。
    /// </summary>
    [Phone, StringLength(32)]
    public string? OwnerPhone { get; set; }

    /// <summary>
    /// 租户负责人姓名。
    /// </summary>
    [Required, StringLength(100)]
    public string OwnerName { get; set; } = string.Empty;

    /// <summary>
    /// 临时密码。
    /// </summary>
    [Required, StringLength(200, MinimumLength = 12)]
    public string TemporaryPassword { get; set; } = string.Empty;

    public CreatePlatformTenantCommand ToCommand() => new(
        Slug, Name, LegalName, Status, BillingStatus, Metadata,
        OwnerEmail, OwnerPhone, OwnerName, TemporaryPassword);
}

/// <summary>
/// 更新平台租户状态请求 DTO。
/// </summary>
public sealed class UpdatePlatformTenantStatusDto
{
    /// <summary>
    /// 租户 ID。
    /// </summary>
    [Required]
    public Guid TenantId { get; set; }

    /// <summary>
    /// 状态。
    /// </summary>
    public TenantStatus Status { get; set; } = TenantStatus.Active;
    /// <summary>
    /// 账务状态。
    /// </summary>
    public BillingStatus BillingStatus { get; set; } = BillingStatus.Active;

    /// <summary>
    /// 原因。
    /// </summary>
    [StringLength(1000)]
    public string? Reason { get; set; }

    public UpdatePlatformTenantStatusCommand ToCommand() => new(TenantId, Status, BillingStatus, Reason);
}

/// <summary>
/// 新增或更新平台租户账务资料请求 DTO。
/// </summary>
public sealed class UpsertPlatformTenantBillingProfileDto
{
    /// <summary>
    /// 租户 ID。
    /// </summary>
    [Required]
    public Guid TenantId { get; set; }

    /// <summary>
    /// 账务名称。
    /// </summary>
    [StringLength(300)]
    public string? BillingName { get; set; }

    /// <summary>
    /// 税号。
    /// </summary>
    [StringLength(100)]
    public string? TaxId { get; set; }

    /// <summary>
    /// 联系人姓名。
    /// </summary>
    [StringLength(100)]
    public string? ContactName { get; set; }

    /// <summary>
    /// 联系人手机号。
    /// </summary>
    [StringLength(32)]
    public string? ContactPhone { get; set; }

    /// <summary>
    /// 联系人邮箱。
    /// </summary>
    [StringLength(320)]
    public string? ContactEmail { get; set; }

    /// <summary>
    /// 账务地址。
    /// </summary>
    [StringLength(1000)]
    public string? BillingAddress { get; set; }

    /// <summary>
    /// 发票抬头。
    /// </summary>
    [StringLength(300)]
    public string? InvoiceTitle { get; set; }

    /// <summary>
    /// 发票类型。
    /// </summary>
    public TenantBillingInvoiceTitleType? InvoiceType { get; set; }

    /// <summary>
    /// 开户银行。
    /// </summary>
    [StringLength(300)]
    public string? BankName { get; set; }

    /// <summary>
    /// 脱敏银行账号。
    /// </summary>
    [StringLength(100)]
    public string? BankAccountMasked { get; set; }

    /// <summary>
    /// 扩展元数据。
    /// </summary>
    public JsonElement Metadata { get; set; } = JsonDefaults.Object();

    public UpsertPlatformTenantBillingProfileCommand ToCommand() => new(
        TenantId,
        BillingName,
        TaxId,
        ContactName,
        ContactPhone,
        ContactEmail,
        BillingAddress,
        InvoiceTitle,
        InvoiceType,
        BankName,
        BankAccountMasked,
        Metadata);
}

/// <summary>
/// 新增或更新平台Staff请求 DTO。
/// </summary>
public sealed class UpsertPlatformStaffDto
{
    /// <summary>
    /// 用户 ID。
    /// </summary>
    public Guid? UserId { get; set; }

    /// <summary>
    /// 邮箱。
    /// </summary>
    [StringLength(320)]
    public string? Email { get; set; }

    /// <summary>
    /// 手机号。
    /// </summary>
    [StringLength(32)]
    public string? Phone { get; set; }

    /// <summary>
    /// 名称。
    /// </summary>
    [StringLength(200)]
    public string? Name { get; set; }

    /// <summary>
    /// 状态。
    /// </summary>
    public UserStatus Status { get; set; } = UserStatus.Active;
    /// <summary>
    /// 角色 ID 列表。
    /// </summary>
    public IReadOnlyCollection<Guid> RoleIds { get; set; } = [];

    public UpsertPlatformStaffCommand ToCommand() => new(UserId, Email, Phone, Name, Status, RoleIds);
}

/// <summary>
/// 更新平台Staff状态请求 DTO。
/// </summary>
public sealed class UpdatePlatformStaffStatusDto
{
    /// <summary>
    /// 用户 ID。
    /// </summary>
    [Required]
    public Guid UserId { get; set; }

    /// <summary>
    /// 状态。
    /// </summary>
    public UserStatus Status { get; set; } = UserStatus.Active;

    /// <summary>
    /// 原因。
    /// </summary>
    [StringLength(1000)]
    public string? Reason { get; set; }

    public UpdatePlatformStaffStatusCommand ToCommand() => new(UserId, Status, Reason);
}

/// <summary>
/// 更新平台审计Alert状态请求 DTO。
/// </summary>
public sealed class UpdatePlatformAuditAlertStatusDto
{
    /// <summary>
    /// 告警 ID。
    /// </summary>
    [Required]
    public Guid AlertId { get; set; }

    /// <summary>
    /// 状态。
    /// </summary>
    public PlatformAuditAlertStatus Status { get; set; } = PlatformAuditAlertStatus.Acknowledged;

    /// <summary>
    /// 处理备注。
    /// </summary>
    [StringLength(1000)]
    public string? ResolutionNote { get; set; }

    public UpdatePlatformAuditAlertStatusCommand ToCommand() => new(AlertId, Status, ResolutionNote);
}

/// <summary>
/// 新增或更新平台DunningChannel请求 DTO。
/// </summary>
public sealed class UpsertPlatformBillingDunningChannelDto
{
    /// <summary>
    /// 通知渠道 ID。
    /// </summary>
    public Guid? ChannelId { get; set; }

    /// <summary>
    /// 渠道编码。
    /// </summary>
    [Required]
    [StringLength(100)]
    public string ChannelCode { get; set; } = string.Empty;

    /// <summary>
    /// 名称。
    /// </summary>
    [Required]
    [StringLength(200)]
    public string Name { get; set; } = string.Empty;

    /// <summary>
    /// 说明。
    /// </summary>
    [StringLength(1000)]
    public string? Description { get; set; }

    /// <summary>
    /// 是否启用。
    /// </summary>
    public bool Enabled { get; set; } = true;
    /// <summary>
    /// 服务提供方。
    /// </summary>
    public PlatformBillingDunningProvider Provider { get; set; } = PlatformBillingDunningProvider.Generic;

    /// <summary>
    /// Webhook 地址。
    /// </summary>
    [Required]
    [StringLength(2048)]
    public string WebhookUrl { get; set; } = string.Empty;

    /// <summary>
    /// 密钥引用。
    /// </summary>
    [StringLength(300)]
    public string? SecretRef { get; set; }

    /// <summary>
    /// 提醒类型列表。
    /// </summary>
    public IReadOnlyCollection<string> ReminderTypes { get; set; } = ["overdue", "final_notice"];
    /// <summary>
    /// 提醒渠道列表。
    /// </summary>
    public IReadOnlyCollection<string> ReminderChannels { get; set; } = ["internal"];

    /// <summary>
    /// 最低提醒级别。
    /// </summary>
    [Range(1, 20)]
    public int MinReminderLevel { get; set; } = 1;

    /// <summary>
    /// 租户 ID 列表。
    /// </summary>
    public IReadOnlyCollection<Guid> TenantIds { get; set; } = [];

    /// <summary>
    /// 超时时长，单位为秒。
    /// </summary>
    [Range(1, 60)]
    public int TimeoutSeconds { get; set; } = 10;

    /// <summary>
    /// 扩展元数据。
    /// </summary>
    public JsonElement Metadata { get; set; } = JsonDefaults.Object();

    public UpsertPlatformBillingDunningChannelCommand ToCommand() => new(
        ChannelId,
        ChannelCode,
        Name,
        Description,
        Enabled,
        Provider,
        WebhookUrl,
        SecretRef,
        ReminderTypes,
        ReminderChannels,
        MinReminderLevel,
        TenantIds,
        TimeoutSeconds,
        Metadata);
}

/// <summary>
/// 禁用平台DunningChannel请求 DTO。
/// </summary>
public sealed class DisablePlatformBillingDunningChannelDto
{
    /// <summary>
    /// 通知渠道 ID。
    /// </summary>
    [Required]
    public Guid ChannelId { get; set; }

    /// <summary>
    /// 原因。
    /// </summary>
    [StringLength(1000)]
    public string? Reason { get; set; }

    public DisablePlatformBillingDunningChannelCommand ToCommand() => new(ChannelId, Reason);
}

/// <summary>
/// 重试平台Dunning事件请求 DTO。
/// </summary>
public sealed class RetryPlatformBillingDunningEventDto
{
    /// <summary>
    /// 事件 ID。
    /// </summary>
    [Required]
    public Guid EventId { get; set; }

    /// <summary>
    /// 原因。
    /// </summary>
    [StringLength(1000)]
    public string? Reason { get; set; }

    public RetryPlatformBillingDunningEventCommand ToCommand() => new(EventId, Reason);
}
