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

namespace Tiku.Api.Contracts;

/// <summary>
/// 平台租户能力通用查询参数。
/// </summary>
public class PlatformCapabilityQueryDto
{
    /// <summary>
    /// 租户 ID。
    /// </summary>
    public Guid? TenantId { get; set; }
    /// <summary>
    /// 状态。
    /// </summary>
    [StringLength(50)]
    public string? Status { get; set; }
    /// <summary>
    /// 返回数量上限。
    /// </summary>
    [Range(1, 500)]
    public int Limit { get; set; } = 100;

    public PlatformCapabilityQuery ToQuery() => new(TenantId, Status, Limit);
}

/// <summary>
/// 新增或更新租户 CRM 配置请求。
/// </summary>
public sealed class UpsertPlatformCrmConfigDto
{
    /// <summary>
    /// ID。
    /// </summary>
    public Guid? Id { get; set; }
    /// <summary>
    /// 租户 ID。
    /// </summary>
    [Required]
    public Guid TenantId { get; set; }
    /// <summary>
    /// 是否启用。
    /// </summary>
    public bool Enabled { get; set; }
    /// <summary>
    /// 回调地址。
    /// </summary>
    [StringLength(2048)]
    public string? Url { get; set; }
    /// <summary>
    /// 密钥引用。
    /// </summary>
    [StringLength(300)]
    public string? SecretRef { get; set; }
    /// <summary>
    /// 表单名称。
    /// </summary>
    [StringLength(200)]
    public string? FormName { get; set; }
    /// <summary>
    /// 考试类型。
    /// </summary>
    [StringLength(100)]
    public string? ExamType { get; set; }
    /// <summary>
    /// 超时时长，单位为秒。
    /// </summary>
    [Range(1, 120)]
    public int? TimeoutSeconds { get; set; }
    /// <summary>
    /// 延迟秒数。
    /// </summary>
    [Range(0, 86400)]
    public int? DelaySeconds { get; set; }
    /// <summary>
    /// 分配模式。
    /// </summary>
    [StringLength(50)]
    public string? AssignmentMode { get; set; }
    /// <summary>
    /// 分配池。
    /// </summary>
    public JsonElement? AssignmentPool { get; set; }
    /// <summary>
    /// 分配配置。
    /// </summary>
    public JsonElement? AssignmentConfig { get; set; }

    public UpsertPlatformCrmConfigCommand ToCommand() =>
        new(Id, TenantId, Enabled, Url, SecretRef, FormName, ExamType, TimeoutSeconds, DelaySeconds, AssignmentMode, AssignmentPool, AssignmentConfig);
}

/// <summary>
/// 重试租户 CRM 线索推送请求。
/// </summary>
public sealed class RetryPlatformCrmLeadDto
{
    /// <summary>
    /// 队列任务 ID。
    /// </summary>
    [Required]
    public Guid QueueId { get; set; }
    /// <summary>
    /// 备注。
    /// </summary>
    [StringLength(500)]
    public string? Note { get; set; }

    public PlatformCrmLeadRetryCommand ToCommand() => new(QueueId, Note);
}

/// <summary>
/// 平台租户 CRM 日志查询参数。
/// </summary>
public sealed class PlatformCrmLogQueryDto : PlatformCapabilityQueryDto
{
    /// <summary>
    /// 队列任务 ID。
    /// </summary>
    public Guid? QueueId { get; set; }
}

/// <summary>
/// 新增或更新租户短信渠道请求。
/// </summary>
public sealed class UpsertPlatformSmsChannelDto
{
    /// <summary>
    /// ID。
    /// </summary>
    public Guid? Id { get; set; }
    /// <summary>
    /// 租户 ID。
    /// </summary>
    [Required]
    public Guid TenantId { get; set; }
    /// <summary>
    /// 服务提供方。
    /// </summary>
    [Required, StringLength(80)]
    public string Provider { get; set; } = "generic";
    /// <summary>
    /// 名称。
    /// </summary>
    [Required, StringLength(200)]
    public string Name { get; set; } = string.Empty;
    /// <summary>
    /// 短信签名。
    /// </summary>
    [Required, StringLength(100)]
    public string Signature { get; set; } = string.Empty;
    /// <summary>
    /// 使用场景。
    /// </summary>
    [Required, StringLength(100)]
    public string Scene { get; set; } = "login";
    /// <summary>
    /// 状态。
    /// </summary>
    public TenantExternalProviderStatus Status { get; set; } = TenantExternalProviderStatus.Disabled;
    /// <summary>
    /// 密钥引用。
    /// </summary>
    [StringLength(300)]
    public string? SecretRef { get; set; }
    /// <summary>
    /// 优先级。
    /// </summary>
    public int? Priority { get; set; }
    /// <summary>
    /// 月度配额。
    /// </summary>
    [Range(0, int.MaxValue)]
    public int? MonthlyQuota { get; set; }
    /// <summary>
    /// 公开配置内容。
    /// </summary>
    public JsonElement ConfigPublic { get; set; } = JsonDefaults.Object();
    /// <summary>
    /// 扩展元数据。
    /// </summary>
    public JsonElement Metadata { get; set; } = JsonDefaults.Object();

    public UpsertPlatformSmsChannelCommand ToCommand() =>
        new(Id, TenantId, Provider, Name, Signature, Scene, Status, SecretRef, Priority, MonthlyQuota, ConfigPublic, Metadata);
}

/// <summary>
/// 新增或更新租户短信模板请求。
/// </summary>
public sealed class UpsertPlatformSmsTemplateDto
{
    /// <summary>
    /// ID。
    /// </summary>
    public Guid? Id { get; set; }
    /// <summary>
    /// 租户 ID。
    /// </summary>
    [Required]
    public Guid TenantId { get; set; }
    /// <summary>
    /// 短信渠道 ID。
    /// </summary>
    [Required]
    public Guid ChannelId { get; set; }
    /// <summary>
    /// 编码。
    /// </summary>
    [Required, StringLength(120)]
    public string Code { get; set; } = string.Empty;
    /// <summary>
    /// 名称。
    /// </summary>
    [Required, StringLength(200)]
    public string Name { get; set; } = string.Empty;
    /// <summary>
    /// 类型。
    /// </summary>
    public SmsTemplateType Type { get; set; } = SmsTemplateType.Notification;
    /// <summary>
    /// 审核状态。
    /// </summary>
    public SmsTemplateAuditStatus AuditStatus { get; set; } = SmsTemplateAuditStatus.Draft;
    /// <summary>
    /// 状态。
    /// </summary>
    public SmsTemplateStatus Status { get; set; } = SmsTemplateStatus.Active;
    /// <summary>
    /// 渠道模板编码。
    /// </summary>
    [StringLength(120)]
    public string? ProviderTemplateCode { get; set; }
    /// <summary>
    /// 模板内容。
    /// </summary>
    [Required, StringLength(1000)]
    public string Content { get; set; } = string.Empty;
    /// <summary>
    /// Remark。
    /// </summary>
    [StringLength(500)]
    public string? Remark { get; set; }
    /// <summary>
    /// 扩展元数据。
    /// </summary>
    public JsonElement Metadata { get; set; } = JsonDefaults.Object();

    public UpsertPlatformSmsTemplateCommand ToCommand() =>
        new(Id, TenantId, ChannelId, Code, Name, Type, AuditStatus, Status, ProviderTemplateCode, Content, Remark, Metadata);
}

/// <summary>
/// 新增或更新平台支付应用请求。
/// </summary>
public sealed class UpsertPlatformPaymentAppDto
{
    /// <summary>
    /// ID。
    /// </summary>
    public Guid? Id { get; set; }
    /// <summary>
    /// 支付应用编码。
    /// </summary>
    [Required, StringLength(100)]
    public string AppCode { get; set; } = string.Empty;
    /// <summary>
    /// 支付应用名称。
    /// </summary>
    [Required, StringLength(200)]
    public string AppName { get; set; } = string.Empty;
    /// <summary>
    /// 状态。
    /// </summary>
    public PlatformPaymentAppStatus Status { get; set; } = PlatformPaymentAppStatus.Disabled;
    /// <summary>
    /// 结算模式。
    /// </summary>
    [StringLength(100)]
    public string SettlementMode { get; set; } = "PlatformCollect";
    /// <summary>
    /// 说明。
    /// </summary>
    [StringLength(500)]
    public string? Description { get; set; }
    /// <summary>
    /// 扩展元数据。
    /// </summary>
    public JsonElement Metadata { get; set; } = JsonDefaults.Object();

    public UpsertPlatformPaymentAppCommand ToCommand() =>
        new(Id, AppCode, AppName, Status, SettlementMode, Description, Metadata);
}

/// <summary>
/// 新增或更新平台支付渠道请求。
/// </summary>
public sealed class UpsertPlatformPaymentChannelDto
{
    /// <summary>
    /// ID。
    /// </summary>
    public Guid? Id { get; set; }
    /// <summary>
    /// 支付应用 ID。
    /// </summary>
    [Required]
    public Guid AppId { get; set; }
    /// <summary>
    /// 服务提供方。
    /// </summary>
    [Required, StringLength(80)]
    public string Provider { get; set; } = "manual";
    /// <summary>
    /// 模式。
    /// </summary>
    [StringLength(100)]
    public string Mode { get; set; } = "PlatformCollect";
    /// <summary>
    /// 状态。
    /// </summary>
    public PlatformPaymentChannelStatus Status { get; set; } = PlatformPaymentChannelStatus.Disabled;
    /// <summary>
    /// 显示名称。
    /// </summary>
    [Required, StringLength(200)]
    public string DisplayName { get; set; } = string.Empty;
    /// <summary>
    /// 密钥引用。
    /// </summary>
    [StringLength(300)]
    public string? SecretRef { get; set; }
    /// <summary>
    /// 回调路径。
    /// </summary>
    [StringLength(500)]
    public string? CallbackPath { get; set; }
    /// <summary>
    /// 优先级。
    /// </summary>
    public int? Priority { get; set; }
    /// <summary>
    /// 公开配置内容。
    /// </summary>
    public JsonElement ConfigPublic { get; set; } = JsonDefaults.Object();
    /// <summary>
    /// 扩展元数据。
    /// </summary>
    public JsonElement Metadata { get; set; } = JsonDefaults.Object();

    public UpsertPlatformPaymentChannelCommand ToCommand() =>
        new(Id, AppId, Provider, Mode, Status, DisplayName, SecretRef, CallbackPath, Priority, ConfigPublic, Metadata);
}

/// <summary>
/// 新增或更新租户支付应用请求。
/// </summary>
public sealed class UpsertPlatformTenantPaymentAppDto
{
    /// <summary>
    /// 租户 ID。
    /// </summary>
    [Required]
    public Guid TenantId { get; set; }
    /// <summary>
    /// 服务提供方。
    /// </summary>
    [Required, StringLength(80)]
    public string Provider { get; set; } = "manual";
    /// <summary>
    /// 状态。
    /// </summary>
    public TenantExternalProviderStatus Status { get; set; } = TenantExternalProviderStatus.Disabled;
    /// <summary>
    /// 显示名称。
    /// </summary>
    [StringLength(200)]
    public string? DisplayName { get; set; }
    /// <summary>
    /// 密钥引用。
    /// </summary>
    [StringLength(300)]
    public string? SecretRef { get; set; }
    /// <summary>
    /// 优先级。
    /// </summary>
    public int? Priority { get; set; }
    /// <summary>
    /// 公开配置内容。
    /// </summary>
    public JsonElement ConfigPublic { get; set; } = JsonDefaults.Object();
    /// <summary>
    /// 扩展元数据。
    /// </summary>
    public JsonElement Metadata { get; set; } = JsonDefaults.Object();

    public UpsertTenantExternalProviderCommand ToCommand() =>
        new(TenantExternalProviderCapability.Payment, Provider, Status, DisplayName, SecretRef, Priority, ConfigPublic, Metadata);
}
